Compare commits
88
Commits
b12c211a69
...
c14e31cc43
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c14e31cc43 | ||
|
|
d7a0acf0a9 | ||
|
|
81dc673ac2 | ||
|
|
3bfb233614 | ||
|
|
34cf3d79cd | ||
|
|
abca5c2d75 | ||
|
|
748c2060a4 | ||
|
|
7cbae3d221 | ||
|
|
a2486c93c5 | ||
|
|
e61f230978 | ||
|
|
0992f3b863 | ||
|
|
345ef7c56c | ||
|
|
899ab7095b | ||
|
|
786fc97ea0 | ||
|
|
4949aef927 | ||
|
|
a85cb5a928 | ||
|
|
7514ceb04f | ||
|
|
c8cbc90d87 | ||
|
|
8342efd8df | ||
|
|
a5ff81e98d | ||
|
|
c5de4d2b04 | ||
|
|
4e8d165892 | ||
|
|
645b51330a | ||
|
|
5dd1d2b296 | ||
|
|
d81a59b9cb | ||
|
|
8f5d690d75 | ||
|
|
35ce6be8f9 | ||
|
|
4e3a3ac899 | ||
|
|
85e4cbdc67 | ||
|
|
8446965d88 | ||
|
|
dd69b30b84 | ||
|
|
b55b476728 | ||
|
|
d3d6ae0b33 | ||
|
|
afe6aa9592 | ||
|
|
070ae74efa | ||
|
|
b8ae0c625d | ||
|
|
d43efc52be | ||
|
|
7a6f51ce09 | ||
|
|
fd2be150dc | ||
|
|
2656cecd77 | ||
|
|
bbaad073dd | ||
|
|
1e6a0b74c9 | ||
|
|
f080ebe36e | ||
|
|
de8b59ec16 | ||
|
|
5fa85c5979 | ||
|
|
4766ac875a | ||
|
|
01c885589d | ||
|
|
b38fb9e12a | ||
|
|
c7c1b50a3e | ||
|
|
fa17d77fda | ||
|
|
76e9d0347d | ||
|
|
448aa80fa4 | ||
|
|
656f144267 | ||
|
|
ec54ddd0f8 | ||
|
|
bd2648a8d3 | ||
|
|
89675c5f16 | ||
|
|
422a1eacc3 | ||
|
|
de068d173c | ||
|
|
1996411136 | ||
|
|
af440f540d | ||
|
|
2ef74d4799 | ||
|
|
cba3fdebb0 | ||
|
|
ee64a7b14f | ||
|
|
d085512998 | ||
|
|
ca65328b32 | ||
|
|
663188920e | ||
|
|
18efc41669 | ||
|
|
c2f48df98f | ||
|
|
b03fe601d9 | ||
|
|
cfa5d6dabf | ||
|
|
e1ff50a9af | ||
|
|
c9ee688537 | ||
|
|
2c0338329b | ||
|
|
ad01b9bb5b | ||
|
|
2fb6061424 | ||
|
|
0c121a6cdf | ||
|
|
dd373eccf5 | ||
|
|
8f73cc892e | ||
|
|
9f64d829a4 | ||
|
|
69552b74d9 | ||
|
|
b2cea40ddb | ||
|
|
9212e17440 | ||
|
|
74ca803c84 | ||
|
|
41bc61b363 | ||
|
|
8d841863cb | ||
|
|
d7dcc7bfbe | ||
|
|
bc47b506c2 | ||
|
|
883f9d26c2 |
No files matched your search
@@ -4,3 +4,4 @@
|
|||||||
.opencode
|
.opencode
|
||||||
|
|
||||||
result
|
result
|
||||||
|
/nvim.log
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
# Yookr credential consolidation
|
||||||
|
|
||||||
|
Archived: historical credential inventory and migration evidence.
|
||||||
|
|
||||||
|
This inventory contains names and provenance only. It intentionally contains no
|
||||||
|
credential values or value hashes.
|
||||||
|
|
||||||
|
## Authority
|
||||||
|
|
||||||
|
Use one SOPS-encrypted `~/.config/yookr/credentials.yaml`, backed by the existing
|
||||||
|
mode-0600 user age identity. SOPS 3.13.3 and the identity are already present,
|
||||||
|
and an exact encrypt/decrypt comparison passed on 2026-09-06. The user approved
|
||||||
|
this authority and an active-credentials-first migration. The directory is mode
|
||||||
|
0700 and the encrypted file is mode 0600; it remains outside Git and the Nix
|
||||||
|
store.
|
||||||
|
|
||||||
|
Keep the document hierarchical so operators can inspect and edit everything in
|
||||||
|
one place while callers extract only their own scalar values or subtree. Do not
|
||||||
|
load the complete document into every repository environment. Public endpoints,
|
||||||
|
queue names, bucket names, and other non-secret configuration remain with their
|
||||||
|
normal owners.
|
||||||
|
|
||||||
|
Top-level groups:
|
||||||
|
|
||||||
|
- `company_login`
|
||||||
|
- `databases`
|
||||||
|
- `leafcloud`
|
||||||
|
- `rabbitmq`
|
||||||
|
- `applications`
|
||||||
|
- `archive`
|
||||||
|
|
||||||
|
Active credentials and ten archived credential sources have been migrated.
|
||||||
|
Archive membership does not imply inactivity, so their source namespaces are
|
||||||
|
preserved. Delete redundant plaintext only with explicit approval after each
|
||||||
|
original consumer is verified.
|
||||||
|
|
||||||
|
## Active sources
|
||||||
|
|
||||||
|
- `~/dev/work/yookr-dashboard/backend/.env`: MySQL, MongoDB, Leafcloud S3, and
|
||||||
|
logger credentials.
|
||||||
|
- `~/dev/work/yookr-dashboard/front-end/.env`: `VITE_BASE_TOKEN` is referenced by
|
||||||
|
frontend source and is therefore client-visible, not a protectable secret.
|
||||||
|
- `~/dev/work/yookr-data-science/.env`: WeatherAPI key.
|
||||||
|
- `~/rabbitmq-creds-test`: test RabbitMQ username and password.
|
||||||
|
- `~/irristaud-openstack-creds`: Irristaud project EC2 credentials.
|
||||||
|
- `~/db-creds`: MySQL test/live and MongoDB test/live material.
|
||||||
|
- `~/dev/work/yookr-api/http-client.private.env.json`: company email and
|
||||||
|
password used for API logins.
|
||||||
|
- `~/.local/share/db_ui/connections.json`: existing `traceability` connection.
|
||||||
|
|
||||||
|
All credential-bearing active files above are mode 0600 after the audit.
|
||||||
|
They remain in place pending consumer-by-consumer removal approval. The dashboard
|
||||||
|
backend's MySQL and MongoDB credentials do not match either named test/live pair,
|
||||||
|
so they are preserved separately instead of being assigned an environment by
|
||||||
|
assumption.
|
||||||
|
|
||||||
|
## Archived credential sources
|
||||||
|
|
||||||
|
- Service login: `inteerlijn`, `water-need`, `temperature-relay-dendron`, and
|
||||||
|
`prediction_mildew_rust`.
|
||||||
|
- Rules service: RabbitMQ and database credentials in `rules-service-hex`.
|
||||||
|
- Legacy management: database, logger, and local-login credentials.
|
||||||
|
- Legacy data science and soil-moisture tools: company login credentials.
|
||||||
|
- `salemans`: CMI credentials.
|
||||||
|
|
||||||
|
These files are now mode 0600 and their selected credentials are preserved under
|
||||||
|
`archive`. The user is still cleaning the filesystem, so stale status must be
|
||||||
|
decided per source; stale credentials should be revoked instead of retained
|
||||||
|
indefinitely.
|
||||||
|
|
||||||
|
## Verified consumers
|
||||||
|
|
||||||
|
- `yookr-workbench` decrypts once in memory and exports only its API login, four
|
||||||
|
database connections, Irristaud S3 credential, and test RabbitMQ credential.
|
||||||
|
- Central test API login and the read-only RabbitMQ overview passed.
|
||||||
|
- MariaDB test/live example queries and MongoDB test/live example scripts passed.
|
||||||
|
Both MariaDB sessions negotiated TLS 1.3. The routers expose auto-generated
|
||||||
|
certificates from unavailable private CAs without valid host identities, so
|
||||||
|
only these two URLs disable certificate verification. The MongoDB endpoints
|
||||||
|
publish SRV rather than direct address records and therefore use `mongodb+srv`
|
||||||
|
URLs.
|
||||||
|
- The ephemeral `irristaud:` rclone remote found the sole `irristaud` container
|
||||||
|
and listed its six root entries. No object content was downloaded and no
|
||||||
|
rclone configuration was persisted.
|
||||||
|
|
||||||
|
Dadbod's four display names are active, both MongoDB connections work, both
|
||||||
|
MariaDB examples produce results through Dadbod UI, and the workbench environment
|
||||||
|
supplies successful Kulala response chaining.
|
||||||
|
|
||||||
|
## Excluded from migration
|
||||||
|
|
||||||
|
- Tracked `.env.example` files and public URL-only frontend environments.
|
||||||
|
- Tracked Apache Superset/Hive development defaults.
|
||||||
|
- Empty placeholders, queue names, ports, bucket names, and service URLs.
|
||||||
|
- NixOS SOPS secrets and personal Vaultwarden entries, which already have their
|
||||||
|
own authorities.
|
||||||
|
|
||||||
|
## Observed services
|
||||||
|
|
||||||
|
The scan identified Yookr measurement, authentication, management, aggregation,
|
||||||
|
rules, prediction, dashboard, and data-science workflows plus MySQL, MongoDB,
|
||||||
|
RabbitMQ, Leafcloud S3, logger, SMTP, Vonage, TTN, WeatherAPI, CMI, Superset, and
|
||||||
|
Hive integrations. Presence in an archive does not establish that a service or
|
||||||
|
credential is still active.
|
||||||
|
|
||||||
|
## Immediate findings
|
||||||
|
|
||||||
|
- The dashboard S3 credential and the Irristaud project credential are distinct;
|
||||||
|
the latter is now centralized and its read-only pilot passed.
|
||||||
|
- The generated Yookr OpenAPI document remains malformed, but direct requests use
|
||||||
|
the reviewed local contract and work independently.
|
||||||
|
- Management accepts an account-issued JWT only as the raw `Authorization` value,
|
||||||
|
contrary to its current OpenAPI Bearer declaration.
|
||||||
|
- The Herdr issue 197 pilot produced local-only frontend and backend planning
|
||||||
|
commits without touching company GitHub. Both identify the separate account
|
||||||
|
service, not `yookr-dashboard`, as the implementation owner.
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,190 @@
|
|||||||
|
# Workflow system execution
|
||||||
|
|
||||||
|
Archived: historical implementation evidence, not the current iteration plan.
|
||||||
|
|
||||||
|
Source: [`../workflow-discovery.md`](../workflow-discovery.md)
|
||||||
|
|
||||||
|
Phase one is complete; explicitly deferred pilots remain. This file is the
|
||||||
|
living handoff for operational constraints and future work; implementation
|
||||||
|
history is available in Git.
|
||||||
|
|
||||||
|
## Activation boundary
|
||||||
|
|
||||||
|
Only the user may switch or activate configurations. Agents must not run
|
||||||
|
`nixos-rebuild switch`, Home Manager activation, or an equivalent command that
|
||||||
|
changes the active generation. Evaluation and builds are allowed; after a
|
||||||
|
successful build, provide the exact activation command and wait for the user.
|
||||||
|
|
||||||
|
This boundary includes changes described as user-level, harmless, temporary, or
|
||||||
|
necessary for live verification. A direct Home Manager activation previously
|
||||||
|
restarted Kitty and closed the user's terminal session.
|
||||||
|
|
||||||
|
## Execution discipline
|
||||||
|
|
||||||
|
- Advance all safe independent work before asking the user to act.
|
||||||
|
- Batch declarative changes behind user-controlled activation.
|
||||||
|
- Consolidate empirical, credential, hardware, and approval gates only after no
|
||||||
|
autonomous work remains.
|
||||||
|
- Keep repositories and worktrees outside `~/sync`; synchronize authored
|
||||||
|
artifacts instead.
|
||||||
|
- Keep GitHub and other repository remotes strictly read-only.
|
||||||
|
- Treat Yookr production source as read-only. Dev-tooling changes are allowed;
|
||||||
|
`yookr-workbench` is the only repository whose own source may be changed for
|
||||||
|
these pilots.
|
||||||
|
|
||||||
|
## Current checkpoint
|
||||||
|
|
||||||
|
- State: phase one complete and active; explicitly deferred pilots remain.
|
||||||
|
- Branch: `chore/workflow-system`.
|
||||||
|
- Validation: `nix flake check --no-build --quiet`, all three no-link system
|
||||||
|
builds, generated Zenith and Polaris Niri validation, and all six companion
|
||||||
|
flake evaluations passed on 2026-09-06. The updated data-science shell exposes
|
||||||
|
Python 3.14.7 and its full project check passes. The expected dirty-tree and
|
||||||
|
unknown `modules` warnings were emitted.
|
||||||
|
- Live state: Walker project and terminal actions, daily notes, stable web apps,
|
||||||
|
Evolution D-Bus activation, the Zenith VPN, invocation-scoped GitHub and
|
||||||
|
Context7 credentials, Pinta, and Orion transcription passed their completed
|
||||||
|
pilots. The corrected Actual, WhatsApp, and Outlook launchers all started
|
||||||
|
successfully. The labeled RabbitMQ test/live bookmarks are present, and the
|
||||||
|
invocation-scoped test overview and queue listing passed. Test API login,
|
||||||
|
Yookr administrator read, rules read, aggregation login, and management health
|
||||||
|
passed. Account login plus a raw-token management user read also passed.
|
||||||
|
The approved user-key SOPS authority now contains active credentials and ten
|
||||||
|
provenance-preserving archive namespaces. Its workbench exports passed a test
|
||||||
|
API login, RabbitMQ overview, MySQL test/live `SELECT 1`, MongoDB test/live
|
||||||
|
`ping`, and read-only Irristaud object-storage listing. Dadbod exposes all four
|
||||||
|
names and the MongoDB connections work. Both MariaDB connections now use the
|
||||||
|
native client with narrowly scoped certificate-verification exceptions; their
|
||||||
|
exact example queries passed over TLS 1.3 in both environments. Direct test
|
||||||
|
login and authenticated reads still return HTTP 200 for Yookr, rules, and
|
||||||
|
management. Kulala login and response chaining are confirmed in Neovim, and
|
||||||
|
both MariaDB examples produced results through Dadbod UI.
|
||||||
|
- Herdr ran the issue 197 planning pilot in two predictable, non-overlapping
|
||||||
|
dashboard worktrees. Codex produced frontend commit `20f9d0f`; Claude produced
|
||||||
|
backend commit `bd965ea`. Short, long, done, fallback-agent, and genuinely
|
||||||
|
approval-blocked states behaved correctly, and dirty worktree removal was
|
||||||
|
refused. Nothing reached company GitHub. Both plans found that password reset
|
||||||
|
belongs to the separate account service rather than `yookr-dashboard`.
|
||||||
|
Documented named-session detach/reattach persistence is accepted without a
|
||||||
|
redundant live trial; notifications are intentionally disabled after their
|
||||||
|
live pilot.
|
||||||
|
|
||||||
|
## Phase-one closure
|
||||||
|
|
||||||
|
- The cross-system investigation and Marimo report pilots move into phase two.
|
||||||
|
- Bruno and DBeaver remain available; retiring old applications is not part of
|
||||||
|
phase one.
|
||||||
|
- Issue 197 planning is complete. Before implementation, route it to the actual
|
||||||
|
account repositories; leave the two local dashboard planning branches
|
||||||
|
available as evidence.
|
||||||
|
|
||||||
|
Herdr's bounded pilot is complete. If later use exposes a problem, fall back
|
||||||
|
independently to native agent sessions or native `git worktree add/list/remove`;
|
||||||
|
do not add a wrapper or Worktrunk without a demonstrated gap.
|
||||||
|
|
||||||
|
## Deferred pilots
|
||||||
|
|
||||||
|
Revisit these alongside related phase-two ideas rather than as isolated cleanup.
|
||||||
|
|
||||||
|
- During a docked Zenith session, capture the external display's stable identity
|
||||||
|
and test the two-output `Super+A` exchange. The current recorded session exposed
|
||||||
|
only `eDP-1`.
|
||||||
|
- Resume Evolution only when the user chooses to configure the personal,
|
||||||
|
old-personal, university, work, and Radicale accounts. Keep Thunderbird and
|
||||||
|
Outlook until the daily-use gate passes.
|
||||||
|
- On Android, complete the DAVx5/Radicale and Tasks.org pilots, including default
|
||||||
|
accounts, recurrence, reminders, and Microsoft To Do within documented limits.
|
||||||
|
- Do not replicate the workstation workflow on Polaris until the user resumes
|
||||||
|
the procedure below.
|
||||||
|
|
||||||
|
The Niri pilot is two-output-only. It passes when the active workspaces exchange
|
||||||
|
physical outputs, both arrivals are active, original names are preserved, and
|
||||||
|
focus returns to the original physical output. Any temporary names must be
|
||||||
|
collision-free and restored on success or failure; missing output or workspace
|
||||||
|
state must leave the session unchanged. Keep the helper only after repeated
|
||||||
|
reliable swaps with an acceptable visible transition.
|
||||||
|
|
||||||
|
## Deferred Polaris replication
|
||||||
|
|
||||||
|
Do not access or test Polaris unless the user resumes this deferred replication.
|
||||||
|
Zenith's result remains representative meanwhile.
|
||||||
|
|
||||||
|
1. Activate this NixOS configuration so `networkmanager-openvpn` is installed.
|
||||||
|
2. Restrict `~/sync/yookr-vpn.ovpn` to mode 0600.
|
||||||
|
3. Import it with `nmcli connection import type openvpn file ~/sync/yookr-vpn.ovpn`.
|
||||||
|
4. Rename the connection to `Yookr VPN`, disable autoconnect, and add
|
||||||
|
`data-ciphers=AES-256-CBC`.
|
||||||
|
5. Connect with `nmcli connection up "Yookr VPN"`.
|
||||||
|
6. Create mode-0600 `~/.config/yookr/github-read-only.token` without a trailing
|
||||||
|
newline, then verify a new shell can run
|
||||||
|
`gh project list --owner yookrdev`.
|
||||||
|
7. Create mode-0600 `~/.config/context7/api-key` without a trailing newline,
|
||||||
|
restart Codex after activation, and run one Context7 lookup.
|
||||||
|
|
||||||
|
Replication passes only when the VPN has the expected route and DNS behavior,
|
||||||
|
reaches a test service, reconnects after disconnect and suspend, and survives a
|
||||||
|
reboot without autoconnecting. The two credential files must remain mode 0600;
|
||||||
|
the fresh-shell GitHub read and restarted-Codex Context7 lookup must both work.
|
||||||
|
|
||||||
|
## Durable implementation decisions
|
||||||
|
|
||||||
|
- Active work repositories live under `~/dev/work`, archives under `.archive`,
|
||||||
|
and worktrees under `.worktrees`. Repository trees never enter Syncthing.
|
||||||
|
- Participating repositories expose non-mutating direnv shells, minimal flake
|
||||||
|
checks, native commands through `just`, concise `AGENTS.md`, and machine-local
|
||||||
|
credential inputs.
|
||||||
|
- `yookr-data-science/conf/local/credentials.yml` is an approved narrow
|
||||||
|
application-owned exception to the external credential-file default: Kedro's
|
||||||
|
named credential dataset resolves it from the native ignored `conf/local`
|
||||||
|
hierarchy. Keep it untracked and mode 0600.
|
||||||
|
- `yookr-data-science` follows ordinary `nixos-unstable`, like the other
|
||||||
|
companion repositories; it needs no `devenv-nixpkgs` compatibility input.
|
||||||
|
- `yookr-workbench` starts with cross-system work only; isolation and additional
|
||||||
|
tools wait for observed needs. Its one API environment catalogue covers the
|
||||||
|
Yookr, rules, aggregation, and management APIs; Kulala owns requests and
|
||||||
|
Dadbod receives the four named database connections from the workbench's
|
||||||
|
SOPS-derived environment. The two MariaDB routers expose auto-generated
|
||||||
|
private-CA certificates without a valid host identity, so only those URLs
|
||||||
|
disable certificate verification while retaining TLS; restore verification
|
||||||
|
when infrastructure provides usable CA and host certificates.
|
||||||
|
- The reviewed `yookr-api/openapi.yaml` remains the usable local contract. The
|
||||||
|
deployed generated document's dangling `ReadParameters` reference is accepted
|
||||||
|
for now and does not block direct API requests.
|
||||||
|
- Walker's native Elephant menu scans repository roots and calls one Nix-owned
|
||||||
|
`open-project` command. Rare menu changes take effect at login.
|
||||||
|
- Home Manager declares the three stable Vivaldi launcher paths with forced
|
||||||
|
ownership. Vivaldi's manual `Create shortcuts` action can replace one until a
|
||||||
|
changed Home Manager generation reclaims it; repeating a no-op activation need
|
||||||
|
not relink it. This accepted edge case does not justify filtering, immutable
|
||||||
|
files, or a watcher because that action is not part of normal use.
|
||||||
|
- Kitty and Neovim are the sole declared terminal and editor. Retired duplicate
|
||||||
|
applications and global language runtimes stay absent unless a concrete owner
|
||||||
|
appears.
|
||||||
|
- The fine-grained GitHub token and Context7 key stay in mode-0600 machine-local
|
||||||
|
files and are exposed only to their callers. Secrets do not enter Nix or broad
|
||||||
|
process environments.
|
||||||
|
- The credential audit and approved central SOPS authority are in
|
||||||
|
[`credential-consolidation.md`](credential-consolidation.md). The authority is
|
||||||
|
active, while original plaintext sources remain pending consumer-specific
|
||||||
|
verification and explicit removal approval.
|
||||||
|
- `sync/notes` is the single notebook owner. Daily notes, meetings, and raw
|
||||||
|
transcripts have separate paths, and agents do not create issues or ingest
|
||||||
|
transcripts automatically.
|
||||||
|
- Orion is the sole transcription owner. It waits for file settlement, validates
|
||||||
|
media, archives originals, and publishes an unlabeled transcript when
|
||||||
|
diarization fails.
|
||||||
|
- Evolution remains a deferred presentation-layer pilot. Microsoft 365 and
|
||||||
|
Radicale remain the data authorities; Thunderbird and Outlook remain available.
|
||||||
|
- GitHub and every other repository remote stay read-only. Local files, commits,
|
||||||
|
fetches, clones, and worktrees remain available.
|
||||||
|
- The provisional team chain is Project Overview project → work package → user
|
||||||
|
requirement → Software Development Backlog ticket → repository issue → one
|
||||||
|
pull request. Treat it as discovery context, not automation policy, until the
|
||||||
|
team settles the workflow; company GitHub remains read-only throughout.
|
||||||
|
- Yookr production source stays read-only during workflow pilots. Changes to
|
||||||
|
development tooling are allowed, and `yookr-workbench` remains the explicit
|
||||||
|
source-code exception.
|
||||||
|
|
||||||
|
## Next step
|
||||||
|
|
||||||
|
Begin phase-two discovery from the user's new workflow ideas.
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# SharePoint reference mirror
|
||||||
|
|
||||||
|
Archived: guidance for the existing implementation, not a new design decision.
|
||||||
|
|
||||||
|
Superseded: this describes the earlier single-source, environment-file-gated
|
||||||
|
implementation. The current [working state](../constellation-work.md) records two
|
||||||
|
fixed library mirrors gated only by the presence of `rclone.conf`. Do not use the
|
||||||
|
setup procedure below as current operational guidance.
|
||||||
|
|
||||||
|
The Zenith user timer mirrors one selected company SharePoint document library
|
||||||
|
into `~/.local/share/yookr-reference/sharepoint` hourly. SharePoint is
|
||||||
|
authoritative: remote updates overwrite local files and remote deletions remove
|
||||||
|
local files. Never author files there; edit them in SharePoint's web UI. The job
|
||||||
|
stops before more than 100 local deletions and reports the failure in the user
|
||||||
|
journal. A failed run may leave earlier updates in place and is not evidence of a
|
||||||
|
complete current snapshot; rclone does not delete destination files when the run
|
||||||
|
has errors.
|
||||||
|
|
||||||
|
The timer remains inert until both `~/.config/rclone/rclone.conf` and
|
||||||
|
`~/.config/rclone/sharepoint-reference.env` exist and the latter names a source.
|
||||||
|
Before adding the SharePoint remote or source file, the user must explicitly
|
||||||
|
start the interactive company sign-in and consent step. Use only delegated,
|
||||||
|
cloud-read-only scopes:
|
||||||
|
`Files.Read Files.Read.All Sites.Read.All offline_access`. Do not accept rclone's
|
||||||
|
broader default scopes or create an application registration. Tenant policy may
|
||||||
|
require administrator consent or an approved single-tenant application; involve
|
||||||
|
the administrator only if the consent response requires it.
|
||||||
|
|
||||||
|
After approval, run `rclone config`, choose Microsoft OneDrive, set the advanced
|
||||||
|
`access_scopes` value above, and select one company SharePoint document library
|
||||||
|
(not a personal account). Before enabling the job, inspect and accept its exact
|
||||||
|
scope, footprint, and first change set:
|
||||||
|
|
||||||
|
```console
|
||||||
|
rclone config redacted company-sharepoint
|
||||||
|
rclone lsd company-sharepoint:
|
||||||
|
rclone size company-sharepoint:
|
||||||
|
rclone sync company-sharepoint: ~/.local/share/yookr-reference/sharepoint --dry-run --max-delete 100
|
||||||
|
```
|
||||||
|
|
||||||
|
The remote-scoped redacted output confirms the configured requested scopes, not
|
||||||
|
what the tenant actually granted. Confirm the consent response also contains only
|
||||||
|
the requested read scopes; stop if it denies them or offers broader authority.
|
||||||
|
|
||||||
|
Only after that preview is accepted, create the gate with mode `0600`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
RCLONE_SHAREPOINT_SOURCE=company-sharepoint:
|
||||||
|
```
|
||||||
|
|
||||||
|
Save it as `~/.config/rclone/sharepoint-reference.env`. Home Manager activation
|
||||||
|
then enables the hourly timer. This is the first bounded library, not a permanent
|
||||||
|
allowlist or a claim that all accessible SharePoint content is mirrored. Add
|
||||||
|
another library only after its own size/preview check, using another native unit
|
||||||
|
and dedicated destination rather than widening this source silently. Refresh and
|
||||||
|
inspect the current unit with:
|
||||||
|
|
||||||
|
```console
|
||||||
|
systemctl --user start sharepoint-reference-sync.service
|
||||||
|
systemctl --user status sharepoint-reference-sync.service
|
||||||
|
journalctl --user -u sharepoint-reference-sync.service
|
||||||
|
```
|
||||||
|
|
||||||
|
For an accepted deletion set larger than 100 files, rerun the dry-run and then a
|
||||||
|
manual `rclone sync` without `--max-delete`; the scheduled guard stays in place.
|
||||||
|
The mutable OAuth token remains in rclone's config outside the Nix store. The
|
||||||
|
local directory is user-writable and its read-only consumer policy is not an OS
|
||||||
|
permission or credential-isolation boundary. New mirror files are private to the
|
||||||
|
user by default (`UMask=0077`), but same-user processes can still read and change
|
||||||
|
them.
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
# Workflow system blueprint
|
||||||
|
|
||||||
|
Status: phase one implemented and active; explicitly deferred pilots remain.
|
||||||
|
The operational handoff lives in
|
||||||
|
[`plans/workflow-system.md`](plans/workflow-system.md).
|
||||||
|
|
||||||
|
This document is the durable design for the workstation and surrounding Yookr
|
||||||
|
workflow. Implementation history belongs in Git.
|
||||||
|
|
||||||
|
## Governing intent
|
||||||
|
|
||||||
|
Build a quiet, keyboard-first control plane over development, investigation,
|
||||||
|
operations, agents, and personal knowledge. Keep the system small and give each
|
||||||
|
intention one canonical owner.
|
||||||
|
|
||||||
|
- Standardize vocabulary and entry points without forcing unlike workloads onto
|
||||||
|
one implementation.
|
||||||
|
- Put frequent actions on direct keys and less frequent actions on their owning
|
||||||
|
discovery surface.
|
||||||
|
- Keep stable packages, services, integration, and durable preferences in Nix.
|
||||||
|
Keep credentials, sessions, databases, caches, and other mutable state with
|
||||||
|
their owning application.
|
||||||
|
- Prefer native file formats and supported application layers. Add wrappers only
|
||||||
|
for demonstrated gaps.
|
||||||
|
- Repositories own reproducible development context, executable project
|
||||||
|
documentation, and code-specific artifacts.
|
||||||
|
- Select `local`, `test`, or `live` per operation; do not depend on an ambient
|
||||||
|
production context.
|
||||||
|
- Make production and destructive actions more deliberate than navigation and
|
||||||
|
read-only inspection.
|
||||||
|
- Promote automation only after the manual workflow repeats and can be verified.
|
||||||
|
- Optimize conceptual complexity and review burden, not package count or line
|
||||||
|
count in isolation.
|
||||||
|
|
||||||
|
The main coordinates are scope (`work`, `own`, `ext`, or `forks`), Yookr domain,
|
||||||
|
environment (`local`, `test`, or `live`), and intention (develop, inspect, query,
|
||||||
|
review, operate, or deploy).
|
||||||
|
|
||||||
|
## Ownership model
|
||||||
|
|
||||||
|
<!-- markdownlint-disable MD013 -->
|
||||||
|
|
||||||
|
| Intention | Canonical owner |
|
||||||
|
| --- | --- |
|
||||||
|
| Find applications, projects, or windows | Walker/Elephant and direct Niri bindings |
|
||||||
|
| Search personal passwords | Walker with `rbw`; company Bitwarden stays in its browser extension |
|
||||||
|
| Navigate browser state | Vivaldi Quick Commands |
|
||||||
|
| Arrange windows and displays | Niri dynamic workspaces |
|
||||||
|
| Work in a terminal | Kitty |
|
||||||
|
| Edit related files and views | Neovim |
|
||||||
|
| Enter a repository environment | `direnv` with `nix-direnv` |
|
||||||
|
| Discover project actions | `just --list` |
|
||||||
|
| Run edited first-party code | Native processes, optionally Process Compose |
|
||||||
|
| Run a container-only project stack | Rootless Podman Compose |
|
||||||
|
| Run a persistent containerized user service | Rootless Podman Quadlet |
|
||||||
|
| Run a durable host service | NixOS modules and systemd |
|
||||||
|
| Exercise APIs | Kulala and `xh`, with tracked `.http` files |
|
||||||
|
| Query databases | Dadbod and native driver CLIs |
|
||||||
|
| Investigate across Yookr systems | `yookr-workbench` |
|
||||||
|
| Connect the Yookr VPN | NetworkManager/OpenVPN through Noctalia |
|
||||||
|
| Inspect test Kubernetes | `just k8s test` using Gardenctl and read-only K9s |
|
||||||
|
| Inspect RabbitMQ | Official management UI; `rabbitmqadmin` for exact terminal operations |
|
||||||
|
| Browse S3-compatible storage | Native `rclone` commands |
|
||||||
|
| Capture and find notes | `zk` through Neovim in one synchronized Markdown notebook |
|
||||||
|
| Present work and personal PIM | Evolution pilot beside Thunderbird and Outlook |
|
||||||
|
| Present personal PIM on Android | DAVx5, aCalendar+, Google Contacts, and Tasks.org |
|
||||||
|
| Give agents durable project context | `AGENTS.md` and project commands |
|
||||||
|
| Run top-level agents | Herdr on demand |
|
||||||
|
| Maintain conversation state and subagents | Each native agent, primarily Codex |
|
||||||
|
| Review local changes | LazyGit in the task checkout |
|
||||||
|
| Review pull requests | `gh`, then a review worktree when local checks are useful |
|
||||||
|
|
||||||
|
<!-- markdownlint-enable MD013 -->
|
||||||
|
|
||||||
|
## Repository contract
|
||||||
|
|
||||||
|
Active work repositories live under `~/dev/work`; inactive repositories live
|
||||||
|
under `~/dev/work/.archive`, and worktrees under `~/dev/work/.worktrees`.
|
||||||
|
Repositories and worktrees never live under `~/sync`.
|
||||||
|
|
||||||
|
Participating repositories use the following small contract:
|
||||||
|
|
||||||
|
- A tracked `.envrc` enters the default flake development shell without starting
|
||||||
|
services, fetching data, or mutating the checkout.
|
||||||
|
- `flake.nix` owns reproducible dependencies, checks, packages, and formatting.
|
||||||
|
- `just --list` indexes non-obvious tasks and delegates to native commands.
|
||||||
|
- `AGENTS.md` contains concise project facts, invariants, architecture pointers,
|
||||||
|
and checks without duplicating global guidance.
|
||||||
|
- Service-owned `.http` and schema-owned `.sql` files stay beside their owner;
|
||||||
|
generated views, caches, and scratch output do not become durable sources.
|
||||||
|
- Secrets enter at runtime from an approved source or a user-only file outside
|
||||||
|
checkouts, initially `~/.config/yookr/<repository>.env`.
|
||||||
|
- A new worktree behaves like a fresh clone and requires its own explicit
|
||||||
|
`direnv allow`.
|
||||||
|
- Branch-derived ports, databases, and container names are added only after a
|
||||||
|
real collision.
|
||||||
|
|
||||||
|
Use Process Compose only when multiple foreground processes benefit from one
|
||||||
|
visible lifecycle. Use Podman Compose for wholly containerized project stacks,
|
||||||
|
Quadlet for persistent user containers, and NixOS modules for durable host
|
||||||
|
services. Do not nest lifecycle tools for another status screen.
|
||||||
|
|
||||||
|
`yookr-workbench` owns cross-system API requests, operational queries, the
|
||||||
|
Garden/Kubernetes entry point, and Marimo investigations. It does not collect
|
||||||
|
service OpenAPI specifications, schema migrations, deployable model code, or
|
||||||
|
copied application state.
|
||||||
|
|
||||||
|
## Interaction and knowledge boundaries
|
||||||
|
|
||||||
|
- Walker scans the four repository roots, excludes `.archive` and `.worktrees`,
|
||||||
|
and invokes one Nix-owned `open-project` command. The command opens Kitty at
|
||||||
|
the repository root, starts Neovim, and leaves a shell after Neovim exits.
|
||||||
|
- Vivaldi remains the bookmark and web-app authority. Home Manager declares
|
||||||
|
stable launchers for Actual, WhatsApp, and Outlook without duplicating browser
|
||||||
|
state and reclaims their paths when a changed Home Manager generation is
|
||||||
|
deployed. Manual shortcut regeneration may replace one meanwhile and is an
|
||||||
|
accepted unused edge case. Its
|
||||||
|
`Operations` folder owns visibly labeled test/live RabbitMQ bookmarks; terminal
|
||||||
|
inspection uses the Nix-provided `rabbitmqadmin-ng` on demand.
|
||||||
|
- Niri keeps dynamic general-purpose workspaces and a compact navigation and
|
||||||
|
movement vocabulary. The two-output active-workspace exchange remains a
|
||||||
|
bounded pilot.
|
||||||
|
- Codex is primary; Claude Code and Pi are fallbacks. Herdr owns persistence and
|
||||||
|
attention for top-level sessions, while each agent owns its internal state.
|
||||||
|
- Use one primary writer per checkout. Subagents may perform bounded independent
|
||||||
|
read-heavy work, but overlapping changes are sequenced.
|
||||||
|
- Substantial multi-session work may keep one living
|
||||||
|
`docs/plans/<task-slug>.md`; lasting knowledge moves to normal documentation
|
||||||
|
and transient execution history is removed when finished.
|
||||||
|
- `~/sync/notes` is the Markdown/zk authority. Daily intake uses
|
||||||
|
`daily/YYYY-MM-DD.md`; planned meetings and raw transcripts use `meetings/`
|
||||||
|
and `transcripts/` respectively.
|
||||||
|
- Microsoft 365 remains authoritative for work/university PIM and Radicale for
|
||||||
|
personal CalDAV, VTODO, and CardDAV. Clients present those authorities without
|
||||||
|
bridging or copying them.
|
||||||
|
- Fossify records on Android and Syncthing delivers completed recordings to
|
||||||
|
Orion. Orion owns event-driven CPU transcription, diarization fallback,
|
||||||
|
archival, and Markdown publication.
|
||||||
|
|
||||||
|
## Safety boundaries
|
||||||
|
|
||||||
|
GitHub and all other remotes are read-only. Local commits, clones, fetches, and
|
||||||
|
worktrees are allowed; remote mutation requires a separate change to policy.
|
||||||
|
Yookr production source is also read-only during these pilots. Development
|
||||||
|
tooling may be changed, and `yookr-workbench` is the explicit source-code
|
||||||
|
exception.
|
||||||
|
|
||||||
|
Credentials and `.env` files normally stay outside Git, the Nix store, and broad
|
||||||
|
synchronization. Machine-local Yookr credentials use the approved user-key SOPS
|
||||||
|
authority at `~/.config/yookr/credentials.yaml`; callers expose only the fields
|
||||||
|
they need. Original plaintext sources remain until their consumers are verified
|
||||||
|
and removal is explicitly approved. The accepted `yookr-vpn.ovpn` is a narrow
|
||||||
|
exception for Zenith and Polaris: keep it user-restricted and import it into
|
||||||
|
NetworkManager without printing or committing its contents.
|
||||||
|
|
||||||
|
`yookr-data-science/conf/local/credentials.yml` is a separate application-owned
|
||||||
|
exception: Kedro resolves its named credential dataset through the conventional
|
||||||
|
ignored `conf/local` hierarchy. Keep the file untracked and mode 0600; do not
|
||||||
|
generalize the exception to other repositories.
|
||||||
|
|
||||||
|
Only the user activates a NixOS or Home Manager generation. Agents may evaluate
|
||||||
|
and build configurations, then provide an activation command.
|
||||||
|
|
||||||
|
## Phase-one closure
|
||||||
|
|
||||||
|
- The workbench environment, all four SOPS-derived Dadbod connections, read-only
|
||||||
|
example-query runs, and Kulala response chaining passed. The cross-system
|
||||||
|
investigation and Marimo report pilots move into phase two.
|
||||||
|
- Add another ephemeral read-only rclone remote only when credentials for a new
|
||||||
|
Leafcloud project become available. Irristaud listing has passed; do not upload.
|
||||||
|
- Use the reviewed local Yookr OpenAPI contract while the accepted malformed
|
||||||
|
generated test document remains deployed.
|
||||||
|
- Herdr's bounded issue 197 pilot is complete. Documented named-session
|
||||||
|
detach/reattach persistence is accepted without a redundant live trial, and
|
||||||
|
notifications are intentionally disabled. Codex/Claude fallback, attention
|
||||||
|
states, local branches, parallel non-overlapping plans, and the dirty-removal
|
||||||
|
guard passed; the plans show that implementation belongs outside the dashboard
|
||||||
|
repository.
|
||||||
|
- Keep Bruno and DBeaver; retiring old applications is outside phase one.
|
||||||
|
|
||||||
|
## Deferred pilots
|
||||||
|
|
||||||
|
Revisit these alongside related phase-two ideas rather than as isolated cleanup.
|
||||||
|
|
||||||
|
- Capture Zenith's external display identity during a docked session and test the
|
||||||
|
two-output `Super+A` exchange, including name and focus restoration on failure.
|
||||||
|
- Resume Evolution and Android PIM only when the user chooses to run those daily
|
||||||
|
use pilots.
|
||||||
|
- Replicate the proven workstation workflow on Polaris only when the user resumes
|
||||||
|
its machine-local VPN and credential procedure.
|
||||||
|
|
||||||
|
## Deferred work
|
||||||
|
|
||||||
|
- Define the team release process and OpenAPI publication policy before encoding
|
||||||
|
deployment automation.
|
||||||
|
- Adopt a company-wide infrastructure secret source only after Yookr selects one.
|
||||||
|
- Publish `yookr-workbench` only when sharing becomes useful.
|
||||||
|
- Pilot SharePoint browse/download through `rclone` after Microsoft consent.
|
||||||
|
- Revisit Worktrunk, `codex agents`, Walker-to-agent launching, formal agent
|
||||||
|
evaluation, remote builders, CI runners, and agent offload only after a concrete
|
||||||
|
gap appears.
|
||||||
|
- Add report servers, notebook hubs, groupware, terminal PIM, meeting summaries,
|
||||||
|
concurrency isolation, OCR, dictation, clipboard remapping, or additional
|
||||||
|
convenience surfaces only after repeated use establishes an owner.
|
||||||
|
|
||||||
|
## Reference baseline
|
||||||
|
|
||||||
|
Recheck fast-moving interfaces against their pinned versions before changing
|
||||||
|
them.
|
||||||
|
|
||||||
|
<!-- markdownlint-disable MD013 -->
|
||||||
|
|
||||||
|
- Projects: [Nix flake templates](https://nix.dev/manual/nix/latest/command-ref/new-cli/nix3-flake-init), [nix-direnv](https://github.com/nix-community/nix-direnv), [just manual](https://just.systems/man/en/), [Podman Compose](https://docs.podman.io/en/latest/markdown/podman-compose.1.html), [Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html), [Marimo](https://docs.marimo.io/).
|
||||||
|
- APIs/data: [Kulala](https://kulala.app/), [Dadbod](https://github.com/tpope/vim-dadbod), [RabbitMQ management](https://www.rabbitmq.com/docs/management), [rclone S3](https://rclone.org/s3/), [rclone OneDrive/SharePoint](https://rclone.org/onedrive/).
|
||||||
|
- Desktop: [Walker](https://walkerlauncher.com/docs/providers), [Elephant menus](https://github.com/abenz1267/elephant/tree/master/internal/providers/menus), [Vivaldi web apps](https://help.vivaldi.com/desktop/miscellaneous/progressive-web-apps/), [Niri IPC](https://niri-wm.github.io/niri/IPC.html).
|
||||||
|
- Agents: [Codex configuration](https://learn.chatgpt.com/docs/config-file/config-basic), [Codex long-running work](https://learn.chatgpt.com/docs/long-running-work), [Herdr](https://herdr.dev/docs/configuration/), [Git worktrees](https://git-scm.com/docs/git-worktree).
|
||||||
|
- PIM/knowledge: [Evolution account types](https://help.gnome.org/evolution/intro-account-types.html), [Radicale](https://radicale.org/v3.html), [DAVx5](https://manual.davx5.com/introduction.html), [Tasks.org](https://tasks.org/docs/), [`zk` daily journal](https://github.com/zk-org/zk/blob/main/docs/tips/daily-journal.md).
|
||||||
|
- Infrastructure: [Gardenctl](https://gardener.cloud/docs/gardenctl-v2/), [NetworkManager](https://networkmanager.pages.freedesktop.org/NetworkManager/NetworkManager/nmcli.html), [Syncthing](https://docs.syncthing.net/users/syncing).
|
||||||
|
|
||||||
|
<!-- markdownlint-enable MD013 -->
|
||||||
@@ -0,0 +1,294 @@
|
|||||||
|
# Constellation: working state
|
||||||
|
|
||||||
|
Read [the design](constellation.md) and this file to resume. Keep this file short:
|
||||||
|
replace superseded state rather than appending a chronological log.
|
||||||
|
|
||||||
|
## Working agreement
|
||||||
|
|
||||||
|
- Explore the philosophy through concrete use, discuss meaningful choices, then
|
||||||
|
implement a small coherent change. Curiosity and alternative designs are welcome;
|
||||||
|
an idea need not prove a defect before we explore it.
|
||||||
|
- Write succinctly without losing important details. Distinguish accepted choices,
|
||||||
|
proposals and observations. Ask when intent would change the design; resolve
|
||||||
|
routine implementation details autonomously. Infer opportunities from the user's
|
||||||
|
philosophy and actual use; contribute design ideas beyond literal backlog items.
|
||||||
|
Continue to the next natural step when the user could only usefully say "continue";
|
||||||
|
pause for material choices or missing authority, not routine progress.
|
||||||
|
- Minimize input stops: plan a coherent batch of autonomous work and gather the
|
||||||
|
material inputs needed for the next batch together. Avoid serial question/action
|
||||||
|
loops. When pausing, state exactly what input is needed and what it will decide;
|
||||||
|
otherwise continue with the next logical step rather than ending with an offer.
|
||||||
|
- The main agent owns alignment, design and integration and may do small work.
|
||||||
|
Use subagents for bounded independent investigations or implementation with clear
|
||||||
|
ownership. Begin with at most two workers; avoid overlapping writes, duplicate
|
||||||
|
investigations and mandatory delegation of trivial tasks.
|
||||||
|
- Give workers the question, relevant paths, constraints and expected result.
|
||||||
|
Prefer a compact brief and fresh context when sufficient; retain relevant prior
|
||||||
|
context for follow-ups. Return conclusions, uncertainty and evidence pointers,
|
||||||
|
not raw logs. Astra/Sol orchestration is a candidate to learn from, not a fixed rule.
|
||||||
|
- Read only what can affect the current decision. Use quiet commands and bounded
|
||||||
|
output; keep large logs in `/tmp` and inspect relevant failures. Do not repeatedly
|
||||||
|
check settled facts. Consult current documentation for consequential or unfamiliar
|
||||||
|
interfaces when needed for the task.
|
||||||
|
- No tests unless explicitly requested. Keep other verification proportional;
|
||||||
|
report only what was actually checked. Avoid turning small changes into campaigns.
|
||||||
|
- Keep durable decisions in the design and current questions/next steps here.
|
||||||
|
Add an area-specific document only when an active topic outgrows this arrangement.
|
||||||
|
No separate backlog, scratchpad, audit ledger or agent-role files for now.
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
Repository remotes are read-only. Only the user activates system generations.
|
||||||
|
Agents must not have write access to live company systems; test writes require
|
||||||
|
task-specific authority and care. Do not read secret values for layout discovery.
|
||||||
|
Current exploration does not authorize relocating credentials, synchronizing
|
||||||
|
company content or deleting existing material. Existing local changes are preserved.
|
||||||
|
|
||||||
|
## Git baseline — 2026-09-09
|
||||||
|
|
||||||
|
The accumulated NixOS changes are recorded in focused local commits on
|
||||||
|
`chore/workflow-system`: AI tooling/inputs, editor ergonomics, query persistence
|
||||||
|
and target context, workspace navigation, Notes, SharePoint, Zellij and TeamViewer.
|
||||||
|
The original long handoff and archived plans are preserved in commit `4e3a3ac`;
|
||||||
|
use Git history for chronology. `nvim.log` is retained locally and ignored.
|
||||||
|
Workbench changes are committed on its local `main`: `eb8da6a` organizes HTTP/SQL
|
||||||
|
material and `063157c` archives helpers and documents native tools. The ordinary
|
||||||
|
company-root files are outside either repository and remain user-owned.
|
||||||
|
This cleanup preserves implementation behavior; a commit does not establish runtime
|
||||||
|
acceptance. Keep subsequent implementation and its documentation in the same
|
||||||
|
coherent commit before starting unrelated work.
|
||||||
|
|
||||||
|
## Implemented state
|
||||||
|
|
||||||
|
- **Places:** `~/yookr` has ordinary `.envrc` and `AGENTS.md` files; its environment
|
||||||
|
loads workbench tools only. Workbench is at `~/yookr/workbench`, company projects
|
||||||
|
at `~/yookr/projects`, and personal groups at `~/projects/{own,ext,forks}`.
|
||||||
|
Direct moves retained archives/worktrees; all three linked dashboard worktrees
|
||||||
|
were repaired. Nix owns tools/integration, not these workspace files.
|
||||||
|
- **Navigation:** Walker enters Yookr or a repository; Git identity follows the
|
||||||
|
company root; XDG projects points to `~/projects`. Notes has a desktop entry
|
||||||
|
opening `~/sync/notes` without creating a daily note. Existing note commands,
|
||||||
|
project search and Niri daily-note behavior remain.
|
||||||
|
- **Synchronization:** Bruno collections were previously moved to Trash on Zenith
|
||||||
|
and their shared Syncthing entry removed. Other devices' files were untouched.
|
||||||
|
Syncthing was subsequently observed running. Notes and credentials remain in place.
|
||||||
|
- **API/database work:** workbench `http/` groups requests by service with shared
|
||||||
|
authentication; `databases/` groups reusable queries by database. Private HTTP
|
||||||
|
environment files are ignored at any depth. Dadbod working queries persist under
|
||||||
|
`stdpath('data')/db_ui/working`; write them there without promoting them into Git.
|
||||||
|
Saved-query storage also contains connection state and must stay outside Git.
|
||||||
|
Lualine uses native Kulala environment and Dadbod connection/timing components.
|
||||||
|
These indicators are not access controls.
|
||||||
|
- **Editor ergonomics:** word-boundary wrapping, count-aware displayed-line `j/k`
|
||||||
|
in ordinary normal/visual buffers, and Blink Escape cancellation. The existing
|
||||||
|
`tests/neovim-ergonomics.lua` is retained; earlier smoke-check evidence is in the
|
||||||
|
archived plan, with interactive preview restoration/visual behavior unproven.
|
||||||
|
- **Agents:** Herdr is selected; agent-deck and tmux remain installed alongside it.
|
||||||
|
Codex has agent-deck notifications and hooks enabled. Shared Context7/NixOS skills
|
||||||
|
live under `.agents/skills`; a Nix-managed marketplace exposes Ponytail.
|
||||||
|
Zellij is also declared on workstations. Further project workflow work is deferred.
|
||||||
|
- **SharePoint:** Zenith declares an hourly service syncing `company-sharepoint:`
|
||||||
|
into `~/.local/share/yookr-reference/sharepoint/Algemeen` and
|
||||||
|
`company-sharepoint-projecten:` into `Projecten`. Each invocation has
|
||||||
|
`--max-delete 100`; new files use `UMask=0077`. The latest implementation only
|
||||||
|
checks for `rclone.conf`; the old environment-file gate is gone. Archived setup
|
||||||
|
instructions describe an earlier version. Consent, remote configuration and
|
||||||
|
synchronization state were not inspected during this cleanup.
|
||||||
|
- **Remote support:** Zenith enables TeamViewer. Temporary Xorg/Xfce settings are
|
||||||
|
comments only. The purpose beyond remote support and runtime acceptance were
|
||||||
|
not recorded; preserve the change without calling it a settled design.
|
||||||
|
- **Inputs:** accumulated lock updates are retained, including an older Elephant
|
||||||
|
revision (`376ee71c` replacing `23f37238`). No rollback rationale was recorded.
|
||||||
|
|
||||||
|
## Activation and verification
|
||||||
|
|
||||||
|
Earlier handoffs report user activation of the relocated XDG/Git/Walker paths and
|
||||||
|
Dadbod working-query persistence. Notes and the newer target statusline were last
|
||||||
|
recorded as pending activation. Only Zenith's filesystem was relocated; other hosts
|
||||||
|
need their own migration before adopting the shared paths. Reopen shells or
|
||||||
|
recreate path-dependent development environments as needed; no compatibility links
|
||||||
|
or cache rewrites were introduced.
|
||||||
|
|
||||||
|
For this cleanup, `nix flake check --no-build --quiet` and diff whitespace checking
|
||||||
|
passed in both NixOS and workbench. NixOS emitted the expected dirty-tree and unknown
|
||||||
|
`modules` warnings; workbench emitted only the dirty-tree warning.
|
||||||
|
No builds, tests, activation, credential reads or company-service calls were
|
||||||
|
performed. Active-generation differences were not checked; earlier activation
|
||||||
|
reports are not a fresh comparison with this baseline.
|
||||||
|
|
||||||
|
## Open choices and next discussion
|
||||||
|
|
||||||
|
Current focus: look and feel/theming, informed by `~/sync/notes/setup-todo.md`.
|
||||||
|
The user accepted complete Nix theme modules with arbitrary plugin/configuration
|
||||||
|
behavior, rather than Stylix or a palette-only abstraction. The single import in
|
||||||
|
`modules/capabilities/theme.nix` selects `./_themes/kanagawa.nix`. `_themes` is
|
||||||
|
excluded from automatic module discovery, so unselected themes are not loaded.
|
||||||
|
Kanagawa owns GTK/icons/cursor, Qt integration, Kitty, Niri colors, Noctalia
|
||||||
|
palette/font/wallpaper, Herdr colors, the native Neovim plugin and its setup, and
|
||||||
|
Limine/SDDM/Plymouth appearance. Only Kanagawa is implemented so far; switching
|
||||||
|
means selecting another module and rebuilding, not a live theme picker.
|
||||||
|
Walker shares a compact layout with theme-provided colors: reduced padding,
|
||||||
|
24px icons, clearer secondary text, and a smaller minimum window height.
|
||||||
|
Limine's terminal background is fully transparent with no edge gradient so it
|
||||||
|
does not obscure the wallpaper. Runtime appearance needs user verification.
|
||||||
|
SDDM's purple-leaves theme and Plymouth's spinner are retained within Kanagawa;
|
||||||
|
their visual redesign and the low-frame-rate boot animation remain open.
|
||||||
|
Verification: flake evaluation and both workstation builds passed. A headless
|
||||||
|
check of the built Neovim confirmed Kanagawa Wave, inactive-window dimming and
|
||||||
|
the custom gutter setting. Rendered Herdr TOML, Walker XML and Limine settings
|
||||||
|
also passed targeted checks. No system activation or live desktop changes performed.
|
||||||
|
|
||||||
|
Dictation: plain local transcription is selected; rambling cleanup is deferred.
|
||||||
|
Handy preferences are application-owned again: the Nix settings generator and
|
||||||
|
startup reset are removed. The existing settings file is left untouched.
|
||||||
|
Nix installs Handy/wtype and runs Handy as a graphical-session user service.
|
||||||
|
Super+D launches a short-lived Python/evdev listener: hold to record, release D
|
||||||
|
or Super to finish. Both keys must be on the same keyboard. Niri owns the shortcut
|
||||||
|
and disables repeat; no persistent keyboard logger or exclusive input grab runs.
|
||||||
|
A udev uaccess rule grants the active local user access to keyboard event devices.
|
||||||
|
Super+Shift+D toggles; Super+Ctrl+D cancels. Both stop any active hold listener
|
||||||
|
before issuing their Handy command, preventing a later release from restarting
|
||||||
|
recording. Begin push-to-talk from idle: Handy exposes toggles, not idempotent
|
||||||
|
start/stop commands. Niri 26.04 itself has no key-release bindings.
|
||||||
|
Noctalia suppresses microphone activity popups/indicators; camera and screen-sharing
|
||||||
|
indications remain. Automatic paste and live capture need interactive checks.
|
||||||
|
|
||||||
|
Hang investigation, parked at the user's request: a debugger capture confirmed
|
||||||
|
Handy's recorder waits for another audio chunk before processing its stop command.
|
||||||
|
When capture stalls, stopping can therefore hang indefinitely; the transcription
|
||||||
|
worker was idle. Bluetooth transport failures accompanied the hangs, and the user
|
||||||
|
reported dictation working after disconnecting the Sony WH-1000XM6. The user wants
|
||||||
|
its microphone when connected. Keeping the headset in a microphone-enabled HFP
|
||||||
|
profile was proposed to avoid repeated profile transitions, but was not applied
|
||||||
|
or verified; the reconnect attempt timed out. No source or Bluetooth configuration
|
||||||
|
was changed. CPU and Vulkan batch inference both worked; changing inference backend
|
||||||
|
is not an established fix. Resume this investigation only if requested.
|
||||||
|
Synthetic listener checks cover release during startup, repeat, modifier-first
|
||||||
|
release, device disconnect and cancellation, without live input/audio access.
|
||||||
|
System activation and an interactive hold/release trial remain user-owned.
|
||||||
|
Formatting, flake evaluation, both workstation builds, synthetic listener checks
|
||||||
|
and whitespace checking passed. No live input listener or microphone was started.
|
||||||
|
|
||||||
|
The focus is the broader environment, not further API/database polish. Candidate
|
||||||
|
areas remain places/ownership, navigation/interaction, human/agent collaboration,
|
||||||
|
and system operation/maintenance; these are discussion areas, not a work queue.
|
||||||
|
|
||||||
|
Herdr's configured keys are accepted: the user reports liking them in practice.
|
||||||
|
Niri workspace grouping stays informal while the user discovers what fits; Herdr
|
||||||
|
provides enough structure for now. No workspace rules or fixed layout are needed.
|
||||||
|
The user reopened Herdr configuration on 2026-09-10 for direct shortcuts and less
|
||||||
|
interaction friction, using supported configuration only. Layout presets and
|
||||||
|
launchers are explicitly unwanted; arrange panes manually. Agent evaluation is
|
||||||
|
explicitly deferred. Do not resume replacement-tool comparisons or ask for an
|
||||||
|
evaluation task/budget as a prerequisite for this work.
|
||||||
|
|
||||||
|
Read-only inspection found existing Niri overview, workspace movement and tabbed
|
||||||
|
columns; Kitty has no declared project/session organization. Installed versions:
|
||||||
|
Kitty 0.48.2, Niri 26.04, tmux 3.7c, Zellij 0.45.1 and Herdr 0.9.0.
|
||||||
|
Herdr's installed default config confirms remappable navigation and agent jumps.
|
||||||
|
Current [Herdr keyboard docs](https://herdr.dev/docs/keyboard/) describe direct
|
||||||
|
chords; [Kitty sessions](https://sw.kovidgoyal.net/kitty/sessions/) supply native
|
||||||
|
session creation/switching. Session layouts and window overviews do not themselves
|
||||||
|
provide authoritative agent attention states. tmux detach keeps processes alive;
|
||||||
|
Zellij resurrection recreates layouts/commands, not process memory. None of these
|
||||||
|
capabilities was exercised interactively; no sessions were inspected or changed.
|
||||||
|
|
||||||
|
Deferred agent workflow proposal (not accepted or a Niri workspace requirement):
|
||||||
|
one lead conversation owns each coherent change. Use bounded subagents when work
|
||||||
|
is independent, with explicit ownership and evidence returned to the lead. Separate
|
||||||
|
worktrees for independent writing efforts, one integration owner. Keep enduring
|
||||||
|
repository rules in AGENTS.md, current goals/acceptance in task prompts, and durable
|
||||||
|
decisions/current state in existing project docs. No fixed agent team is selected.
|
||||||
|
|
||||||
|
Herdr configuration is now declared in `modules/capabilities/ai.nix`, including
|
||||||
|
the existing Kanagawa theme, workspace-sorted agent panel and disabled toasts.
|
||||||
|
Home Manager owns `~/.config/herdr/config.toml` after activation; maintain these
|
||||||
|
preferences in Nix. Its configured `.bak` mechanism preserves the previous regular
|
||||||
|
file. Direct Ctrl+Alt bindings supplement the existing Ctrl+B prefix shortcuts:
|
||||||
|
|
||||||
|
| Ctrl+Alt + | Action |
|
||||||
|
| --- | --- |
|
||||||
|
| H / J / K / L | Focus pane left / down / up / right |
|
||||||
|
| U / I | Next / previous workspace |
|
||||||
|
| O / G | Workspace picker / goto picker |
|
||||||
|
| P / N | Previous / next agent |
|
||||||
|
| [ / ] | Previous / next tab |
|
||||||
|
| Enter | New tab |
|
||||||
|
| V / Minus | Split right / down |
|
||||||
|
| F | Zoom pane |
|
||||||
|
| Q | Detach, leaving the session running |
|
||||||
|
| Shift+H / J / K / L | Swap panes left / down / up / right (Shift on each) |
|
||||||
|
| Shift+arrows | Resize pane directly |
|
||||||
|
| R | Resize mode |
|
||||||
|
| Tab / Shift+Tab | Next / previous pane |
|
||||||
|
| Backspace | Return to last pane, including across tabs/spaces |
|
||||||
|
| X / Shift+X | Close pane / tab |
|
||||||
|
| Shift+P / Shift+A | Rename pane / tab |
|
||||||
|
| Shift+[ / Shift+] | Move tab earlier / later |
|
||||||
|
| Shift+Enter | New space |
|
||||||
|
| Shift+W / Shift+D | Rename / close space |
|
||||||
|
| W / Shift+B | Open / create worktree |
|
||||||
|
| Y / E | Copy mode / open scrollback in Neovim |
|
||||||
|
| Shift+G | Lazygit popup |
|
||||||
|
| B | Toggle sidebar |
|
||||||
|
| / | Keybinding help |
|
||||||
|
| S / Shift+R | Settings / reload configuration |
|
||||||
|
|
||||||
|
Inside workspace navigation, U/I moves down/up and H/J/K/L retains pane navigation.
|
||||||
|
Niri and Kitty bindings are unchanged. Direct number bindings are removed because
|
||||||
|
the user finds them unergonomic; built-in prefix shortcuts remain available.
|
||||||
|
|
||||||
|
Use one space per project or worktree, tabs for different activities, and panes
|
||||||
|
for tools needed together. Start Neovim in a shell, split right with Ctrl+Alt+V
|
||||||
|
for an agent shell, and optionally split that pane down with Ctrl+Alt+Minus for
|
||||||
|
tests or a server. Choose and launch the agent manually. No preset is installed.
|
||||||
|
Ctrl+Alt+Shift+G opens lazygit at 90% width/height in the focused pane's working
|
||||||
|
directory. Quit lazygit to return; the popup owns input until its command exits.
|
||||||
|
|
||||||
|
Tabs now open immediately with generated names; rename them only when useful.
|
||||||
|
New spaces already skip naming, and new panes inherit the current directory by
|
||||||
|
default. Workspace-close confirmation remains enabled to protect running work.
|
||||||
|
Direct resizing, previous/next agent navigation, last-pane switching, copy mode,
|
||||||
|
and Neovim scrollback access avoid extra navigation or mode-entry steps.
|
||||||
|
No documented native setting or CLI action opens Goto directly in search mode;
|
||||||
|
that limitation remains under the configuration-only constraint. No input macros,
|
||||||
|
plugins, or package patches are added.
|
||||||
|
|
||||||
|
After activating Nix, reload Herdr with Ctrl+B then Shift+R; subsequent reloads
|
||||||
|
can use Ctrl+Alt+Shift+R. The expanded shortcuts require interactive verification
|
||||||
|
through Kitty, including popup working directory, pane swapping/resizing, and
|
||||||
|
scrollback opening. The earlier bindings were reported working by the user.
|
||||||
|
Verification (2026-09-10): formatting, flake evaluation, Polaris and Zenith no-link
|
||||||
|
system builds, and whitespace checks passed. Both hosts generate identical Herdr
|
||||||
|
TOML, accepted by installed Herdr 0.9.0's `config check`. No activation or live
|
||||||
|
Herdr session changes were performed.
|
||||||
|
The earlier activation installed the Herdr config and preserved `config.toml.bak`,
|
||||||
|
but Home Manager later timed out (below).
|
||||||
|
|
||||||
|
Activation fix (2026-09-09): Home Manager's service switch stopped and restarted
|
||||||
|
the running SharePoint oneshot, then waited until Home Manager's five-minute start
|
||||||
|
timeout. Service-state inspection identified SharePoint as the sole pending user
|
||||||
|
job; its oneshot start timeout is unlimited. This was not a Herdr file collision.
|
||||||
|
Set `Unit.X-SwitchMethod = "keep-old"` in `sharepoint-reference.nix` so activation
|
||||||
|
leaves an in-flight sync running; subsequent timer runs use the updated unit.
|
||||||
|
Verified against pinned Home Manager/sd-switch source. Formatting, flake evaluation,
|
||||||
|
Zenith build and whitespace checks passed; the focused sd-switch dry run reported
|
||||||
|
`Keep active sharepoint-reference-sync.service`, with no restart planned. No live
|
||||||
|
units were changed and no company content or credentials were read. The user must
|
||||||
|
retry activation to verify the full switch; sync health/content completeness were
|
||||||
|
not investigated.
|
||||||
|
|
||||||
|
Mail search remains unresolved. The workbench's custom mail reader, inventory
|
||||||
|
pilot, justfile and old README are archived; native Garden/kubectl/K9s now own the
|
||||||
|
documented operations. No replacement mail helper or semantic index is selected;
|
||||||
|
raw mailbox grep is not assumed sufficient. No new ingestion is authorized.
|
||||||
|
|
||||||
|
Human credential delivery remains both test/live via environment variables with
|
||||||
|
ordinary editor startup. Workbench `.envrc` supplies aggregate credentials; agents
|
||||||
|
must not source it. Separate read-only agent credentials and access isolation are
|
||||||
|
explicitly deferred, not prerequisites for unrelated work. Do not resume the
|
||||||
|
rejected per-connection launchers or per-selection decryption proposal.
|
||||||
|
|
||||||
|
Notes placement and further company material organization remain open. Work is
|
||||||
|
mostly project-based and notes mostly meetings; do not impose investigation
|
||||||
|
folders, outer project containers or company-wide editor search without a need.
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# Constellation
|
||||||
|
|
||||||
|
An evolving personal computing environment. This is the current design, starting
|
||||||
|
fresh with iteration two; decisions can change through discussion and use.
|
||||||
|
See [working state](constellation-work.md) for how we collaborate and where to resume.
|
||||||
|
|
||||||
|
## Philosophy
|
||||||
|
|
||||||
|
Build a quiet, keyboard-driven, text-oriented environment from understandable
|
||||||
|
tools that compose naturally. Keep information accessible through standard formats
|
||||||
|
and interfaces, so humans and agents can work with the same underlying resources.
|
||||||
|
Organize files and workflows consistently, making it intuitive where to look,
|
||||||
|
where things belong and how to proceed. Let structure guide everyday work while
|
||||||
|
leaving room for exploration and exceptions. Use graphical applications where
|
||||||
|
they serve the task well.
|
||||||
|
|
||||||
|
Make the usual path obvious and exceptions understandable. Consistency should
|
||||||
|
reduce remembering and decision-making without requiring identical bindings or
|
||||||
|
fixed procedures everywhere. A terminal interface alone does not establish fit.
|
||||||
|
|
||||||
|
Nix configures installed tools and system integration. Working directories,
|
||||||
|
checkouts, workspace `.envrc` files and context documents are ordinary user-owned
|
||||||
|
files, maintained directly rather than generated by Home Manager. A workbench may
|
||||||
|
use a flake to declare its tools without Nix owning the surrounding workspace.
|
||||||
|
|
||||||
|
## What that means so far
|
||||||
|
|
||||||
|
- Themes are complete Nix modules, not just palettes. Select one through
|
||||||
|
`modules/capabilities/theme.nix`; it may install native theme plugins, configure
|
||||||
|
their behavior and choose assets for each application. Kanagawa is the first
|
||||||
|
implementation. Shared interaction/layout choices stay in capability modules.
|
||||||
|
Stylix is not selected: preserving theme-specific behavior matters more than
|
||||||
|
forcing applications through one generated color scheme.
|
||||||
|
- Neovim, Niri, Walker and the terminal feel right: direct, keyboard-driven
|
||||||
|
interaction with useful connections to the rest of the environment.
|
||||||
|
- Use Handy for local plain dictation, mainly English with occasional Dutch.
|
||||||
|
Use native Wayland automatic paste and optional live text with a streaming model.
|
||||||
|
Handy owns its preferences, models and recordings. Nix installs and starts it
|
||||||
|
and supplies desktop shortcuts, including a short-lived push-to-talk listener. Cleanup
|
||||||
|
through Codex, a cloud API or a local language model is deferred.
|
||||||
|
- Outlook is acceptable as an application, but its interaction and integration
|
||||||
|
do not fit as naturally. Accessible mail for tools and agents matters separately
|
||||||
|
from choosing a mail reader. Preserve meaning and source context, not just text.
|
||||||
|
- Herdr is the chosen agent workspace manager: its spaces, running-agent overview
|
||||||
|
and attention states fit. Its configured keybindings are accepted in daily use.
|
||||||
|
Use Ctrl+Alt for direct Herdr actions alongside Super for Niri and Ctrl navigation
|
||||||
|
in Neovim; retain Herdr's prefix bindings. Agent-deck's startup issues and other
|
||||||
|
session-manager alternatives are not the current focus.
|
||||||
|
- Keep Niri workspaces flexible. Herdr supplies enough structure that no strict
|
||||||
|
desktop grouping, fixed workspace names or project-to-workspace mapping is
|
||||||
|
needed now. Let actual use inform any later organization.
|
||||||
|
- Further Herdr configuration, agent workflows and project management are deferred
|
||||||
|
until the user chooses to revisit them. Existing configuration remains in use.
|
||||||
|
Alignment, maintainability and human attention matter
|
||||||
|
alongside speed/cost. Agent-workflow evaluation is deferred; no fixed delegation
|
||||||
|
pattern has been selected.
|
||||||
|
- Repositories should contain code and documentation needed by that code, not
|
||||||
|
become containers for general notes and company material destined for Git remotes.
|
||||||
|
- Company work includes repositories, reference material, notes, credentials and
|
||||||
|
investigation tools. Its organization must accommodate those different roles.
|
||||||
|
- Actual work is mostly project-based; notes are primarily meeting notes so far.
|
||||||
|
Do not impose a topic/investigation workflow or a fixed future note taxonomy.
|
||||||
|
- Yookr workbench is an investigation environment, not a product repository.
|
||||||
|
Its placement and versioning can be considered separately.
|
||||||
|
- Accepted direction: workbench supplies the environment at the company-workspace
|
||||||
|
root. Its reusable requests live in `workbench/http/` and queries in
|
||||||
|
`workbench/databases/`, grouped by service/database;
|
||||||
|
the company root need not itself be a Git repository.
|
||||||
|
- Expose native capabilities and useful context rather than a menu of predetermined
|
||||||
|
investigations. The custom inventory and mail helpers are archived; native
|
||||||
|
Garden/kubectl/K9s own the documented Kubernetes workflow. Mail retrieval and
|
||||||
|
broader system access remain exploratory.
|
||||||
|
- Accepted interaction direction: find HTTP requests by service; start database
|
||||||
|
exploration from a named connection. Keep targets visible and use the existing
|
||||||
|
execution vocabulary. Working queries should survive restart without automatically
|
||||||
|
becoming reusable tracked material. Company-wide Neovim search is deferred: no
|
||||||
|
concrete use case currently justifies adding it.
|
||||||
|
- Human credential delivery uses environment variables with both test and live
|
||||||
|
credentials available. Keep ordinary editor startup; no per-connection launcher
|
||||||
|
or on-demand decryption workflow. Agent authority is a separate concern.
|
||||||
|
- Separate read-only company credentials for agents are the eventual direction.
|
||||||
|
Access isolation is explicitly deferred: new credentials cannot be made now.
|
||||||
|
Existing agent access boundaries remain in force; this does not block unrelated
|
||||||
|
design and organization work.
|
||||||
|
|
||||||
|
The company root is `~/yookr`, with repositories in `~/yookr/projects` and the
|
||||||
|
cross-project workbench in `~/yookr/workbench`. Personal/non-company repositories
|
||||||
|
live under `~/projects/{own,ext,forks}`. Projects currently mostly live in their
|
||||||
|
repositories; no extra project containers are needed. Meeting notes remain in
|
||||||
|
`~/sync/notes`. Remaining layout and credential locations are still being explored.
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
`~/sync/notes/setup-todo.md` is the idea inbox, not a committed backlog.
|
||||||
|
Existing implementation is the starting system, not a fixed future architecture.
|
||||||
|
Documents under [.archive/](.archive/) are historical evidence; consult only the
|
||||||
|
relevant parts when needed. Their plans, priorities and old approvals do not define
|
||||||
|
this iteration. Preserve existing work while reconsidering its design.
|
||||||
Generated
+69
-178
@@ -20,15 +20,16 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784665499,
|
"lastModified": 1788011267,
|
||||||
"narHash": "sha256-9BMxlTxCCDAeoNLtb1a/st7udtTIJep+wpUzquA29VU=",
|
"narHash": "sha256-mEq2kU+ljompTToZ44Afvm7d/rHJ5iMBl0tjZuyShJs=",
|
||||||
"owner": "nix-community",
|
"owner": "Mic92",
|
||||||
"repo": "bun2nix",
|
"repo": "bun2nix",
|
||||||
"rev": "0f2a1f0b6f42cebe3b149bf62d38754c5e0e9729",
|
"rev": "5765b0614591f75ee8ba5596e81ae85c167d1071",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"owner": "Mic92",
|
||||||
|
"ref": "fix-structured-attrs-hook",
|
||||||
"repo": "bun2nix",
|
"repo": "bun2nix",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -56,16 +57,20 @@
|
|||||||
"elephant": {
|
"elephant": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
"walker",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems"
|
"systems": [
|
||||||
|
"walker",
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784365424,
|
"lastModified": 1775706155,
|
||||||
"narHash": "sha256-kJO1Tww/GkvLq5amrV4BKidYGr5YumM+cH/xYALAiw4=",
|
"narHash": "sha256-h7Rw0vlb0n0Jsk21WJPm7H+1T1bG+PEuxE5cJ2TZl8A=",
|
||||||
"owner": "abenz1267",
|
"owner": "abenz1267",
|
||||||
"repo": "elephant",
|
"repo": "elephant",
|
||||||
"rev": "23f37238367355cf46843015ad5e94706200176a",
|
"rev": "376ee71c66db38683daabd57350bf3f6f086eaf8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -79,11 +84,11 @@
|
|||||||
"nixpkgs-lib": "nixpkgs-lib"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787559586,
|
"lastModified": 1788450739,
|
||||||
"narHash": "sha256-onL0VLf9vPllmT0H/OlURIU5r5t5WIEl7t4tVNKT0Nw=",
|
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "9d0d87172c374f89da73c1cfe6d81ae62feac1f1",
|
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -100,11 +105,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785627969,
|
"lastModified": 1788450739,
|
||||||
"narHash": "sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw=",
|
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "427bf4bd9435fdf21321c8cc628c24efc14c0f7a",
|
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -113,25 +118,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"helix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"rust-overlay": "rust-overlay"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1784822617,
|
|
||||||
"narHash": "sha256-IYDL6Vnf13Sa+wbeXZTAxvdLA4h8Ew5ha0spcJy/Yk0=",
|
|
||||||
"owner": "helix-editor",
|
|
||||||
"repo": "helix",
|
|
||||||
"rev": "079a789e8cb08ead67f19e1971a1b7438b37354b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "helix-editor",
|
|
||||||
"repo": "helix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -139,11 +125,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787540599,
|
"lastModified": 1788651960,
|
||||||
"narHash": "sha256-MHwk52ty3NsLhq9a1IbIfBJZlCUJIdiUYFo52JLK9hY=",
|
"narHash": "sha256-v9wJd32eZ2bvhBzVOd7TIjLQd011P7nwOhjKtWlci5I=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "03f4cd46bc1dd4f3a96da778d2ce9f7ce39dd450",
|
"rev": "2c0350c759688177331b8f5242311fae8877bdb3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -154,11 +140,11 @@
|
|||||||
},
|
},
|
||||||
"import-tree": {
|
"import-tree": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784254960,
|
"lastModified": 1788467110,
|
||||||
"narHash": "sha256-iI88R3wHz8wTKQb5orvpc51L/Xr64AJyxid/0MKa/b8=",
|
"narHash": "sha256-ljEMTXP/rH0tOvDzc9gzwww6KcHRPRnEHzd9lK48V7s=",
|
||||||
"owner": "vic",
|
"owner": "vic",
|
||||||
"repo": "import-tree",
|
"repo": "import-tree",
|
||||||
"rev": "4ebb10ae17d5f1ad366e7aef5b92cb8eecf24f69",
|
"rev": "eb1b52eaecc57f7c136d07ae8a93e724dfecac46",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -174,15 +160,15 @@
|
|||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems_2",
|
"systems": "systems",
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787551962,
|
"lastModified": 1788858717,
|
||||||
"narHash": "sha256-zfumhlJTGDKSILebSBa8nTKG76ByIPlLkGPAKjxaiwE=",
|
"narHash": "sha256-lNh6z7qJ35S8msz4kH3xNxXTN7PLENpesL5LatpNBGA=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "llm-agents.nix",
|
"repo": "llm-agents.nix",
|
||||||
"rev": "46e6a013fd49779cd2def2c98fa447f197da3fe7",
|
"rev": "30e001e67438ab6ba024fa8d4f2e9be0ba7548af",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -198,11 +184,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787457452,
|
"lastModified": 1788680125,
|
||||||
"narHash": "sha256-FJh4esFS3zqNNuKwvN3t6wrJGewqp1AUF9DAEvoKPD8=",
|
"narHash": "sha256-amGSoDobwmp4CFvCn841ws2iuitus+HUJdD/gKgsrJA=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix-index-database",
|
"repo": "nix-index-database",
|
||||||
"rev": "c51d5c2ba69c907a34e90c9b6b80cd2b93811745",
|
"rev": "116ad1c2adb642405ef8916f6a94c8626f971344",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -218,11 +204,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787579952,
|
"lastModified": 1788744583,
|
||||||
"narHash": "sha256-Dn6IPaLyltx8hBTyC4hgNWDb7T7WHRYUG6wWh6KBHXA=",
|
"narHash": "sha256-oNMrijfyaoRjjWhxHNFSBYyEB4u/zb/AxoKewC56LvE=",
|
||||||
"owner": "BirdeeHub",
|
"owner": "BirdeeHub",
|
||||||
"repo": "nix-wrapper-modules",
|
"repo": "nix-wrapper-modules",
|
||||||
"rev": "b56e973dd2bd62244b44d6542fb52182bc3a3cda",
|
"rev": "e88c449105c6aafa460196d3cbd16718655aee0f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -233,14 +219,16 @@
|
|||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787144466,
|
"lastModified": 1788860136,
|
||||||
"narHash": "sha256-HHfv2/HkNSKbbSyU9iD/g8lbP6r4tl33sSw1W4rXCk0=",
|
"narHash": "sha256-MhPMOFV4pVkygWEbQ8t1De/uQ9cWF1u++tRe2L5tG48=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "0471accf8d0a8210b31d947497d179ecc99e0021",
|
"rev": "62173785b9a18c78b4a15aca2623d02bceb9d077",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -252,100 +240,44 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775036866,
|
"lastModified": 1788834054,
|
||||||
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=",
|
"narHash": "sha256-kkWAS4mE+fmi+u3mxwD9/bfX6DGJ49Tv8O9kzN5r0HQ=",
|
||||||
"owner": "nixos",
|
"rev": "e9b9cbecbf6c25ca26c150d78570e6332694a129",
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "6201e203d09599479a3b3450ed24fa81537ebc4e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-lib": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1785031560,
|
|
||||||
"narHash": "sha256-OmshNvn2vupOFpYinLUu+1Dnpu4n7Q5N3ggGVNHpkUI=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nixpkgs.lib",
|
|
||||||
"rev": "0e79af5e3d4dcfcd676ab5ba3f95d2e3352e078c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nixpkgs.lib",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-stable": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1787414105,
|
|
||||||
"narHash": "sha256-WncT27+3BOkgTaJZLnCsf3LcYf9RXMuR9ONSN4rzQ7s=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a9e6d84f9c2f9012f5fe7d964a7851352300e61a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-26.05",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1767892417,
|
|
||||||
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
|
|
||||||
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
|
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
|
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1069601.e9b9cbecbf6c/nixexprs.tar.xz"
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1787394516,
|
|
||||||
"narHash": "sha256-wS+SNrj0wobAXQONggzrpetnZ9E0FL7l0WVWDRQ77Sc=",
|
|
||||||
"rev": "c8f90650c15282fa8656a041bfbbd2403997a9a7",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1059707.c8f90650c152/nixexprs.tar.xz"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"
|
"url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787360063,
|
"lastModified": 1788057806,
|
||||||
"narHash": "sha256-95aJfHyQTLWslCXFVNB0odgmVkpdmDezQwTg9mhqV1E=",
|
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
|
||||||
"rev": "2c423e03bbafcff28bfadc6781a4a8257f205cb5",
|
"owner": "nix-community",
|
||||||
"type": "tarball",
|
"repo": "nixpkgs.lib",
|
||||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1059570.2c423e03bbaf/nixexprs.tar.zst"
|
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
|
||||||
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"owner": "nix-community",
|
||||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.zst"
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"noctalia": {
|
"noctalia": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_4"
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787575682,
|
"lastModified": 1788886125,
|
||||||
"narHash": "sha256-qSjBgNe40+DxiMV+obDrJ+WCI/zynUbOtcXQDAXv5Fk=",
|
"narHash": "sha256-5rgQFUGr8GXYyyuy8ynrN39WfZzSiO/wqGWjELBOkEY=",
|
||||||
"owner": "noctalia-dev",
|
"owner": "noctalia-dev",
|
||||||
"repo": "noctalia",
|
"repo": "noctalia",
|
||||||
"rev": "0f61b0ae07607739189d07a0a7617ef0d8f3796c",
|
"rev": "d6607b4eafbb92f6d494ebed3e296d4b741c0b58",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -357,43 +289,19 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"elephant": "elephant",
|
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"helix": "helix",
|
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"import-tree": "import-tree",
|
"import-tree": "import-tree",
|
||||||
"llm-agents": "llm-agents",
|
"llm-agents": "llm-agents",
|
||||||
"nix-index-database": "nix-index-database",
|
"nix-index-database": "nix-index-database",
|
||||||
"nix-wrapper-modules": "nix-wrapper-modules",
|
"nix-wrapper-modules": "nix-wrapper-modules",
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
"nixpkgs": "nixpkgs_3",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-stable": "nixpkgs-stable",
|
|
||||||
"noctalia": "noctalia",
|
"noctalia": "noctalia",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"walker": "walker"
|
"walker": "walker"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rust-overlay": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"helix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1775358767,
|
|
||||||
"narHash": "sha256-f2eC+WIfhjevCPQILuV08i/kmKZzYZpUvkom/33VxCA=",
|
|
||||||
"owner": "oxalica",
|
|
||||||
"repo": "rust-overlay",
|
|
||||||
"rev": "20fd44bc663daa53a2575e01293e24e681d62244",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "oxalica",
|
|
||||||
"repo": "rust-overlay",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sops-nix": {
|
"sops-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -401,11 +309,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786629091,
|
"lastModified": 1788337237,
|
||||||
"narHash": "sha256-gkig4nPi1CWc4Z50GBsjE4ygSE7hMpl/TwID2an2Cck=",
|
"narHash": "sha256-gkSH8VUtCo6hnysNmb9DbTuDepH2t5pv+QWjP75xKAk=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "a8627b21b9107c5711c96b84f32a9a4b3d45295f",
|
"rev": "fbf759290e0cb0a98dfc813a4eb7d53ad1dacb57",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -415,21 +323,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
|
||||||
"lastModified": 1689347949,
|
|
||||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default-linux",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_2": {
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
@@ -444,7 +337,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems_3": {
|
"systems_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1689347949,
|
"lastModified": 1689347949,
|
||||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||||
@@ -482,13 +375,11 @@
|
|||||||
},
|
},
|
||||||
"walker": {
|
"walker": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"elephant": [
|
"elephant": "elephant",
|
||||||
"elephant"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems_3"
|
"systems": "systems_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784217994,
|
"lastModified": 1784217994,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
helix.url = "github:helix-editor/helix";
|
|
||||||
home-manager = {
|
home-manager = {
|
||||||
url = "github:nix-community/home-manager";
|
url = "github:nix-community/home-manager";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@@ -21,10 +20,15 @@
|
|||||||
url = "github:BirdeeHub/nix-wrapper-modules";
|
url = "github:BirdeeHub/nix-wrapper-modules";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
nixos-hardware = {
|
||||||
|
url = "github:NixOS/nixos-hardware/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
|
nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
|
||||||
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-26.05";
|
noctalia = {
|
||||||
noctalia.url = "github:noctalia-dev/noctalia";
|
url = "github:noctalia-dev/noctalia";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
sops-nix = {
|
sops-nix = {
|
||||||
url = "github:Mic92/sops-nix";
|
url = "github:Mic92/sops-nix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@@ -34,13 +38,8 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
elephant = {
|
|
||||||
url = "github:abenz1267/elephant";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
walker = {
|
walker = {
|
||||||
url = "github:abenz1267/walker";
|
url = "github:abenz1267/walker";
|
||||||
inputs.elephant.follows = "elephant";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
File renamed without changes.
@@ -0,0 +1,277 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
palette = (import ./_kanagawa-palette.nix).palette;
|
||||||
|
hex = lib.removePrefix "#";
|
||||||
|
cursor = {
|
||||||
|
name = "phinger-cursors-light";
|
||||||
|
size = 24;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
flake.modules.nixos.theme =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home-manager.sharedModules = [ config.flake.modules.homeManager.theme ];
|
||||||
|
environment.systemPackages = [ pkgs.phinger-cursors ];
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.theme =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
version = "unstable-2025-10-23";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "Fausto-Korpsvart";
|
||||||
|
repo = "Kanagawa-GKT-Theme";
|
||||||
|
rev = "55ca4ba249eba21f861b9866b71ab41bb8930318";
|
||||||
|
hash = "sha256-UdMoMx2DoovcxSp/zBZ3PRv/Qpj+prd0uPm1gmdak2E=";
|
||||||
|
};
|
||||||
|
kanagawaGtkTheme = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
pname = "kanagawa-gtk-theme";
|
||||||
|
inherit src version;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ pkgs.sassc ];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p "$out/share/themes"
|
||||||
|
bash ./themes/install.sh \
|
||||||
|
--dest "$out/share/themes" \
|
||||||
|
--name Kanagawa \
|
||||||
|
--color dark
|
||||||
|
|
||||||
|
rm -r "$out/share/themes/Kanagawa-Dark/gtk-2.0"
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.pointerCursor = cursor // {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.phinger-cursors;
|
||||||
|
dotIcons.enable = false;
|
||||||
|
gtk.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
theme = {
|
||||||
|
name = "Kanagawa-Dark";
|
||||||
|
package = kanagawaGtkTheme;
|
||||||
|
};
|
||||||
|
gtk4.theme = null;
|
||||||
|
iconTheme = {
|
||||||
|
name = "Kanagawa";
|
||||||
|
package = pkgs.kanagawa-icon-theme.overrideAttrs (_: {
|
||||||
|
inherit src version;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
qt = {
|
||||||
|
enable = true;
|
||||||
|
platformTheme.name = "gtk3";
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.systemDirs.data = [
|
||||||
|
"${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}"
|
||||||
|
"${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.nixos.limine =
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
let
|
||||||
|
terminalPalette = palette.terminal;
|
||||||
|
mkPalette = colors: lib.concatStringsSep ";" (map hex colors);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
boot.loader.limine.style = {
|
||||||
|
wallpapers = [ pkgs.nixos-artwork.wallpapers.simple-dark-gray-bootloader.gnomeFilePath ];
|
||||||
|
wallpaperStyle = "stretched";
|
||||||
|
backdrop = hex palette.secondaryBackground;
|
||||||
|
|
||||||
|
graphicalTerminal = {
|
||||||
|
# TT is transparency: let the boot wallpaper show through the terminal.
|
||||||
|
background = "FF${hex palette.background}";
|
||||||
|
foreground = hex palette.foreground;
|
||||||
|
brightForeground = hex palette.selectionForeground;
|
||||||
|
brightBackground = hex palette.selectionBackground;
|
||||||
|
palette = mkPalette [
|
||||||
|
terminalPalette.color0
|
||||||
|
terminalPalette.color1
|
||||||
|
terminalPalette.color2
|
||||||
|
terminalPalette.color3
|
||||||
|
terminalPalette.color4
|
||||||
|
terminalPalette.color5
|
||||||
|
terminalPalette.color6
|
||||||
|
terminalPalette.color7
|
||||||
|
];
|
||||||
|
brightPalette = mkPalette [
|
||||||
|
terminalPalette.color8
|
||||||
|
terminalPalette.color9
|
||||||
|
terminalPalette.color10
|
||||||
|
terminalPalette.color11
|
||||||
|
terminalPalette.color12
|
||||||
|
terminalPalette.color13
|
||||||
|
terminalPalette.color14
|
||||||
|
terminalPalette.color15
|
||||||
|
];
|
||||||
|
font = {
|
||||||
|
scale = "2x2";
|
||||||
|
spacing = 1;
|
||||||
|
};
|
||||||
|
margin = 64;
|
||||||
|
marginGradient = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface = {
|
||||||
|
branding = config.networking.hostName;
|
||||||
|
brandingColor = hex palette.accents.blue;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.nixos.sddm = { pkgs, ... }: {
|
||||||
|
services.displayManager.sddm = {
|
||||||
|
theme = "${
|
||||||
|
pkgs.sddm-astronaut.override { embeddedTheme = "purple_leaves"; }
|
||||||
|
}/share/sddm/themes/sddm-astronaut-theme";
|
||||||
|
extraPackages = [ pkgs.kdePackages.qtmultimedia ];
|
||||||
|
settings.Theme = {
|
||||||
|
CursorTheme = cursor.name;
|
||||||
|
CursorSize = cursor.size;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.nixos.plymouth = { pkgs, ... }: {
|
||||||
|
boot.plymouth = {
|
||||||
|
theme = "spinner_alt";
|
||||||
|
themePackages = [ pkgs.adi1090x-plymouth-themes ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.terminal-kitty = {
|
||||||
|
programs.kitty = {
|
||||||
|
settings = {
|
||||||
|
bold_font = "postscript_name=JetBrainsMono-Bold";
|
||||||
|
bold_italic_font = "postscript_name=JetBrainsMono-BoldItalic";
|
||||||
|
};
|
||||||
|
font = {
|
||||||
|
name = "JetBrains Mono";
|
||||||
|
size = 11;
|
||||||
|
};
|
||||||
|
extraConfig = ''
|
||||||
|
# Nerd Fonts v3.4.0
|
||||||
|
symbol_map U+e000-U+e00a,U+e0a0-U+e0a2,U+e0a3,U+e0b0-U+e0b3,U+e0b4-U+e0c8,U+e0ca,U+e0cc-U+e0d7,U+e200-U+e2a9,U+e300-U+e3e3,U+e5fa-U+e6b7,U+e700-U+e8ef,U+ea60-U+ec1e,U+ed00-U+efce,U+f000-U+f2ff,U+f300-U+f381,U+f400-U+f533,U+f0001-U+f1af0 Symbols Nerd Font Mono
|
||||||
|
|
||||||
|
## name: Kanagawa Wave
|
||||||
|
## license: MIT
|
||||||
|
## author: Tommaso Laurenzi
|
||||||
|
## upstream: https://github.com/rebelot/kanagawa.nvim/
|
||||||
|
|
||||||
|
background ${palette.background}
|
||||||
|
foreground ${palette.foreground}
|
||||||
|
selection_background ${palette.selectionBackground}
|
||||||
|
selection_foreground ${palette.selectionForeground}
|
||||||
|
url_color ${palette.url}
|
||||||
|
cursor ${palette.cursor}
|
||||||
|
|
||||||
|
active_tab_background ${palette.background}
|
||||||
|
active_tab_foreground ${palette.selectionForeground}
|
||||||
|
inactive_tab_background ${palette.background}
|
||||||
|
inactive_tab_foreground ${palette.muted}
|
||||||
|
|
||||||
|
color0 ${palette.terminal.color0}
|
||||||
|
color1 ${palette.terminal.color1}
|
||||||
|
color2 ${palette.terminal.color2}
|
||||||
|
color3 ${palette.terminal.color3}
|
||||||
|
color4 ${palette.terminal.color4}
|
||||||
|
color5 ${palette.terminal.color5}
|
||||||
|
color6 ${palette.terminal.color6}
|
||||||
|
color7 ${palette.terminal.color7}
|
||||||
|
|
||||||
|
color8 ${palette.terminal.color8}
|
||||||
|
color9 ${palette.terminal.color9}
|
||||||
|
color10 ${palette.terminal.color10}
|
||||||
|
color11 ${palette.terminal.color11}
|
||||||
|
color12 ${palette.terminal.color12}
|
||||||
|
color13 ${palette.terminal.color13}
|
||||||
|
color14 ${palette.terminal.color14}
|
||||||
|
color15 ${palette.terminal.color15}
|
||||||
|
|
||||||
|
color16 ${palette.terminal.color16}
|
||||||
|
color17 ${palette.terminal.color17}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.niri = {
|
||||||
|
dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
|
||||||
|
wayland.windowManager.niri.settings.layout.border = {
|
||||||
|
active-color = palette.accents.blue;
|
||||||
|
inactive-color = palette.subtleBorder;
|
||||||
|
urgent-color = palette.accents.red;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.ai = {
|
||||||
|
xdg.configFile."herdr/config.toml".text = lib.mkAfter ''
|
||||||
|
[theme]
|
||||||
|
name = "kanagawa"
|
||||||
|
auto_switch = false
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.noctalia =
|
||||||
|
{ config, ... }:
|
||||||
|
let
|
||||||
|
wallpaper = "${config.home.homeDirectory}/media/images/wallpapers/green-leaves.png";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.noctalia.settings = {
|
||||||
|
shell.font_family = "Lexend";
|
||||||
|
theme = {
|
||||||
|
builtin = "Kanagawa";
|
||||||
|
community_palette = "Kanagawa Paper";
|
||||||
|
wallpaper_scheme = "m3-content";
|
||||||
|
};
|
||||||
|
wallpaper = {
|
||||||
|
default.path = wallpaper;
|
||||||
|
last.path = wallpaper;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.neovim = { pkgs, ... }: {
|
||||||
|
wrappers.neovim.specs.theme = {
|
||||||
|
data = pkgs.vimPlugins.kanagawa-nvim;
|
||||||
|
before = [ "INIT_MAIN" ];
|
||||||
|
config = ''
|
||||||
|
require("kanagawa").setup({
|
||||||
|
dimInactive = true,
|
||||||
|
colors = {
|
||||||
|
theme = {
|
||||||
|
all = {
|
||||||
|
ui = { bg_gutter = "none" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
vim.cmd.colorscheme("kanagawa-wave")
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.walker = {
|
||||||
|
programs.walker.themes.constellation.style = lib.mkAfter ''
|
||||||
|
@define-color window_bg_color ${palette.background};
|
||||||
|
@define-color accent_bg_color ${palette.selectionBackground};
|
||||||
|
@define-color theme_fg_color ${palette.foreground};
|
||||||
|
@define-color error_bg_color ${palette.terminal.color1};
|
||||||
|
@define-color error_fg_color ${palette.foreground};
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -92,8 +92,9 @@ process_recording() (
|
|||||||
local transcript_dir=$3
|
local transcript_dir=$3
|
||||||
local archive_dir=$4
|
local archive_dir=$4
|
||||||
local failed_dir=$5
|
local failed_dir=$5
|
||||||
local base stem transcript archive original_path recorded_at transcribed_at
|
local base stem transcript archive original_path recorded_at transcribed_at duration
|
||||||
local work_dir log_file raw_output rendered_output draft state_file recovery_status
|
local work_dir log_file raw_output rendered_output draft state_file recovery_status
|
||||||
|
local diarization_succeeded=false
|
||||||
|
|
||||||
base=$(basename "$source")
|
base=$(basename "$source")
|
||||||
stem=${base%.*}
|
stem=${base%.*}
|
||||||
@@ -129,6 +130,20 @@ process_recording() (
|
|||||||
raw_output="$work_dir/transcript"
|
raw_output="$work_dir/transcript"
|
||||||
rendered_output="$work_dir/transcript.md"
|
rendered_output="$work_dir/transcript.md"
|
||||||
|
|
||||||
|
if ! duration=$(ffprobe \
|
||||||
|
-v error \
|
||||||
|
-show_entries format=duration \
|
||||||
|
-of default=noprint_wrappers=1:nokey=1 \
|
||||||
|
"$source" 2>"$log_file"); then
|
||||||
|
fail_recording "$source" "$failed_dir" "Media validation failed" "$log_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [[ ! $duration =~ ^[0-9]+([.][0-9]+)?$ || -z ${duration//[.0]/} ]]; then
|
||||||
|
printf 'Invalid media duration: %s\n' "$duration" >"$log_file"
|
||||||
|
fail_recording "$source" "$failed_dir" "Media validation failed" "$log_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
if ! ffmpeg \
|
if ! ffmpeg \
|
||||||
-nostdin \
|
-nostdin \
|
||||||
-hide_banner \
|
-hide_banner \
|
||||||
@@ -148,18 +163,24 @@ process_recording() (
|
|||||||
--file "$work_dir/audio.wav" \
|
--file "$work_dir/audio.wav" \
|
||||||
--language auto \
|
--language auto \
|
||||||
--output-json-full \
|
--output-json-full \
|
||||||
--output-file "$raw_output" >>"$log_file" 2>&1 || [[ ! -s "${raw_output}.json" ]]; then
|
--output-txt \
|
||||||
|
--output-file "$raw_output" >>"$log_file" 2>&1 \
|
||||||
|
|| [[ ! -s "${raw_output}.json" || ! -s "${raw_output}.txt" ]]; then
|
||||||
fail_recording "$source" "$failed_dir" "Whisper transcription failed" "$log_file"
|
fail_recording "$source" "$failed_dir" "Whisper transcription failed" "$log_file"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! diarize-transcript \
|
if [[ -f "$TRANSCRIBE_DIARIZATION_MODEL/.complete" && -f "$TRANSCRIBE_DIARIZATION_MODEL/config.yaml" ]] \
|
||||||
--audio "$work_dir/audio.wav" \
|
&& diarize-transcript \
|
||||||
--model "$TRANSCRIBE_DIARIZATION_MODEL" \
|
--audio "$work_dir/audio.wav" \
|
||||||
--transcript "${raw_output}.json" \
|
--model "$TRANSCRIBE_DIARIZATION_MODEL" \
|
||||||
--output "$rendered_output" >>"$log_file" 2>&1 || [[ ! -s "$rendered_output" ]]; then
|
--transcript "${raw_output}.json" \
|
||||||
fail_recording "$source" "$failed_dir" "Speaker diarization failed" "$log_file"
|
--output "$rendered_output" >>"$log_file" 2>&1 \
|
||||||
return 1
|
&& [[ -s "$rendered_output" ]]; then
|
||||||
|
diarization_succeeded=true
|
||||||
|
else
|
||||||
|
printf 'Speaker diarization unavailable; publishing unlabeled transcript\n' >&2
|
||||||
|
cp -- "${raw_output}.txt" "$rendered_output"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
draft=$(mktemp "$transcript_dir/.transcript.XXXXXX")
|
draft=$(mktemp "$transcript_dir/.transcript.XXXXXX")
|
||||||
@@ -168,12 +189,17 @@ process_recording() (
|
|||||||
printf -- '- Original recording: %s\n' "$original_path"
|
printf -- '- Original recording: %s\n' "$original_path"
|
||||||
printf -- '- Recording timestamp: %s\n' "$recorded_at"
|
printf -- '- Recording timestamp: %s\n' "$recorded_at"
|
||||||
printf -- '- Transcription timestamp: %s\n' "$transcribed_at"
|
printf -- '- Transcription timestamp: %s\n' "$transcribed_at"
|
||||||
printf -- '- Engine: whisper.cpp %s (Vulkan)\n' "$TRANSCRIBE_ENGINE_VERSION"
|
printf -- '- Duration: %s seconds\n' "$duration"
|
||||||
|
printf -- '- Engine: whisper.cpp %s (%s)\n' "$TRANSCRIBE_ENGINE_VERSION" "$TRANSCRIBE_ENGINE_ACCELERATION"
|
||||||
printf -- '- Model: %s\n' "$TRANSCRIBE_MODEL_NAME"
|
printf -- '- Model: %s\n' "$TRANSCRIBE_MODEL_NAME"
|
||||||
printf -- '- Model SHA-256: %s\n' "$TRANSCRIBE_MODEL_SHA256"
|
printf -- '- Model SHA-256: %s\n' "$TRANSCRIBE_MODEL_SHA256"
|
||||||
printf -- '- Diarization engine: pyannote.audio %s (CPU)\n' "$TRANSCRIBE_DIARIZATION_ENGINE_VERSION"
|
if [[ $diarization_succeeded == true ]]; then
|
||||||
printf -- '- Diarization model: %s\n' "$TRANSCRIBE_DIARIZATION_MODEL_NAME"
|
printf -- '- Diarization engine: pyannote.audio %s (CPU)\n' "$TRANSCRIBE_DIARIZATION_ENGINE_VERSION"
|
||||||
printf -- '- Diarization model revision: %s\n\n' "$TRANSCRIBE_DIARIZATION_MODEL_REVISION"
|
printf -- '- Diarization model: %s\n' "$TRANSCRIBE_DIARIZATION_MODEL_NAME"
|
||||||
|
printf -- '- Diarization model revision: %s\n\n' "$TRANSCRIBE_DIARIZATION_MODEL_REVISION"
|
||||||
|
else
|
||||||
|
printf -- '- Diarization: unavailable; unlabeled fallback published\n\n'
|
||||||
|
fi
|
||||||
cat -- "$rendered_output"
|
cat -- "$rendered_output"
|
||||||
} >"$draft"
|
} >"$draft"
|
||||||
chmod 0644 "$draft"
|
chmod 0644 "$draft"
|
||||||
@@ -203,11 +229,10 @@ process_scope() {
|
|||||||
local processing_dir="$recordings_dir/processing"
|
local processing_dir="$recordings_dir/processing"
|
||||||
local archive_dir="$recordings_dir/archive"
|
local archive_dir="$recordings_dir/archive"
|
||||||
local failed_dir="$recordings_dir/failed"
|
local failed_dir="$recordings_dir/failed"
|
||||||
local source processing_target recording_status scope_status=0
|
local source processing_target recording_status signature index scope_status=0
|
||||||
|
local -a sources signatures
|
||||||
|
|
||||||
if ! mkdir -p "$inbox_dir" "$processing_dir" "$archive_dir" "$failed_dir" "$transcript_dir"; then
|
mkdir -p "$inbox_dir" "$processing_dir" "$archive_dir" "$failed_dir" "$transcript_dir" || return 1
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while IFS= read -r -d '' source; do
|
while IFS= read -r -d '' source; do
|
||||||
if is_recording "$source"; then
|
if is_recording "$source"; then
|
||||||
@@ -219,23 +244,42 @@ process_scope() {
|
|||||||
fi
|
fi
|
||||||
done < <(find "$processing_dir" -maxdepth 1 -type f -print0 | sort -z)
|
done < <(find "$processing_dir" -maxdepth 1 -type f -print0 | sort -z)
|
||||||
|
|
||||||
while IFS= read -r -d '' source; do
|
while true; do
|
||||||
if ! is_recording "$source"; then
|
sources=()
|
||||||
continue
|
signatures=()
|
||||||
|
|
||||||
|
while IFS= read -r -d '' source; do
|
||||||
|
if is_recording "$source" && signature=$(stat -c '%s:%y:%i' -- "$source"); then
|
||||||
|
sources+=("$source")
|
||||||
|
signatures+=("$signature")
|
||||||
|
fi
|
||||||
|
done < <(find "$inbox_dir" -maxdepth 1 -type f -print0 | sort -z)
|
||||||
|
|
||||||
|
if [[ ${#sources[@]} -eq 0 ]]; then
|
||||||
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
processing_target="$processing_dir/$(basename "$source")"
|
sleep "${TRANSCRIBE_SETTLE_SECONDS:-300}"
|
||||||
if ! move_no_clobber "$source" "$processing_target"; then
|
|
||||||
fail_recording "$source" "$failed_dir" "Processing filename already exists: $processing_target"
|
for index in "${!sources[@]}"; do
|
||||||
scope_status=1
|
source=${sources[$index]}
|
||||||
continue
|
if [[ ! -f "$source" ]] || [[ $(stat -c '%s:%y:%i' -- "$source") != "${signatures[$index]}" ]]; then
|
||||||
fi
|
continue
|
||||||
process_recording "$processing_target" "$inbox_dir" "$transcript_dir" "$archive_dir" "$failed_dir"
|
fi
|
||||||
recording_status=$?
|
|
||||||
if [[ $recording_status -ne 0 ]]; then
|
processing_target="$processing_dir/$(basename "$source")"
|
||||||
scope_status=1
|
if ! move_no_clobber "$source" "$processing_target"; then
|
||||||
fi
|
fail_recording "$source" "$failed_dir" "Processing filename already exists: $processing_target"
|
||||||
done < <(find "$inbox_dir" -maxdepth 1 -type f -print0 | sort -z)
|
scope_status=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
process_recording "$processing_target" "$inbox_dir" "$transcript_dir" "$archive_dir" "$failed_dir"
|
||||||
|
recording_status=$?
|
||||||
|
if [[ $recording_status -ne 0 ]]; then
|
||||||
|
scope_status=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
return "$scope_status"
|
return "$scope_status"
|
||||||
}
|
}
|
||||||
@@ -243,14 +287,5 @@ process_scope() {
|
|||||||
runtime_dir="${XDG_RUNTIME_DIR:?}/transcribe-recordings"
|
runtime_dir="${XDG_RUNTIME_DIR:?}/transcribe-recordings"
|
||||||
mkdir -p "$runtime_dir"
|
mkdir -p "$runtime_dir"
|
||||||
|
|
||||||
if [[ ! -f "$TRANSCRIBE_DIARIZATION_MODEL/.complete" || ! -f "$TRANSCRIBE_DIARIZATION_MODEL/config.yaml" ]]; then
|
|
||||||
printf 'Speaker diarization model is not installed; run prepare-transcription-diarization-model\n' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
set +o errexit
|
set +o errexit
|
||||||
process_scope "$TRANSCRIBE_SYNC_ROOT/recordings" "$TRANSCRIBE_SYNC_ROOT/notes/transcripts"
|
process_scope "$TRANSCRIBE_SYNC_ROOT/recordings" "$TRANSCRIBE_SYNC_ROOT/notes/transcripts"
|
||||||
personal_status=$?
|
|
||||||
process_scope "$TRANSCRIBE_SYNC_ROOT/work/recordings" "$TRANSCRIBE_SYNC_ROOT/work/notes/transcripts"
|
|
||||||
work_status=$?
|
|
||||||
exit "$((personal_status != 0 || work_status != 0))"
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
flake.modules.nixos.adb =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ pkgs.android-tools ];
|
||||||
|
};
|
||||||
|
}
|
||||||
+142
-9
@@ -6,11 +6,57 @@ in
|
|||||||
{
|
{
|
||||||
flake.modules.nixos.ai =
|
flake.modules.nixos.ai =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
ai = import ./ai/_assets.nix { inherit pkgs; };
|
||||||
|
codexConfig = (pkgs.formats.toml { }).generate "codex-config.toml" {
|
||||||
|
model = "gpt-5.6-sol";
|
||||||
|
model_reasoning_effort = "high";
|
||||||
|
plan_mode_reasoning_effort = "high";
|
||||||
|
service_tier = "default";
|
||||||
|
approvals_reviewer = "auto_review";
|
||||||
|
features.hooks = true;
|
||||||
|
notify = [
|
||||||
|
"${pkgs.llm-agents.agent-deck}/bin/agent-deck"
|
||||||
|
"codex-notify"
|
||||||
|
];
|
||||||
|
|
||||||
|
tui = {
|
||||||
|
status_line = [
|
||||||
|
"model-with-reasoning"
|
||||||
|
"current-dir"
|
||||||
|
"context-remaining"
|
||||||
|
"five-hour-limit"
|
||||||
|
"weekly-limit"
|
||||||
|
"git-branch"
|
||||||
|
];
|
||||||
|
status_line_use_colors = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
features.plugins = true;
|
||||||
|
marketplaces.nix-managed = {
|
||||||
|
source_type = "local";
|
||||||
|
source = "${ai.marketplace}";
|
||||||
|
};
|
||||||
|
plugins."ponytail@nix-managed".enabled = true;
|
||||||
|
hooks = ai.codexHooks;
|
||||||
|
mcp_servers = ai.servers // {
|
||||||
|
context7 = ai.servers.context7 // {
|
||||||
|
http_headers_helper = "${ai.context7Headers}";
|
||||||
|
};
|
||||||
|
nixos = ai.servers.nixos // {
|
||||||
|
startup_timeout_sec = 60.0;
|
||||||
|
tools.nix.approval_mode = "approve";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [ nixosModules.podman ];
|
imports = [ nixosModules.podman ];
|
||||||
|
|
||||||
home-manager.sharedModules = [ hmModules.ai ];
|
home-manager.sharedModules = [ hmModules.ai ];
|
||||||
|
|
||||||
|
environment.etc."codex/config.toml".source = codexConfig;
|
||||||
|
|
||||||
nixpkgs.overlays = [ inputs.llm-agents.overlays.shared-nixpkgs ];
|
nixpkgs.overlays = [ inputs.llm-agents.overlays.shared-nixpkgs ];
|
||||||
|
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
@@ -28,7 +74,10 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.ai =
|
flake.modules.homeManager.ai =
|
||||||
{ pkgs, ... }:
|
{ pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
ai = import ./ai/_assets.nix { inherit pkgs; };
|
||||||
|
in
|
||||||
{
|
{
|
||||||
services.podman = {
|
services.podman = {
|
||||||
volumes = {
|
volumes = {
|
||||||
@@ -54,20 +103,104 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.mcp = {
|
|
||||||
enable = true;
|
|
||||||
servers.nixos = {
|
|
||||||
command = "${pkgs.uv}/bin/uvx";
|
|
||||||
args = [ "mcp-nixos" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
home.packages = [
|
home.packages = [
|
||||||
|
# Node-based Codex plugin hooks and skill scripts need node/npm outside project dev shells.
|
||||||
|
pkgs.nodejs
|
||||||
|
pkgs.python3
|
||||||
pkgs.llm-agents.codex
|
pkgs.llm-agents.codex
|
||||||
pkgs.llm-agents.pi
|
pkgs.llm-agents.pi
|
||||||
pkgs.llm-agents.claude-code
|
pkgs.llm-agents.claude-code
|
||||||
|
pkgs.llm-agents.agent-deck
|
||||||
pkgs.llm-agents.herdr
|
pkgs.llm-agents.herdr
|
||||||
|
pkgs.tmux
|
||||||
pkgs.ctx7
|
pkgs.ctx7
|
||||||
];
|
];
|
||||||
|
|
||||||
|
xdg.configFile."herdr/config.toml".text = ''
|
||||||
|
onboarding = false
|
||||||
|
|
||||||
|
[ui]
|
||||||
|
agent_panel_sort = "spaces"
|
||||||
|
prompt_new_tab_name = false
|
||||||
|
|
||||||
|
[ui.toast]
|
||||||
|
delivery = "off"
|
||||||
|
|
||||||
|
[keys]
|
||||||
|
# Super belongs to Niri; Ctrl navigation belongs to Neovim.
|
||||||
|
focus_pane_left = ["prefix+h", "ctrl+alt+h"]
|
||||||
|
focus_pane_down = ["prefix+j", "ctrl+alt+j"]
|
||||||
|
focus_pane_up = ["prefix+k", "ctrl+alt+k"]
|
||||||
|
focus_pane_right = ["prefix+l", "ctrl+alt+l"]
|
||||||
|
next_workspace = "ctrl+alt+u"
|
||||||
|
previous_workspace = "ctrl+alt+i"
|
||||||
|
navigate_workspace_down = "u"
|
||||||
|
navigate_workspace_up = "i"
|
||||||
|
workspace_picker = ["prefix+w", "ctrl+alt+o"]
|
||||||
|
goto = ["prefix+g", "ctrl+alt+g"]
|
||||||
|
previous_agent = "ctrl+alt+p"
|
||||||
|
next_agent = "ctrl+alt+n"
|
||||||
|
previous_tab = ["prefix+p", "ctrl+alt+["]
|
||||||
|
next_tab = ["prefix+n", "ctrl+alt+]"]
|
||||||
|
new_tab = ["prefix+c", "ctrl+alt+enter"]
|
||||||
|
split_vertical = ["prefix+v", "ctrl+alt+v"]
|
||||||
|
split_horizontal = ["prefix+minus", "ctrl+alt+minus"]
|
||||||
|
zoom = ["prefix+z", "ctrl+alt+f"]
|
||||||
|
detach = ["prefix+q", "ctrl+alt+q"]
|
||||||
|
|
||||||
|
swap_pane_left = ["prefix+shift+h", "ctrl+alt+shift+h"]
|
||||||
|
swap_pane_down = ["prefix+shift+j", "ctrl+alt+shift+j"]
|
||||||
|
swap_pane_up = ["prefix+shift+k", "ctrl+alt+shift+k"]
|
||||||
|
swap_pane_right = ["prefix+shift+l", "ctrl+alt+shift+l"]
|
||||||
|
resize_pane_left = "ctrl+alt+shift+left"
|
||||||
|
resize_pane_down = "ctrl+alt+shift+down"
|
||||||
|
resize_pane_up = "ctrl+alt+shift+up"
|
||||||
|
resize_pane_right = "ctrl+alt+shift+right"
|
||||||
|
resize_mode = ["prefix+r", "ctrl+alt+r"]
|
||||||
|
cycle_pane_next = ["prefix+tab", "ctrl+alt+tab"]
|
||||||
|
cycle_pane_previous = ["prefix+shift+tab", "ctrl+alt+shift+tab"]
|
||||||
|
last_pane = "ctrl+alt+backspace"
|
||||||
|
close_pane = ["prefix+x", "ctrl+alt+x"]
|
||||||
|
rename_pane = ["prefix+shift+p", "ctrl+alt+shift+p"]
|
||||||
|
copy_mode = ["prefix+[", "ctrl+alt+y"]
|
||||||
|
edit_scrollback = ["prefix+e", "ctrl+alt+e"]
|
||||||
|
|
||||||
|
close_tab = ["prefix+shift+x", "ctrl+alt+shift+x"]
|
||||||
|
rename_tab = ["prefix+shift+t", "ctrl+alt+shift+a"]
|
||||||
|
move_tab_previous = "ctrl+alt+shift+["
|
||||||
|
move_tab_next = "ctrl+alt+shift+]"
|
||||||
|
new_workspace = ["prefix+shift+n", "ctrl+alt+shift+enter"]
|
||||||
|
rename_workspace = ["prefix+shift+w", "ctrl+alt+shift+w"]
|
||||||
|
close_workspace = ["prefix+shift+d", "ctrl+alt+shift+d"]
|
||||||
|
open_worktree = "ctrl+alt+w"
|
||||||
|
new_worktree = ["prefix+shift+g", "ctrl+alt+shift+b"]
|
||||||
|
|
||||||
|
toggle_sidebar = ["prefix+b", "ctrl+alt+b"]
|
||||||
|
help = ["prefix+?", "ctrl+alt+slash"]
|
||||||
|
settings = ["prefix+s", "ctrl+alt+s"]
|
||||||
|
reload_config = ["prefix+shift+r", "ctrl+alt+shift+r"]
|
||||||
|
|
||||||
|
[[keys.command]]
|
||||||
|
key = "ctrl+alt+shift+g"
|
||||||
|
type = "popup"
|
||||||
|
command = "lazygit"
|
||||||
|
description = "Lazygit"
|
||||||
|
width = "90%"
|
||||||
|
height = "90%"
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Codex owns its writable user config; Nix owns assets and system defaults.
|
||||||
|
home.file =
|
||||||
|
lib.mapAttrs' (
|
||||||
|
name: source: lib.nameValuePair ".agents/skills/${name}" { inherit source; }
|
||||||
|
) ai.skills
|
||||||
|
// {
|
||||||
|
".codex/AGENTS.md".text = builtins.readFile ./ai/instructions/codex.md;
|
||||||
|
# Codex's installed-plugin scanner skips symlinked version directories.
|
||||||
|
"${ai.codexCache}" = {
|
||||||
|
source = ai.sources.ponytail;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Codex installation
|
||||||
|
|
||||||
|
`ai.nix` installs binaries and Codex defaults on Polaris and Zenith.
|
||||||
|
`_sources.nix` pins upstream assets; `_assets.nix` declares skills, MCP servers,
|
||||||
|
the Ponytail marketplace and the upstream Herdr session hook.
|
||||||
|
Edit `instructions/codex.md` for global Codex instructions.
|
||||||
|
|
||||||
|
Nix owns installation files. Codex owns writable user settings, plugin toggles,
|
||||||
|
trust, credentials and sessions. Bundled/service-delivered capabilities remain
|
||||||
|
vendor-managed. Update Ponytail's revision, hash and `ponytailVersion` together.
|
||||||
|
The cache uses real directories with linked files because Codex skips symlinked
|
||||||
|
plugin version directories. Do not run plugin updaters on Nix-managed assets.
|
||||||
|
|
||||||
|
Herdr's skill is linked directly from the same source as its binary. An agent
|
||||||
|
can also read it with `herdr --skill`; no generated file is necessary.
|
||||||
|
The upstream session hook supports restore, not model instruction injection.
|
||||||
|
|
||||||
|
## Manual transition
|
||||||
|
|
||||||
|
Close Codex before cleaning up the previous setup and activating the new one.
|
||||||
|
No migration or compatibility code runs automatically.
|
||||||
|
|
||||||
|
- Remove old standalone skills: `~/.codex/skills/ponytail`,
|
||||||
|
`~/.agents/skills/find-skills`, `~/.agents/skills/context7-mcp.bak`,
|
||||||
|
and `~/.codex/skills/nixos-maintainer.bak`.
|
||||||
|
- Remove the old Ponytail cache `~/.codex/plugins/cache/ponytail/ponytail`.
|
||||||
|
Remove any unmanaged copy at `~/.codex/plugins/cache/nix-managed/ponytail/4.9.0`
|
||||||
|
if it blocks Home Manager activation. The obsolete managed
|
||||||
|
`~/.codex/plugins/ponytail` link is removed by Home Manager.
|
||||||
|
- In `~/.codex/config.toml`, remove the old `marketplaces.ponytail` entry and
|
||||||
|
rename `plugins."ponytail@ponytail"` to `plugins."ponytail@nix-managed"`,
|
||||||
|
preserving its enabled preference. Remove user launch fields for the
|
||||||
|
`context7`, `nixos` and `openaiDeveloperDocs` MCP servers so system defaults
|
||||||
|
apply; preserve toggles and unrelated preferences.
|
||||||
|
- Remove the old Herdr SessionStart command from `~/.codex/hooks.json` and its
|
||||||
|
`~/.codex/herdr-agent-state.sh` file. Preserve unrelated hooks.
|
||||||
|
- Activate your Nix configuration, then restart Codex.
|
||||||
|
|
||||||
|
If an earlier version of this work was activated, Home Manager removes its
|
||||||
|
managed instruction and integration links for other harnesses. Unmanaged copies
|
||||||
|
must be removed manually if no longer wanted.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
{ pkgs }:
|
||||||
|
let
|
||||||
|
sources = import ./_sources.nix { inherit pkgs; };
|
||||||
|
json = pkgs.formats.json { };
|
||||||
|
ponytailVersion = "4.9.0";
|
||||||
|
context7Headers = pkgs.writeShellScript "context7-http-headers" ''
|
||||||
|
set -euo pipefail
|
||||||
|
CONTEXT7_KEY_FILE="''${XDG_CONFIG_HOME:-$HOME/.config}/context7/api-key"
|
||||||
|
CONTEXT7_KEY="$(< "$CONTEXT7_KEY_FILE")"
|
||||||
|
exec ${pkgs.jq}/bin/jq --null-input --compact-output \
|
||||||
|
--arg authorization "Bearer $CONTEXT7_KEY" '{ Authorization: $authorization }'
|
||||||
|
'';
|
||||||
|
codexHooks = {
|
||||||
|
SessionStart = [
|
||||||
|
{
|
||||||
|
hooks = [
|
||||||
|
{
|
||||||
|
type = "command";
|
||||||
|
command = "${pkgs.bash}/bin/bash ${sources.herdr}/src/integration/assets/codex/herdr-agent-state.sh session";
|
||||||
|
timeout = 10;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit sources ponytailVersion context7Headers;
|
||||||
|
inherit codexHooks;
|
||||||
|
codexCache = ".codex/plugins/cache/nix-managed/ponytail/${ponytailVersion}";
|
||||||
|
marketplace = pkgs.runCommand "ai-marketplace" { } ''
|
||||||
|
mkdir -p "$out/.agents/plugins" "$out/plugins"
|
||||||
|
ln -s ${sources.ponytail} "$out/plugins/ponytail"
|
||||||
|
cp ${
|
||||||
|
json.generate "ai-marketplace.json" {
|
||||||
|
name = "nix-managed";
|
||||||
|
plugins = [
|
||||||
|
{
|
||||||
|
name = "ponytail";
|
||||||
|
source = {
|
||||||
|
source = "local";
|
||||||
|
path = "./plugins/ponytail";
|
||||||
|
};
|
||||||
|
policy = {
|
||||||
|
installation = "AVAILABLE";
|
||||||
|
authentication = "ON_INSTALL";
|
||||||
|
};
|
||||||
|
category = "Productivity";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} "$out/.agents/plugins/marketplace.json"
|
||||||
|
'';
|
||||||
|
skills = {
|
||||||
|
context7-mcp = ../skills/context7-mcp;
|
||||||
|
nixos-maintainer = ../skills/nixos-maintainer;
|
||||||
|
herdr = "${sources.herdr}/skills/herdr";
|
||||||
|
};
|
||||||
|
servers = {
|
||||||
|
context7.url = "https://mcp.context7.com/mcp";
|
||||||
|
nixos.command = "${pkgs.mcp-nixos}/bin/mcp-nixos";
|
||||||
|
openaiDeveloperDocs.url = "https://developers.openai.com/mcp";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{ pkgs }:
|
||||||
|
{
|
||||||
|
ponytail = pkgs.fetchFromGitHub {
|
||||||
|
owner = "DietrichGebert";
|
||||||
|
repo = "ponytail";
|
||||||
|
rev = "356918eba965ee1eac64bd3a7f0dd02108350de5";
|
||||||
|
hash = "sha256-LPNMyHsri3+eeDmphEAKL1JgoRE4dLIPfZ4XZ+xu5UY=";
|
||||||
|
};
|
||||||
|
herdr = pkgs.llm-agents.herdr.src;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Environment
|
||||||
|
|
||||||
|
- This is Nix; use `nix run` for missing commands. Default Nix commands to `--quiet`.
|
||||||
|
- Keep output bounded. Capture large Nix listings in `/tmp`; inspect targeted excerpts and failing logs only. Locate store files before reading them.
|
||||||
|
- Manage persistent binaries, skills, plugins and MCP definitions in `/home/kiri/.config/nixos`. Keep interactive settings, credentials and session state outside Nix.
|
||||||
|
- `HERDR_ENV=1` means you are inside Herdr. Read the Herdr skill or run `herdr --skill` when Herdr interaction is needed.
|
||||||
|
|
||||||
|
# Work
|
||||||
|
|
||||||
|
- Inspect relevant code and callers; follow project conventions and fix root causes.
|
||||||
|
- Prefer existing code, standard libraries and native capabilities. Avoid speculative abstractions; optimize conceptual simplicity, not line count.
|
||||||
|
- Keep changes focused. Prefer clean breaking changes over compatibility layers or migration scripts; explain required manual steps.
|
||||||
|
- Use targeted reads and tool calls. Verify unfamiliar or consequential APIs against version-appropriate primary documentation; prefer Context7 when needed.
|
||||||
|
- In reviews, distinguish confirmed problems from optional improvements and explain meaningful tradeoffs.
|
||||||
|
- Never push without my explicit approval. Other remote actions must remain within the authorized task.
|
||||||
|
- User instructions take precedence over skill guidelines, including testing defaults.
|
||||||
|
|
||||||
|
# Validation
|
||||||
|
|
||||||
|
Do not add or run tests unless explicitly requested or necessary to resolve a
|
||||||
|
concrete correctness concern. Use the smallest relevant validation and stop once
|
||||||
|
it provides sufficient confidence. Avoid broad suites and repeated builds without
|
||||||
|
a specific reason. Report only checks actually performed.
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
alsa.enable = true;
|
alsa.enable = true;
|
||||||
pulse.enable = true;
|
pulse.enable = true;
|
||||||
jack.enable = true;
|
jack.enable = true;
|
||||||
wireplumber.enable = true;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
{
|
||||||
flake.modules.homeManager.desktop-commands =
|
flake.modules.homeManager.desktop-commands =
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
@@ -23,9 +22,68 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.vivaldi =
|
flake.modules.homeManager.vivaldi =
|
||||||
{ lib, pkgs, ... }:
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
command = lib.getExe pkgs.vivaldi;
|
command = lib.getExe pkgs.vivaldi;
|
||||||
|
appCommand = id: "${command} --profile-directory=Default --app-id=${id}";
|
||||||
|
actualId = "ahoihnifhakgijcmjlhbcgehigihinlo";
|
||||||
|
outlookId = "eoficlgicibekocmfdomjbfnjmehnhcd";
|
||||||
|
whatsappId = "hnpfjngllnobngcgfapefoaidbinmjnm";
|
||||||
|
actualDesktop = pkgs.makeDesktopItem {
|
||||||
|
name = "vivaldi-${actualId}-Default";
|
||||||
|
desktopName = "Actual";
|
||||||
|
exec = appCommand actualId;
|
||||||
|
icon = "vivaldi-${actualId}-Default";
|
||||||
|
extraConfig.StartupWMClass = "crx_${actualId}";
|
||||||
|
actions = {
|
||||||
|
Accounts = {
|
||||||
|
name = "Accounts";
|
||||||
|
exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/accounts";
|
||||||
|
};
|
||||||
|
"Add-Transaction" = {
|
||||||
|
name = "Add Transaction";
|
||||||
|
exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/transactions/new";
|
||||||
|
};
|
||||||
|
Reports = {
|
||||||
|
name = "Reports";
|
||||||
|
exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/reports";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
whatsappDesktop = pkgs.makeDesktopItem {
|
||||||
|
name = "vivaldi-${whatsappId}-Default";
|
||||||
|
desktopName = "WhatsApp Web";
|
||||||
|
exec = appCommand whatsappId;
|
||||||
|
icon = "vivaldi-${whatsappId}-Default";
|
||||||
|
extraConfig.StartupWMClass = "crx_${whatsappId}";
|
||||||
|
};
|
||||||
|
outlookDesktop = pkgs.makeDesktopItem {
|
||||||
|
name = "vivaldi-${outlookId}-Default";
|
||||||
|
desktopName = "Outlook";
|
||||||
|
exec = "${appCommand outlookId} %U";
|
||||||
|
icon = "vivaldi-${outlookId}-Default";
|
||||||
|
mimeTypes = [ "x-scheme-handler/mailto" ];
|
||||||
|
extraConfig.StartupWMClass = "crx_${outlookId}";
|
||||||
|
actions = {
|
||||||
|
Calendar = {
|
||||||
|
name = "Open calendar";
|
||||||
|
exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/calendar";
|
||||||
|
};
|
||||||
|
Compose = {
|
||||||
|
name = "New message";
|
||||||
|
exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/mail/deeplink/compose";
|
||||||
|
};
|
||||||
|
Event = {
|
||||||
|
name = "New event";
|
||||||
|
exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/calendar/deeplink/compose";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
desktop.commands.browser = [ command ];
|
desktop.commands.browser = [ command ];
|
||||||
@@ -33,7 +91,23 @@
|
|||||||
packages = [ pkgs.vivaldi ];
|
packages = [ pkgs.vivaldi ];
|
||||||
sessionVariables.BROWSER = command;
|
sessionVariables.BROWSER = command;
|
||||||
};
|
};
|
||||||
xdg.mimeApps.defaultApplicationPackages = [ pkgs.vivaldi ];
|
xdg = {
|
||||||
|
dataFile = {
|
||||||
|
"applications/vivaldi-${actualId}-Default.desktop" = {
|
||||||
|
force = true;
|
||||||
|
source = "${actualDesktop}/share/applications/vivaldi-${actualId}-Default.desktop";
|
||||||
|
};
|
||||||
|
"applications/vivaldi-${whatsappId}-Default.desktop" = {
|
||||||
|
force = true;
|
||||||
|
source = "${whatsappDesktop}/share/applications/vivaldi-${whatsappId}-Default.desktop";
|
||||||
|
};
|
||||||
|
"applications/vivaldi-${outlookId}-Default.desktop" = {
|
||||||
|
force = true;
|
||||||
|
source = "${outlookDesktop}/share/applications/vivaldi-${outlookId}-Default.desktop";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mimeApps.defaultApplicationPackages = [ pkgs.vivaldi ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.nautilus =
|
flake.modules.homeManager.nautilus =
|
||||||
@@ -70,57 +144,13 @@
|
|||||||
flake.modules.homeManager.workstation-apps =
|
flake.modules.homeManager.workstation-apps =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
home.file.".harlequin.toml".text = ''
|
|
||||||
[profiles.taop]
|
|
||||||
adapter = "postgres"
|
|
||||||
conn_str = "postgresql://taop:taop@127.0.0.1:5433/taop"
|
|
||||||
|
|
||||||
[profiles.schemas]
|
|
||||||
adapter = "postgres"
|
|
||||||
conn_str = "postgresql://mathesar:mathesar@127.0.0.1:55432/traceability"
|
|
||||||
'';
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
postman
|
|
||||||
spotify
|
spotify
|
||||||
rainfrog
|
|
||||||
dblab
|
|
||||||
harlequin
|
|
||||||
tabularis
|
|
||||||
dbgate
|
|
||||||
pgadmin4-desktopmode
|
|
||||||
tbls
|
|
||||||
(pgmodeler.overrideAttrs (old: {
|
|
||||||
version = "2.0.0-beta";
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "nullptrlabs";
|
|
||||||
repo = "pgmodeler";
|
|
||||||
rev = "v2.0.0-beta";
|
|
||||||
hash = "sha256-NH7iRc484HskeSa8fi3nYThLq6kul3MItaiEezA4pd8=";
|
|
||||||
};
|
|
||||||
nativeBuildInputs = builtins.filter (input: input != qt6.qmake) old.nativeBuildInputs ++ [ cmake ];
|
|
||||||
buildInputs = old.buildInputs ++ [ libxml2 ];
|
|
||||||
qmakeFlags = [ ];
|
|
||||||
cmakeFlags = [ "-DPGM_PREFIX=${placeholder "out"}" ];
|
|
||||||
postPatch = ''
|
|
||||||
patchShebangs getbuildnum.sh
|
|
||||||
substituteInPlace BuildConfs.cmake \
|
|
||||||
--replace-fail /usr/bin/clang++ "$CXX" \
|
|
||||||
--replace-fail /usr/bin/clang "$CC"
|
|
||||||
'';
|
|
||||||
postInstall = ''
|
|
||||||
install -Dm444 "$src/assets/conf/pgmodeler_logo.png" \
|
|
||||||
"$out/share/icons/hicolor/256x256/apps/pgmodeler.png"
|
|
||||||
'';
|
|
||||||
}))
|
|
||||||
calcure
|
|
||||||
planify
|
|
||||||
unzip
|
unzip
|
||||||
gimp
|
|
||||||
dbeaver-bin
|
dbeaver-bin
|
||||||
beekeeper-studio
|
|
||||||
onlyoffice-desktopeditors
|
onlyoffice-desktopeditors
|
||||||
obsidian
|
pinta
|
||||||
|
zellij
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -138,9 +168,6 @@
|
|||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
cacheHome = "${localDir}/cache";
|
cacheHome = "${localDir}/cache";
|
||||||
configHome = "${homeDir}/.config";
|
|
||||||
dataHome = "${localDir}/share";
|
|
||||||
stateHome = "${localDir}/state";
|
|
||||||
|
|
||||||
userDirs = {
|
userDirs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -149,7 +176,7 @@
|
|||||||
|
|
||||||
download = "${homeDir}/downloads";
|
download = "${homeDir}/downloads";
|
||||||
documents = "${homeDir}/documents";
|
documents = "${homeDir}/documents";
|
||||||
projects = "${homeDir}/dev";
|
projects = "${homeDir}/projects";
|
||||||
music = "${mediaDir}/music";
|
music = "${mediaDir}/music";
|
||||||
pictures = "${mediaDir}/images";
|
pictures = "${mediaDir}/images";
|
||||||
videos = "${mediaDir}/videos";
|
videos = "${mediaDir}/videos";
|
||||||
|
|||||||
@@ -1,38 +1,52 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
{
|
||||||
flake.modules.homeManager.dev-tools =
|
flake.modules.homeManager.dev-tools =
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
let
|
let
|
||||||
stablePkgs = import inputs.nixpkgs-stable {
|
gardenctl = pkgs.stdenvNoCC.mkDerivation {
|
||||||
inherit (pkgs.stdenv.hostPlatform) system;
|
pname = "gardenctl";
|
||||||
config = {
|
version = "2.14.0";
|
||||||
inherit (pkgs.config) allowUnfree;
|
src = pkgs.fetchurl {
|
||||||
|
url = "https://github.com/gardener/gardenctl-v2/releases/download/v2.14.0/gardenctl_v2_linux_amd64";
|
||||||
|
hash = "sha256-JCZ0eJLgYbd2ZMCCWFlhX4vOhHKZL40oR2a3EZ3i4Q8=";
|
||||||
};
|
};
|
||||||
|
dontUnpack = true;
|
||||||
|
installPhase = ''
|
||||||
|
install -Dm755 "$src" "$out/bin/gardenctl"
|
||||||
|
install -d "$out/share/zsh/site-functions"
|
||||||
|
"$out/bin/gardenctl" completion zsh > "$out/share/zsh/site-functions/_gardenctl"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
gardenlogin = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
pname = "gardenlogin";
|
||||||
|
version = "0.10.0";
|
||||||
|
src = pkgs.fetchurl {
|
||||||
|
url = "https://github.com/gardener/gardenlogin/releases/download/v0.10.0/gardenlogin_linux_amd64";
|
||||||
|
hash = "sha256-X4nHiZ29Mbnhxv/wlyD6PxX1KxzaX2R27N7Muu/gnH8=";
|
||||||
|
};
|
||||||
|
dontUnpack = true;
|
||||||
|
installPhase = ''
|
||||||
|
install -Dm755 "$src" "$out/bin/gardenlogin"
|
||||||
|
ln -s gardenlogin "$out/bin/kubectl-gardenlogin"
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.sessionVariables.CARGO_HOME = "${config.xdg.dataHome}/cargo";
|
home.sessionVariables.CARGO_HOME = "${config.xdg.dataHome}/cargo";
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
httpie
|
|
||||||
bruno
|
bruno
|
||||||
usql
|
|
||||||
posting
|
|
||||||
resterm
|
|
||||||
kubectl
|
kubectl
|
||||||
mongodb-compass
|
kubelogin-oidc
|
||||||
|
rclone
|
||||||
scc
|
scc
|
||||||
nodejs
|
just
|
||||||
mariadb
|
gardenctl
|
||||||
|
gardenlogin
|
||||||
];
|
];
|
||||||
|
|
||||||
programs.lazygit = {
|
programs.lazygit.enable = true;
|
||||||
enable = true;
|
|
||||||
enableZshIntegration = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.jujutsu.enable = true;
|
programs.jujutsu.enable = true;
|
||||||
programs.jq.enable = true;
|
programs.jq.enable = true;
|
||||||
programs.bun.enable = true;
|
|
||||||
programs.ripgrep.enable = true;
|
programs.ripgrep.enable = true;
|
||||||
programs.k9s.enable = true;
|
programs.k9s.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
flake.modules.nixos.flatpak = {
|
flake.modules.nixos.flatpak.services.flatpak.enable = true;
|
||||||
services.flatpak.enable = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
@@ -28,21 +28,9 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
fontconfig = {
|
fontconfig = {
|
||||||
enable = true;
|
|
||||||
antialias = true;
|
|
||||||
allowBitmaps = false;
|
allowBitmaps = false;
|
||||||
useEmbeddedBitmaps = false;
|
useEmbeddedBitmaps = false;
|
||||||
|
subpixel.lcdfilter = "none";
|
||||||
hinting = {
|
|
||||||
enable = true;
|
|
||||||
autohint = false;
|
|
||||||
style = "slight";
|
|
||||||
};
|
|
||||||
|
|
||||||
subpixel = {
|
|
||||||
rgba = "none";
|
|
||||||
lcdfilter = "none";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,11 +6,24 @@ in
|
|||||||
flake.modules.homeManager.git =
|
flake.modules.homeManager.git =
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
machine = config.facts.machine;
|
machine = config.facts.machine;
|
||||||
allowedSignersFile = "${config.xdg.configHome}/git/allowed_signers";
|
allowedSignersFile = "${config.xdg.configHome}/git/allowed_signers";
|
||||||
|
githubTokenFile = "${config.xdg.configHome}/yookr/github-read-only.token";
|
||||||
|
|
||||||
|
gh = pkgs.symlinkJoin {
|
||||||
|
name = "gh-with-read-only-token-${pkgs.gh.version}";
|
||||||
|
paths = [ pkgs.gh ];
|
||||||
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
meta.mainProgram = "gh";
|
||||||
|
postBuild = ''
|
||||||
|
wrapProgram "$out/bin/gh" \
|
||||||
|
--run 'if [[ -z "''${GH_TOKEN:-}" && -r "${githubTokenFile}" ]]; then export GH_TOKEN="$(< "${githubTokenFile}")"; fi'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
mkScope =
|
mkScope =
|
||||||
scope:
|
scope:
|
||||||
@@ -66,18 +79,27 @@ in
|
|||||||
contents = personal.git;
|
contents = personal.git;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
condition = "gitdir:${config.xdg.userDirs.projects}/";
|
condition = "gitdir:${config.home.homeDirectory}/yookr/";
|
||||||
|
contents = work.git;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
condition = "gitdir:${config.xdg.userDirs.projects}/own/";
|
||||||
contents = personal.git;
|
contents = personal.git;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
condition = "gitdir:${config.home.homeDirectory}/work/";
|
condition = "gitdir:${config.xdg.userDirs.projects}/ext/";
|
||||||
contents = work.git;
|
contents = personal.git;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
condition = "gitdir:${config.xdg.userDirs.projects}/forks/";
|
||||||
|
contents = personal.git;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.gh = {
|
programs.gh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
package = gh;
|
||||||
settings.git_protocol = "ssh";
|
settings.git_protocol = "ssh";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
flake.modules.nixos.handy = { pkgs, ... }: {
|
||||||
|
services.udev.packages = [
|
||||||
|
(pkgs.writeTextDir "lib/udev/rules.d/70-handy-keyboard.rules" ''
|
||||||
|
SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_KEYBOARD}=="1", TAG+="uaccess"
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager.handy =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
python = pkgs.python3.withPackages (ps: [ ps.evdev ]);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.handy ];
|
||||||
|
|
||||||
|
systemd.user.services.handy = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Handy dictation";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.handy}/bin/handy --start-hidden";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.handy-ptt = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Handy push-to-talk key release listener";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
Requisite = [ "handy.service" ];
|
||||||
|
After = [ "handy.service" ];
|
||||||
|
};
|
||||||
|
Service.ExecStart = "${python}/bin/python ${./handy/_push_to_talk.py} ${pkgs.handy}/bin/handy";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
"""Wait for release of the physical Super+D chord that launched this service."""
|
||||||
|
|
||||||
|
import signal
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
|
from evdev import InputDevice, ecodes as key, list_devices
|
||||||
|
|
||||||
|
|
||||||
|
def held(keys):
|
||||||
|
return key.KEY_D in keys and bool({key.KEY_LEFTMETA, key.KEY_RIGHTMETA} & set(keys))
|
||||||
|
|
||||||
|
|
||||||
|
def interrupted(signum, frame):
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
|
|
||||||
|
def main(handy):
|
||||||
|
signal.signal(signal.SIGTERM, interrupted)
|
||||||
|
for path in list_devices():
|
||||||
|
try:
|
||||||
|
device = InputDevice(path)
|
||||||
|
except OSError:
|
||||||
|
continue # Devices can disappear between enumeration and opening.
|
||||||
|
with closing(device):
|
||||||
|
if not held(device.active_keys()):
|
||||||
|
continue
|
||||||
|
action = "--cancel"
|
||||||
|
try:
|
||||||
|
subprocess.run([handy, "--toggle-transcription"], check=True)
|
||||||
|
# A quick release may already be queued while the CLI starts.
|
||||||
|
if held(device.active_keys()):
|
||||||
|
for event in device.read_loop():
|
||||||
|
if not held(device.active_keys()):
|
||||||
|
break
|
||||||
|
action = "--toggle-transcription"
|
||||||
|
finally:
|
||||||
|
# Disconnects, cancellation and service shutdown discard the recording.
|
||||||
|
subprocess.run([handy, action], check=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main(sys.argv[1])
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
"""Synthetic key-state checks; never reads a keyboard or records audio."""
|
||||||
|
|
||||||
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
|
import _push_to_talk as ptt
|
||||||
|
|
||||||
|
down = [ptt.key.KEY_LEFTMETA, ptt.key.KEY_D]
|
||||||
|
|
||||||
|
|
||||||
|
def check(states, expected, error=None):
|
||||||
|
device = Mock()
|
||||||
|
device.active_keys.side_effect = states
|
||||||
|
device.read_loop.return_value = iter([object(), object()])
|
||||||
|
if error:
|
||||||
|
device.read_loop.side_effect = error
|
||||||
|
with (
|
||||||
|
patch.object(ptt, "list_devices", return_value=["keyboard"]),
|
||||||
|
patch.object(ptt, "InputDevice", return_value=device),
|
||||||
|
patch.object(ptt.signal, "signal"),
|
||||||
|
patch.object(ptt.subprocess, "run") as run,
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
ptt.main("handy")
|
||||||
|
except (OSError, KeyboardInterrupt):
|
||||||
|
assert error is not None
|
||||||
|
assert [call.args[0][1] for call in run.call_args_list] == expected
|
||||||
|
device.close.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
check([[]], []) # Released before the listener starts: do not record.
|
||||||
|
check([down, []], ["--toggle-transcription", "--toggle-transcription"])
|
||||||
|
check([down, down, down, [ptt.key.KEY_D]], ["--toggle-transcription"] * 2)
|
||||||
|
check([down, down], ["--toggle-transcription", "--cancel"], OSError("unplugged"))
|
||||||
|
check([down, down], ["--toggle-transcription", "--cancel"], KeyboardInterrupt())
|
||||||
|
assert ptt.held([ptt.key.KEY_RIGHTMETA, ptt.key.KEY_D])
|
||||||
|
assert not ptt.held([ptt.key.KEY_LEFTMETA])
|
||||||
|
print("Push-to-talk release, repeat, disconnect and cancellation checks passed")
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
{ config, inputs, ... }:
|
|
||||||
let
|
|
||||||
homeModules = config.flake.modules.homeManager;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.modules.nixos.helix-cache = {
|
|
||||||
nix.settings = {
|
|
||||||
extra-substituters = [ "https://helix.cachix.org" ];
|
|
||||||
extra-trusted-public-keys = [
|
|
||||||
"helix.cachix.org-1:ejp9KQpR1FBI2onstMQ34yogDm4OgU2ru6lIwPvuCVs="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
flake.modules.homeManager.helix =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
let
|
|
||||||
svelteLanguageServer = (import ./_svelte-language-server.nix { inherit pkgs; }).overrideAttrs (
|
|
||||||
_: previousAttrs: {
|
|
||||||
postInstall = (previousAttrs.postInstall or "") + ''
|
|
||||||
# @vscode/emmet-helper only enables JSX expansion for JSX syntax;
|
|
||||||
# Helix's Svelte HTML regions also need it for HTML syntax.
|
|
||||||
substituteInPlace \
|
|
||||||
"$out/lib/node_modules/svelte-language-server/packages/language-server/node_modules/@vscode/emmet-helper/lib/cjs/emmetHelper.js" \
|
|
||||||
--replace-fail \
|
|
||||||
"'jsx.enabled': syntax === 'jsx'," \
|
|
||||||
"'jsx.enabled': syntax === 'jsx' || syntax === 'html',"
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
in
|
|
||||||
{
|
|
||||||
programs.helix = {
|
|
||||||
enable = true;
|
|
||||||
package = inputs.helix.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
|
||||||
extraPackages = with pkgs; [
|
|
||||||
vtsls
|
|
||||||
svelteLanguageServer
|
|
||||||
tailwindcss-language-server
|
|
||||||
|
|
||||||
nixd
|
|
||||||
nixfmt
|
|
||||||
oxfmt
|
|
||||||
|
|
||||||
simple-completion-language-server
|
|
||||||
|
|
||||||
odin
|
|
||||||
ols
|
|
||||||
|
|
||||||
rust-analyzer
|
|
||||||
rustfmt
|
|
||||||
cargo
|
|
||||||
|
|
||||||
zig
|
|
||||||
zls
|
|
||||||
lldb
|
|
||||||
];
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
theme = "kanagawa-custom";
|
|
||||||
editor = {
|
|
||||||
soft-wrap.enable = true;
|
|
||||||
lsp = {
|
|
||||||
auto-document-highlight = true;
|
|
||||||
display-inlay-hints = false;
|
|
||||||
};
|
|
||||||
rainbow-brackets = true;
|
|
||||||
line-number = "relative";
|
|
||||||
cursorline = true;
|
|
||||||
gutters = [
|
|
||||||
"code-action-hint"
|
|
||||||
"diagnostics"
|
|
||||||
"spacer"
|
|
||||||
"line-numbers"
|
|
||||||
"spacer"
|
|
||||||
"diff"
|
|
||||||
];
|
|
||||||
color-modes = true;
|
|
||||||
cursor-shape = {
|
|
||||||
insert = "bar";
|
|
||||||
normal = "block";
|
|
||||||
select = "underline";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
themes.kanagawa-custom = {
|
|
||||||
inherits = "kanagawa";
|
|
||||||
"ui.highlight".underline = {
|
|
||||||
color = "dragonBlue";
|
|
||||||
style = "line";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
languages = {
|
|
||||||
language-server.scls = {
|
|
||||||
command = "simple-completion-language-server";
|
|
||||||
environment.SNIPPETS_PATH = "${pkgs.vimPlugins.friendly-snippets}/snippets";
|
|
||||||
};
|
|
||||||
|
|
||||||
language-server.vtsls.config.vtsls.autoUseWorkspaceTsdk = true;
|
|
||||||
|
|
||||||
language = [
|
|
||||||
{
|
|
||||||
name = "javascript";
|
|
||||||
language-servers = [
|
|
||||||
"vtsls"
|
|
||||||
"scls"
|
|
||||||
];
|
|
||||||
auto-format = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "jsx";
|
|
||||||
language-servers = [
|
|
||||||
"vtsls"
|
|
||||||
"scls"
|
|
||||||
];
|
|
||||||
auto-format = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "typescript";
|
|
||||||
language-servers = [
|
|
||||||
"vtsls"
|
|
||||||
"scls"
|
|
||||||
];
|
|
||||||
auto-format = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "tsx";
|
|
||||||
language-servers = [
|
|
||||||
"vtsls"
|
|
||||||
"scls"
|
|
||||||
];
|
|
||||||
auto-format = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "svelte";
|
|
||||||
formatter = {
|
|
||||||
command = "${pkgs.coreutils}/bin/env";
|
|
||||||
args = [
|
|
||||||
"NODE_PATH=%{workspace_directory}/node_modules"
|
|
||||||
"oxfmt"
|
|
||||||
"--stdin-filepath=%{buffer_name}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
auto-format = true;
|
|
||||||
language-servers = [
|
|
||||||
"scls"
|
|
||||||
"svelteserver"
|
|
||||||
"tailwindcss-ls"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "nix";
|
|
||||||
auto-format = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "rust";
|
|
||||||
auto-format = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
flake.modules.homeManager.primary-editor-helix = {
|
|
||||||
imports = [ homeModules.helix ];
|
|
||||||
programs.helix.defaultEditor = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
flake.modules.homeManager.keyring = {
|
flake.modules.homeManager.keyring.services.gnome-keyring.enable = true;
|
||||||
services.gnome-keyring.enable = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,11 @@
|
|||||||
{ config, lib, ... }:
|
{ ... }:
|
||||||
let
|
|
||||||
palette = (import ./_kanagawa.nix).palette;
|
|
||||||
hex = lib.removePrefix "#";
|
|
||||||
terminalPalette = palette.terminal;
|
|
||||||
mkPalette = colors: lib.concatStringsSep ";" (map hex colors);
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
flake.modules.nixos.limine =
|
flake.modules.nixos.limine =
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
displayValues = builtins.attrValues config.facts.machine.displays;
|
primaryDisplay = lib.findFirst (display: display.primary) null (
|
||||||
primaryDisplays = lib.filter (display: display.primary) displayValues;
|
builtins.attrValues config.facts.machine.displays
|
||||||
primaryDisplay = if primaryDisplays == [ ] then null else builtins.head primaryDisplays;
|
);
|
||||||
interfaceResolution =
|
interfaceResolution =
|
||||||
if primaryDisplay != null && primaryDisplay.width != null then
|
if primaryDisplay != null && primaryDisplay.width != null then
|
||||||
"${toString primaryDisplay.width}x${toString primaryDisplay.height}"
|
"${toString primaryDisplay.width}x${toString primaryDisplay.height}"
|
||||||
@@ -24,53 +18,9 @@ in
|
|||||||
limine = {
|
limine = {
|
||||||
enable = true;
|
enable = true;
|
||||||
maxGenerations = 10;
|
maxGenerations = 10;
|
||||||
|
|
||||||
style = {
|
|
||||||
backdrop = hex palette.secondaryBackground;
|
|
||||||
|
|
||||||
graphicalTerminal = {
|
|
||||||
background = "00${hex palette.background}";
|
|
||||||
foreground = hex palette.foreground;
|
|
||||||
brightForeground = hex palette.selectionForeground;
|
|
||||||
brightBackground = hex palette.selectionBackground;
|
|
||||||
palette = mkPalette [
|
|
||||||
terminalPalette.color0
|
|
||||||
terminalPalette.color1
|
|
||||||
terminalPalette.color2
|
|
||||||
terminalPalette.color3
|
|
||||||
terminalPalette.color4
|
|
||||||
terminalPalette.color5
|
|
||||||
terminalPalette.color6
|
|
||||||
terminalPalette.color7
|
|
||||||
];
|
|
||||||
brightPalette = mkPalette [
|
|
||||||
terminalPalette.color8
|
|
||||||
terminalPalette.color9
|
|
||||||
terminalPalette.color10
|
|
||||||
terminalPalette.color11
|
|
||||||
terminalPalette.color12
|
|
||||||
terminalPalette.color13
|
|
||||||
terminalPalette.color14
|
|
||||||
terminalPalette.color15
|
|
||||||
];
|
|
||||||
font = {
|
|
||||||
scale = "2x2";
|
|
||||||
spacing = 1;
|
|
||||||
};
|
|
||||||
margin = 64;
|
|
||||||
marginGradient = 24;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface = {
|
|
||||||
branding = config.networking.hostName;
|
|
||||||
brandingColor = hex palette.accents.blue;
|
|
||||||
helpHidden = false;
|
|
||||||
resolution = interfaceResolution;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// lib.optionalAttrs (interfaceResolution != null) {
|
|
||||||
resolution = interfaceResolution;
|
resolution = interfaceResolution;
|
||||||
|
|
||||||
|
style.interface.resolution = interfaceResolution;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
{
|
{
|
||||||
programs.mpv = {
|
programs.mpv = {
|
||||||
enable = true;
|
enable = true;
|
||||||
bindings = {
|
bindings.D = "cycle deband";
|
||||||
D = "cycle deband";
|
|
||||||
};
|
|
||||||
config = {
|
config = {
|
||||||
profile = "high-quality";
|
profile = "high-quality";
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
{ themeName }:
|
|
||||||
''
|
|
||||||
require("kanagawa").setup({
|
|
||||||
dimInactive = true,
|
|
||||||
colors = {
|
|
||||||
theme = {
|
|
||||||
all = {
|
|
||||||
ui = {
|
|
||||||
bg_gutter = "none"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
overrides = function(colors)
|
|
||||||
local theme = colors.theme
|
|
||||||
|
|
||||||
local makeDiagnosticColor = function(color)
|
|
||||||
local c = require("kanagawa.lib.color")
|
|
||||||
return { fg = color, bg = c(color):blend(theme.ui.bg, 0.95):to_hex() }
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
TelescopeTitle = { fg = theme.ui.special, bold = true },
|
|
||||||
TelescopePromptNormal = { bg = theme.ui.bg_p1 },
|
|
||||||
TelescopePromptBorder = { fg = theme.ui.bg_p1, bg = theme.ui.bg_p1 },
|
|
||||||
TelescopeResultsNormal = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m1 },
|
|
||||||
TelescopeResultsBorder = { fg = theme.ui.bg_m1, bg = theme.ui.bg_m1 },
|
|
||||||
TelescopePreviewNormal = { bg = theme.ui.bg_dim },
|
|
||||||
TelescopePreviewBorder = { bg = theme.ui.bg_dim, fg = theme.ui.bg_dim },
|
|
||||||
|
|
||||||
Pmenu = { fg = theme.ui.shade0, bg = theme.ui.bg_p1 }, -- add `blend = vim.o.pumblend` to enable transparency
|
|
||||||
PmenuSel = { fg = "NONE", bg = theme.ui.bg_p2 },
|
|
||||||
PmenuSbar = { bg = theme.ui.bg_m1 },
|
|
||||||
PmenuThumb = { bg = theme.ui.bg_p2 },
|
|
||||||
|
|
||||||
DiagnosticVirtualTextHint = makeDiagnosticColor(theme.diag.hint),
|
|
||||||
DiagnosticVirtualTextInfo = makeDiagnosticColor(theme.diag.info),
|
|
||||||
DiagnosticVirtualTextWarn = makeDiagnosticColor(theme.diag.warning),
|
|
||||||
DiagnosticVirtualTextError = makeDiagnosticColor(theme.diag.error),
|
|
||||||
|
|
||||||
DiagnosticVirtualLinesHint = makeDiagnosticColor(theme.diag.hint),
|
|
||||||
DiagnosticVirtualLinesInfo = makeDiagnosticColor(theme.diag.info),
|
|
||||||
DiagnosticVirtualLinesWarn = makeDiagnosticColor(theme.diag.warning),
|
|
||||||
DiagnosticVirtualLinesError = makeDiagnosticColor(theme.diag.error),
|
|
||||||
|
|
||||||
FloatBorder = { fg = theme.ui.float.fg_border, bg = theme.ui.float.bg },
|
|
||||||
NormalFloat = { fg = theme.ui.float.fg, bg = theme.ui.float.bg },
|
|
||||||
WinBar = { fg = theme.ui.fg_dim, bg = "NONE" },
|
|
||||||
WinBarNC = { fg = theme.ui.nontext, bg = theme.ui.bg_dim },
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.cmd.colorscheme("${themeName}")
|
|
||||||
''
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
let
|
||||||
account = config.facts.account;
|
account = config.facts.account;
|
||||||
homeModules = config.flake.modules.homeManager;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.homeManager.neovim =
|
flake.modules.homeManager.neovim =
|
||||||
@@ -24,11 +23,33 @@ in
|
|||||||
hash = "sha256-RIAe30TTzZhHuXxC2VRVk/X73Qm1u2LWOW3AsnUfRzI=";
|
hash = "sha256-RIAe30TTzZhHuXxC2VRVk/X73Qm1u2LWOW3AsnUfRzI=";
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
nvimTreesitterWithAllGrammars = nvimTreesitter.withPlugins (
|
nvimTreesitterWithGrammars = nvimTreesitter.withPlugins (
|
||||||
_:
|
grammars: with grammars; [
|
||||||
map (
|
astro
|
||||||
grammar: if grammar == nvimTreesitter.builtGrammars.svelte then svelteGrammar else grammar
|
css
|
||||||
) nvimTreesitter.allGrammars
|
html
|
||||||
|
http
|
||||||
|
javascript
|
||||||
|
jsdoc
|
||||||
|
json
|
||||||
|
lua
|
||||||
|
markdown
|
||||||
|
markdown_inline
|
||||||
|
nix
|
||||||
|
python
|
||||||
|
query
|
||||||
|
regex
|
||||||
|
rust
|
||||||
|
sql
|
||||||
|
svelteGrammar
|
||||||
|
toml
|
||||||
|
tsx
|
||||||
|
typescript
|
||||||
|
typst
|
||||||
|
vim
|
||||||
|
vimdoc
|
||||||
|
yaml
|
||||||
|
]
|
||||||
);
|
);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -41,118 +62,146 @@ in
|
|||||||
|
|
||||||
wrappers.neovim = {
|
wrappers.neovim = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
settings.config_directory = ./lua-config;
|
settings.config_directory = ./lua-config;
|
||||||
|
|
||||||
runtimePkgs = with pkgs; [
|
runtimePkgs = with pkgs; [
|
||||||
ripgrep
|
ripgrep
|
||||||
fd
|
fd
|
||||||
wl-clipboard
|
wl-clipboard
|
||||||
|
|
||||||
stylua
|
stylua
|
||||||
|
nixfmt
|
||||||
|
oxfmt
|
||||||
taplo
|
taplo
|
||||||
yamlfmt
|
yamlfmt
|
||||||
lua-language-server
|
|
||||||
nixd
|
|
||||||
nixfmt
|
|
||||||
dafny
|
|
||||||
vscode-langservers-extracted
|
|
||||||
tailwindcss-language-server
|
|
||||||
rust-analyzer
|
|
||||||
rustfmt
|
rustfmt
|
||||||
astro-language-server
|
|
||||||
tinymist
|
|
||||||
typstyle
|
typstyle
|
||||||
websocat
|
|
||||||
ty
|
|
||||||
ruff
|
ruff
|
||||||
|
|
||||||
|
lua-language-server
|
||||||
|
nixd
|
||||||
|
vscode-langservers-extracted
|
||||||
|
yaml-language-server
|
||||||
vtsls
|
vtsls
|
||||||
oxlint
|
|
||||||
oxfmt
|
|
||||||
emmet-language-server
|
|
||||||
svelteLanguageServer
|
svelteLanguageServer
|
||||||
|
tailwindcss-language-server
|
||||||
|
emmet-language-server
|
||||||
|
oxlint
|
||||||
|
rust-analyzer
|
||||||
|
astro-language-server
|
||||||
|
tinymist
|
||||||
|
ty
|
||||||
|
|
||||||
|
postgresql
|
||||||
|
mariadb
|
||||||
|
mongosh
|
||||||
|
|
||||||
|
kulala-core
|
||||||
|
kulala-fmt
|
||||||
|
curl
|
||||||
|
jq
|
||||||
|
openssl
|
||||||
|
|
||||||
|
zk
|
||||||
];
|
];
|
||||||
|
|
||||||
specs = {
|
specs = {
|
||||||
lz-n = {
|
lz-n.data = pkgs.vimPlugins.lz-n;
|
||||||
data = pkgs.vimPlugins.lz-n;
|
|
||||||
};
|
|
||||||
|
|
||||||
support = {
|
editing = {
|
||||||
data = with pkgs.vimPlugins; [
|
|
||||||
plenary-nvim
|
|
||||||
kanagawa-nvim
|
|
||||||
nvimTreesitterWithAllGrammars
|
|
||||||
nvim-treesitter-textobjects
|
|
||||||
rainbow-delimiters-nvim
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
completion = {
|
|
||||||
lazy = true;
|
lazy = true;
|
||||||
data = with pkgs.vimPlugins; [
|
data = with pkgs.vimPlugins; [
|
||||||
blink-cmp
|
mini-nvim
|
||||||
luasnip
|
guess-indent-nvim
|
||||||
friendly-snippets
|
nvimTreesitterWithGrammars
|
||||||
colorful-menu-nvim
|
nvim-treesitter-textobjects
|
||||||
|
rainbow-delimiters-nvim
|
||||||
|
nvim-ts-autotag
|
||||||
|
grug-far-nvim
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
navigation = {
|
||||||
|
lazy = true;
|
||||||
|
data = with pkgs.vimPlugins; [
|
||||||
|
plenary-nvim
|
||||||
|
telescope-nvim
|
||||||
|
telescope-fzf-native-nvim
|
||||||
|
telescope-ui-select-nvim
|
||||||
|
{
|
||||||
|
data = oil-nvim;
|
||||||
|
lazy = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
diagnostics = {
|
||||||
|
lazy = true;
|
||||||
|
data = with pkgs.vimPlugins; [ trouble-nvim ];
|
||||||
|
};
|
||||||
|
|
||||||
lsp = {
|
lsp = {
|
||||||
lazy = true;
|
lazy = true;
|
||||||
data = with pkgs.vimPlugins; [
|
data = with pkgs.vimPlugins; [
|
||||||
nvim-lspconfig
|
nvim-lspconfig
|
||||||
lazydev-nvim
|
lazydev-nvim
|
||||||
nvim-navic
|
nvim-navic
|
||||||
trouble-nvim
|
SchemaStore-nvim
|
||||||
typst-preview-nvim
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
completion = {
|
||||||
|
lazy = true;
|
||||||
|
data = with pkgs.vimPlugins; [
|
||||||
|
blink-cmp
|
||||||
|
colorful-menu-nvim
|
||||||
|
friendly-snippets
|
||||||
|
{
|
||||||
|
data = blink-compat;
|
||||||
|
lazy = false;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
formatting = {
|
formatting = {
|
||||||
lazy = true;
|
lazy = true;
|
||||||
data = with pkgs.vimPlugins; [
|
data = with pkgs.vimPlugins; [ conform-nvim ];
|
||||||
conform-nvim
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
core = {
|
|
||||||
lazy = true;
|
|
||||||
data = with pkgs.vimPlugins; [
|
|
||||||
mini-nvim
|
|
||||||
guess-indent-nvim
|
|
||||||
direnv-vim
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ui = {
|
ui = {
|
||||||
lazy = true;
|
lazy = true;
|
||||||
data = with pkgs.vimPlugins; [
|
data = with pkgs.vimPlugins; [
|
||||||
|
render-markdown-nvim
|
||||||
lualine-nvim
|
lualine-nvim
|
||||||
gitsigns-nvim
|
gitsigns-nvim
|
||||||
|
diffview-nvim
|
||||||
zen-mode-nvim
|
zen-mode-nvim
|
||||||
which-key-nvim
|
which-key-nvim
|
||||||
kulala-nvim
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
project = {
|
database = {
|
||||||
lazy = true;
|
lazy = true;
|
||||||
data = with pkgs.vimPlugins; [
|
data = with pkgs.vimPlugins; [
|
||||||
project-nvim
|
vim-dadbod
|
||||||
|
vim-dadbod-completion
|
||||||
|
vim-dadbod-ui
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
telescope = {
|
http = {
|
||||||
lazy = true;
|
lazy = true;
|
||||||
data = with pkgs.vimPlugins; [
|
data = with pkgs.vimPlugins; [ kulala-nvim ];
|
||||||
telescope-nvim
|
};
|
||||||
telescope-fzf-native-nvim
|
|
||||||
telescope-ui-select-nvim
|
notes = {
|
||||||
];
|
lazy = true;
|
||||||
|
data = with pkgs.vimPlugins; [ zk-nvim ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
env.ZK_NOTEBOOK_DIR = "${config.home.homeDirectory}/sync/notes";
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
nixdExtras = {
|
nixdExtras = {
|
||||||
nixpkgs = "import ${pkgs.path} {}";
|
nixpkgs = "import ${pkgs.path} {}";
|
||||||
@@ -160,26 +209,15 @@ in
|
|||||||
home_manager_options = ''(builtins.getFlake "path://${account.nixosConfigurationPath}").nixosConfigurations.${osConfig.facts.machine.name}.options.home-manager.users.type.getSubOptions []'';
|
home_manager_options = ''(builtins.getFlake "path://${account.nixosConfigurationPath}").nixosConfigurations.${osConfig.facts.machine.name}.options.home-manager.users.type.getSubOptions []'';
|
||||||
};
|
};
|
||||||
|
|
||||||
themeSetup = import ./_kanagawa-theme.nix {
|
kulalaCorePath = "${pkgs.kulala-core}/bin/kulala-core";
|
||||||
themeName = "kanagawa-wave";
|
|
||||||
};
|
|
||||||
|
|
||||||
typstPreviewDependencies = {
|
|
||||||
tinymist = "${pkgs.tinymist}/bin/tinymist";
|
|
||||||
websocat = "${pkgs.websocat}/bin/websocat";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hosts.python3.nvim-host.enable = true;
|
|
||||||
hosts.node.nvim-host.enable = true;
|
|
||||||
binName = "nvim";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.primary-editor-neovim =
|
flake.modules.homeManager.primary-editor-neovim =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [ homeModules.neovim ];
|
imports = [ config.flake.modules.homeManager.neovim ];
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
EDITOR = "nvim";
|
EDITOR = "nvim";
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
require("options")
|
require("options")
|
||||||
|
require("keymaps")
|
||||||
|
require("autocmds")
|
||||||
|
require("plugins.editing")
|
||||||
|
require("plugins.navigation")
|
||||||
|
require("plugins.diagnostics")
|
||||||
require("plugins.lsp")
|
require("plugins.lsp")
|
||||||
require("plugins.completion")
|
require("plugins.completion")
|
||||||
require("plugins.formatting")
|
require("plugins.formatting")
|
||||||
require("plugins.treesitter")
|
|
||||||
require("plugins.telescope")
|
|
||||||
require("plugins.ui")
|
require("plugins.ui")
|
||||||
require("plugins.core")
|
require("plugins.database")
|
||||||
|
require("plugins.http")
|
||||||
|
require("plugins.notes")
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "TermLeave" }, {
|
||||||
|
desc = "Reload externally changed files without discarding unsaved edits",
|
||||||
|
group = vim.api.nvim_create_augroup("lux-checktime", { clear = true }),
|
||||||
|
command = "checktime",
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("TextYankPost", {
|
||||||
|
desc = "Highlight yanked text",
|
||||||
|
group = vim.api.nvim_create_augroup("lux-highlight-yank", { clear = true }),
|
||||||
|
callback = function()
|
||||||
|
vim.hl.on_yank()
|
||||||
|
end,
|
||||||
|
})
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
vim.g.mapleader = " "
|
||||||
|
vim.g.maplocalleader = ","
|
||||||
|
|
||||||
|
for _, lhs in ipairs({ "grn", "gra", "grx", "grr", "gri", "grt", "gO" }) do
|
||||||
|
vim.keymap.del("n", lhs)
|
||||||
|
end
|
||||||
|
vim.keymap.del("x", "gra")
|
||||||
|
vim.keymap.del({ "i", "s" }, "<C-S>")
|
||||||
|
|
||||||
|
for _, key in ipairs({ "j", "k" }) do
|
||||||
|
vim.keymap.set({ "n", "x" }, key, function()
|
||||||
|
return vim.bo.buftype == "" and vim.v.count == 0 and "g" .. key or key
|
||||||
|
end, { expr = true, desc = "Move by displayed line, or logical line with a count" })
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<C-h>", "<C-w><C-h>", { desc = "Focus left window" })
|
||||||
|
vim.keymap.set("n", "<C-j>", "<C-w><C-j>", { desc = "Focus lower window" })
|
||||||
|
vim.keymap.set("n", "<C-k>", "<C-w><C-k>", { desc = "Focus upper window" })
|
||||||
|
vim.keymap.set("n", "<C-l>", "<C-w><C-l>", { desc = "Focus right window" })
|
||||||
|
vim.keymap.set("n", "gl", vim.diagnostic.open_float, { desc = "Show diagnostic details" })
|
||||||
|
vim.keymap.set("t", "<Esc><Esc>", "<C-\\><C-n>", { desc = "Leave terminal mode" })
|
||||||
|
vim.keymap.set("n", "<leader>bd", "<cmd>bdelete<cr>", { desc = "Delete current buffer" })
|
||||||
|
vim.keymap.set("n", "[d", function()
|
||||||
|
vim.diagnostic.jump({ count = -1 })
|
||||||
|
end, { desc = "Previous diagnostic" })
|
||||||
|
vim.keymap.set("n", "]d", function()
|
||||||
|
vim.diagnostic.jump({ count = 1 })
|
||||||
|
end, { desc = "Next diagnostic" })
|
||||||
@@ -1,76 +1,32 @@
|
|||||||
vim.g.mapleader = " "
|
|
||||||
vim.g.maplocalleader = " "
|
|
||||||
|
|
||||||
vim.o.expandtab = true
|
vim.o.expandtab = true
|
||||||
vim.o.shiftwidth = 2
|
vim.o.shiftwidth = 2
|
||||||
vim.o.tabstop = 2
|
vim.o.tabstop = 2
|
||||||
vim.o.softtabstop = 2
|
vim.o.softtabstop = 2
|
||||||
|
|
||||||
vim.o.number = true
|
vim.o.number = true
|
||||||
-- vim.o.relativenumber = true
|
|
||||||
|
|
||||||
vim.o.mouse = "a"
|
|
||||||
|
|
||||||
vim.o.showmode = false
|
vim.o.showmode = false
|
||||||
vim.o.showtabline = 0
|
vim.o.showtabline = 0
|
||||||
|
|
||||||
vim.opt.shortmess:append("Wc")
|
|
||||||
|
|
||||||
vim.schedule(function()
|
|
||||||
vim.o.clipboard = "unnamedplus"
|
|
||||||
end)
|
|
||||||
|
|
||||||
vim.o.breakindent = true
|
|
||||||
|
|
||||||
vim.o.undofile = true
|
|
||||||
|
|
||||||
vim.o.ignorecase = true
|
|
||||||
vim.o.smartcase = true
|
|
||||||
|
|
||||||
vim.o.signcolumn = "yes"
|
vim.o.signcolumn = "yes"
|
||||||
|
vim.o.cursorline = true
|
||||||
|
vim.o.scrolloff = 10
|
||||||
|
|
||||||
|
vim.o.mouse = "a"
|
||||||
|
vim.o.clipboard = "unnamedplus"
|
||||||
|
vim.o.confirm = true
|
||||||
|
vim.o.timeoutlen = 300
|
||||||
vim.o.updatetime = 250
|
vim.o.updatetime = 250
|
||||||
|
|
||||||
vim.o.timeoutlen = 300
|
vim.o.breakindent = true
|
||||||
|
vim.o.linebreak = true
|
||||||
|
vim.o.undofile = true
|
||||||
|
vim.o.ignorecase = true
|
||||||
|
vim.o.smartcase = true
|
||||||
|
vim.o.inccommand = "split"
|
||||||
|
|
||||||
vim.o.splitright = true
|
vim.o.splitright = true
|
||||||
vim.o.splitbelow = true
|
vim.o.splitbelow = true
|
||||||
|
|
||||||
|
vim.opt.shortmess:append("Wc")
|
||||||
|
|
||||||
vim.o.list = true
|
vim.o.list = true
|
||||||
vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" }
|
vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" }
|
||||||
|
|
||||||
vim.o.inccommand = "split"
|
|
||||||
|
|
||||||
vim.o.cursorline = true
|
|
||||||
|
|
||||||
vim.o.scrolloff = 10
|
|
||||||
|
|
||||||
vim.o.confirm = true
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
|
|
||||||
vim.keymap.set("n", "<leader>bd", "<cmd>bdelete<CR>", { desc = "[B]uffer [D]elete" })
|
|
||||||
|
|
||||||
vim.keymap.set("t", "<Esc><Esc>", "<C-\\><C-n>", { desc = "Exit terminal mode" })
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<C-h>", "<C-w><C-h>", { desc = "Move focus to the left window" })
|
|
||||||
vim.keymap.set("n", "<C-l>", "<C-w><C-l>", { desc = "Move focus to the right window" })
|
|
||||||
vim.keymap.set("n", "<C-j>", "<C-w><C-j>", { desc = "Move focus to the lower window" })
|
|
||||||
vim.keymap.set("n", "<C-k>", "<C-w><C-k>", { desc = "Move focus to the upper window" })
|
|
||||||
|
|
||||||
vim.keymap.set("n", "j", "gj", { silent = true })
|
|
||||||
vim.keymap.set("n", "k", "gk", { silent = true })
|
|
||||||
|
|
||||||
-- vim.keymap.set("n", "<C-S-h>", "<C-w>H", { desc = "Move window to the left" })
|
|
||||||
-- vim.keymap.set("n", "<C-S-l>", "<C-w>L", { desc = "Move window to the right" })
|
|
||||||
-- vim.keymap.set("n", "<C-S-j>", "<C-w>J", { desc = "Move window to the lower" })
|
|
||||||
-- vim.keymap.set("n", "<C-S-k>", "<C-w>K", { desc = "Move window to the upper" })
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("TextYankPost", {
|
|
||||||
desc = "Highlight when yanking (copying) text",
|
|
||||||
group = vim.api.nvim_create_augroup("lux-highlight-yank", { clear = true }),
|
|
||||||
callback = function()
|
|
||||||
vim.hl.on_yank()
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
@@ -1,19 +1,7 @@
|
|||||||
|
require("blink.compat").setup({})
|
||||||
|
|
||||||
require("lz.n").load({
|
require("lz.n").load({
|
||||||
{
|
{ "friendly-snippets" },
|
||||||
"friendly-snippets",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"luasnip",
|
|
||||||
event = { "InsertEnter", "CmdlineEnter" },
|
|
||||||
before = function()
|
|
||||||
require("lz.n").trigger_load("friendly-snippets")
|
|
||||||
end,
|
|
||||||
after = function()
|
|
||||||
require("luasnip.loaders.from_vscode").lazy_load()
|
|
||||||
-- Load custom lua snippets
|
|
||||||
require("luasnip.loaders.from_lua").load({ paths = { vim.fn.stdpath("config") .. "/snippets" } })
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"colorful-menu.nvim",
|
"colorful-menu.nvim",
|
||||||
event = { "InsertEnter", "CmdlineEnter" },
|
event = { "InsertEnter", "CmdlineEnter" },
|
||||||
@@ -24,41 +12,18 @@ require("lz.n").load({
|
|||||||
{
|
{
|
||||||
"blink.cmp",
|
"blink.cmp",
|
||||||
event = { "InsertEnter", "CmdlineEnter" },
|
event = { "InsertEnter", "CmdlineEnter" },
|
||||||
before = function()
|
|
||||||
-- Trigger lazydev so it's ready for blink source
|
|
||||||
require("lz.n").trigger_load({ "lazydev.nvim", "luasnip", "colorful-menu.nvim" })
|
|
||||||
end,
|
|
||||||
after = function()
|
after = function()
|
||||||
require("blink.cmp").setup({
|
require("blink.cmp").setup({
|
||||||
keymap = {
|
keymap = {
|
||||||
preset = "default",
|
["<Esc>"] = { "cancel", "fallback" },
|
||||||
|
|
||||||
-- [Up/Down]
|
|
||||||
["<C-j>"] = { "select_next", "fallback" },
|
["<C-j>"] = { "select_next", "fallback" },
|
||||||
["<C-k>"] = { "select_prev", "fallback" }, -- Overrides Signature Help
|
["<C-k>"] = { "select_prev", "fallback" },
|
||||||
|
["<Tab>"] = { "select_and_accept", "fallback" },
|
||||||
-- [Insert Suggestion]
|
|
||||||
["<tab>"] = { "select_and_accept", "fallback" },
|
|
||||||
|
|
||||||
-- [Remap Signature Help]
|
|
||||||
-- Since we took <C-k>, let's move signature help to <C-g> (optional)
|
|
||||||
["<C-g>"] = { "show_signature", "hide_signature", "fallback" },
|
["<C-g>"] = { "show_signature", "hide_signature", "fallback" },
|
||||||
},
|
},
|
||||||
|
|
||||||
appearance = {
|
|
||||||
nerd_font_variant = "mono",
|
|
||||||
},
|
|
||||||
|
|
||||||
completion = {
|
completion = {
|
||||||
documentation = {
|
documentation = { auto_show = true },
|
||||||
auto_show = true,
|
|
||||||
auto_show_delay_ms = 500,
|
|
||||||
window = {
|
|
||||||
border = "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
menu = {
|
menu = {
|
||||||
border = "none",
|
|
||||||
draw = {
|
draw = {
|
||||||
columns = { { "kind_icon" }, { "label", gap = 1 } },
|
columns = { { "kind_icon" }, { "label", gap = 1 } },
|
||||||
components = {
|
components = {
|
||||||
@@ -74,38 +39,30 @@ require("lz.n").load({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
cmdline = {
|
cmdline = {
|
||||||
completion = {
|
completion = { menu = { auto_show = true } },
|
||||||
menu = {
|
|
||||||
auto_show = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
keymap = { preset = "inherit" },
|
keymap = { preset = "inherit" },
|
||||||
},
|
},
|
||||||
|
|
||||||
sources = {
|
sources = {
|
||||||
default = {
|
default = { "lsp", "path", "snippets" },
|
||||||
"lsp",
|
per_filetype = {
|
||||||
"path",
|
lua = { inherit_defaults = true, "lazydev" },
|
||||||
"snippets",
|
sql = { inherit_defaults = true, "vim-dadbod-completion" },
|
||||||
"lazydev",
|
mysql = { inherit_defaults = true, "vim-dadbod-completion" },
|
||||||
|
plsql = { inherit_defaults = true, "vim-dadbod-completion" },
|
||||||
},
|
},
|
||||||
providers = {
|
providers = {
|
||||||
lazydev = { module = "lazydev.integrations.blink", score_offset = 100 },
|
lazydev = {
|
||||||
},
|
module = "lazydev.integrations.blink",
|
||||||
},
|
score_offset = 100,
|
||||||
|
},
|
||||||
snippets = { preset = "luasnip" },
|
["vim-dadbod-completion"] = {
|
||||||
|
name = "vim-dadbod-completion",
|
||||||
fuzzy = { implementation = "prefer_rust_with_warning" },
|
module = "blink.compat.source",
|
||||||
|
},
|
||||||
signature = {
|
|
||||||
enabled = true,
|
|
||||||
window = {
|
|
||||||
border = "none",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
signature = { enabled = true },
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
require("lz.n").load({
|
|
||||||
{
|
|
||||||
"mini.nvim",
|
|
||||||
event = { "BufReadPre", "BufNewFile" },
|
|
||||||
after = function()
|
|
||||||
require("mini.ai").setup({ n_lines = 500 })
|
|
||||||
require("mini.surround").setup()
|
|
||||||
require("mini.pairs").setup()
|
|
||||||
|
|
||||||
local files = require("mini.files")
|
|
||||||
files.setup()
|
|
||||||
vim.keymap.set("n", "<leader>e", function()
|
|
||||||
if not files.close() then
|
|
||||||
files.open(vim.api.nvim_buf_get_name(0))
|
|
||||||
end
|
|
||||||
end, { desc = "File [E]xplorer" })
|
|
||||||
|
|
||||||
local icons = require("mini.icons")
|
|
||||||
icons.setup()
|
|
||||||
icons.mock_nvim_web_devicons()
|
|
||||||
|
|
||||||
local hipatterns = require("mini.hipatterns")
|
|
||||||
hipatterns.setup({
|
|
||||||
highlighters = {
|
|
||||||
hex_color = hipatterns.gen_highlighter.hex_color(),
|
|
||||||
fixme = { pattern = "%f[%w]()FIXME()%f[%W]", group = "MiniHipatternsFixme" },
|
|
||||||
hack = { pattern = "%f[%w]()HACK()%f[%W]", group = "MiniHipatternsHack" },
|
|
||||||
todo = { pattern = "%f[%w]()TODO()%f[%W]", group = "MiniHipatternsTodo" },
|
|
||||||
note = { pattern = "%f[%w]()NOTE()%f[%W]", group = "MiniHipatternsNote" },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
local indentscope = require("mini.indentscope")
|
|
||||||
indentscope.setup({
|
|
||||||
symbol = "│",
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("FileType", {
|
|
||||||
pattern = { "help", "Trouble" },
|
|
||||||
callback = function()
|
|
||||||
vim.b.miniindentscope_disable = true
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"guess-indent.nvim",
|
|
||||||
event = { "BufReadPre", "BufNewFile" },
|
|
||||||
after = function()
|
|
||||||
require("guess-indent").setup({})
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"direnv.vim",
|
|
||||||
event = "BufEnter",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
local commands = {
|
||||||
|
"DBUI",
|
||||||
|
"DBUIToggle",
|
||||||
|
"DBUIAddConnection",
|
||||||
|
"DBUIFindBuffer",
|
||||||
|
"DBUIRenameBuffer",
|
||||||
|
"DBUILastQueryInfo",
|
||||||
|
}
|
||||||
|
local sql_filetypes = { "sql", "mysql", "plsql" }
|
||||||
|
local query_filetypes = { "sql", "mysql", "plsql", "javascript" }
|
||||||
|
|
||||||
|
require("lz.n").load({
|
||||||
|
{ "vim-dadbod" },
|
||||||
|
{ "vim-dadbod-completion", ft = sql_filetypes },
|
||||||
|
{
|
||||||
|
"vim-dadbod-ui",
|
||||||
|
cmd = commands,
|
||||||
|
ft = query_filetypes,
|
||||||
|
keys = {
|
||||||
|
{ "<leader>qo", "<cmd>DBUIToggle<cr>", desc = "Toggle database workspace" },
|
||||||
|
{
|
||||||
|
"<localleader>r",
|
||||||
|
"<Plug>(DBUI_ExecuteQuery)",
|
||||||
|
mode = { "n", "x" },
|
||||||
|
ft = query_filetypes,
|
||||||
|
remap = true,
|
||||||
|
desc = "Execute database query",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>s",
|
||||||
|
"<Plug>(DBUI_SaveQuery)",
|
||||||
|
ft = query_filetypes,
|
||||||
|
remap = true,
|
||||||
|
desc = "Save database query",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>p",
|
||||||
|
"<Plug>(DBUI_EditBindParameters)",
|
||||||
|
ft = query_filetypes,
|
||||||
|
remap = true,
|
||||||
|
desc = "Edit query parameters",
|
||||||
|
},
|
||||||
|
{ "<CR>", "<Plug>(DBUI_SelectLine)", ft = "dbui", remap = true, desc = "Open database item" },
|
||||||
|
{
|
||||||
|
"<localleader>a",
|
||||||
|
"<Plug>(DBUI_AddConnection)",
|
||||||
|
ft = "dbui",
|
||||||
|
remap = true,
|
||||||
|
desc = "Add database connection",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>d",
|
||||||
|
"<Plug>(DBUI_DeleteLine)",
|
||||||
|
ft = "dbui",
|
||||||
|
remap = true,
|
||||||
|
desc = "Delete database item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>n",
|
||||||
|
"<Plug>(DBUI_RenameLine)",
|
||||||
|
ft = "dbui",
|
||||||
|
remap = true,
|
||||||
|
desc = "Rename database item",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>r",
|
||||||
|
"<Plug>(DBUI_Redraw)",
|
||||||
|
ft = "dbui",
|
||||||
|
remap = true,
|
||||||
|
desc = "Refresh database workspace",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>f",
|
||||||
|
"<Plug>(DBUI_JumpToForeignKey)",
|
||||||
|
ft = "dbout",
|
||||||
|
remap = true,
|
||||||
|
desc = "Follow foreign key",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>l",
|
||||||
|
"<Plug>(DBUI_ToggleResultLayout)",
|
||||||
|
ft = "dbout",
|
||||||
|
remap = true,
|
||||||
|
desc = "Toggle result layout",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
before = function()
|
||||||
|
vim.g.db_ui_execute_on_save = 0
|
||||||
|
vim.g.db_ui_tmp_query_location = vim.fn.stdpath("data") .. "/db_ui/working"
|
||||||
|
vim.g.db_ui_disable_mappings = 1
|
||||||
|
vim.g.db_ui_show_help = 0
|
||||||
|
vim.g.dbs = {
|
||||||
|
["MySQL — TEST"] = vim.env.YOOKR_MYSQL_TEST_DATABASE_URL,
|
||||||
|
["MySQL — LIVE"] = vim.env.YOOKR_MYSQL_LIVE_DATABASE_URL,
|
||||||
|
["MongoDB — TEST"] = vim.env.YOOKR_MONGODB_TEST_DATABASE_URL,
|
||||||
|
["MongoDB — LIVE"] = vim.env.YOOKR_MONGODB_LIVE_DATABASE_URL,
|
||||||
|
}
|
||||||
|
if vim.env.DATABASE_URL and vim.env.DATABASE_URL ~= "" then
|
||||||
|
vim.g.db = vim.env.DATABASE_URL
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
vim.diagnostic.config({
|
||||||
|
signs = {
|
||||||
|
text = {
|
||||||
|
[vim.diagnostic.severity.ERROR] = " ",
|
||||||
|
[vim.diagnostic.severity.WARN] = " ",
|
||||||
|
[vim.diagnostic.severity.INFO] = " ",
|
||||||
|
[vim.diagnostic.severity.HINT] = " ",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
severity_sort = true,
|
||||||
|
float = { source = "if_many" },
|
||||||
|
})
|
||||||
|
|
||||||
|
require("lz.n").load({
|
||||||
|
{
|
||||||
|
"trouble.nvim",
|
||||||
|
cmd = "Trouble",
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"<leader>dd",
|
||||||
|
"<cmd>Trouble diagnostics toggle<cr>",
|
||||||
|
desc = "Show workspace diagnostics",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>db",
|
||||||
|
"<cmd>Trouble diagnostics toggle filter.buf=0<cr>",
|
||||||
|
desc = "Show buffer diagnostics",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
after = function()
|
||||||
|
require("trouble").setup({})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
require("lz.n").load({
|
||||||
|
{
|
||||||
|
"mini.nvim",
|
||||||
|
event = "VimEnter",
|
||||||
|
after = function()
|
||||||
|
require("mini.ai").setup({ n_lines = 500 })
|
||||||
|
require("mini.surround").setup()
|
||||||
|
require("mini.pairs").setup()
|
||||||
|
|
||||||
|
local icons = require("mini.icons")
|
||||||
|
icons.setup()
|
||||||
|
icons.mock_nvim_web_devicons()
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"guess-indent.nvim",
|
||||||
|
event = { "BufReadPre", "BufNewFile" },
|
||||||
|
after = function()
|
||||||
|
require("guess-indent").setup({})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nvim-treesitter",
|
||||||
|
event = "FileType",
|
||||||
|
after = function()
|
||||||
|
require("nvim-treesitter").setup({})
|
||||||
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
|
group = vim.api.nvim_create_augroup("lux-treesitter", { clear = true }),
|
||||||
|
callback = function(args)
|
||||||
|
if vim.bo[args.buf].buftype ~= "" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if pcall(vim.treesitter.start, args.buf) then
|
||||||
|
vim.bo[args.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nvim-treesitter-textobjects",
|
||||||
|
event = "FileType",
|
||||||
|
after = function()
|
||||||
|
require("nvim-treesitter-textobjects").setup({
|
||||||
|
select = { lookahead = true },
|
||||||
|
})
|
||||||
|
|
||||||
|
local select = require("nvim-treesitter-textobjects.select")
|
||||||
|
local move = require("nvim-treesitter-textobjects.move")
|
||||||
|
local objects = {
|
||||||
|
{ "if", "@function.inner", "Select inner function" },
|
||||||
|
{ "af", "@function.outer", "Select outer function" },
|
||||||
|
{ "ic", "@class.inner", "Select inner class" },
|
||||||
|
{ "ac", "@class.outer", "Select outer class" },
|
||||||
|
{ "ia", "@parameter.inner", "Select inner parameter" },
|
||||||
|
{ "aa", "@parameter.outer", "Select outer parameter" },
|
||||||
|
{ "ii", "@conditional.inner", "Select inner conditional" },
|
||||||
|
{ "ai", "@conditional.outer", "Select outer conditional" },
|
||||||
|
{ "il", "@loop.inner", "Select inner loop" },
|
||||||
|
{ "al", "@loop.outer", "Select outer loop" },
|
||||||
|
{ "ib", "@block.inner", "Select inner block" },
|
||||||
|
{ "ab", "@block.outer", "Select outer block" },
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, object in ipairs(objects) do
|
||||||
|
vim.keymap.set({ "o", "x" }, object[1], function()
|
||||||
|
select.select_textobject(object[2], "textobjects")
|
||||||
|
end, { desc = object[3] })
|
||||||
|
end
|
||||||
|
|
||||||
|
local motions = {
|
||||||
|
{ "[f", move.goto_previous_start, "@function.outer", "Previous function" },
|
||||||
|
{ "]f", move.goto_next_start, "@function.outer", "Next function" },
|
||||||
|
{ "[c", move.goto_previous_start, "@class.outer", "Previous class" },
|
||||||
|
{ "]c", move.goto_next_start, "@class.outer", "Next class" },
|
||||||
|
{ "[a", move.goto_previous_start, "@parameter.inner", "Previous parameter" },
|
||||||
|
{ "]a", move.goto_next_start, "@parameter.inner", "Next parameter" },
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, motion in ipairs(motions) do
|
||||||
|
vim.keymap.set({ "n", "x", "o" }, motion[1], function()
|
||||||
|
motion[2](motion[3], "textobjects")
|
||||||
|
end, { desc = motion[4] })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rainbow-delimiters.nvim",
|
||||||
|
event = "FileType",
|
||||||
|
after = function()
|
||||||
|
require("rainbow-delimiters.setup").setup({})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nvim-ts-autotag",
|
||||||
|
ft = { "svelte", "astro", "html", "javascriptreact", "typescriptreact" },
|
||||||
|
after = function()
|
||||||
|
local enabled = { enable_close = true, enable_rename = true }
|
||||||
|
require("nvim-ts-autotag").setup({
|
||||||
|
opts = { enable_close = false, enable_rename = false },
|
||||||
|
per_filetype = {
|
||||||
|
svelte = enabled,
|
||||||
|
astro = enabled,
|
||||||
|
html = enabled,
|
||||||
|
javascriptreact = enabled,
|
||||||
|
typescriptreact = enabled,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"grug-far.nvim",
|
||||||
|
cmd = "GrugFar",
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"<leader>cR",
|
||||||
|
function()
|
||||||
|
require("grug-far").open({
|
||||||
|
prefills = {
|
||||||
|
search = vim.fn.expand("<cword>"),
|
||||||
|
paths = require("project").root(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
desc = "Replace across project",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>cR",
|
||||||
|
function()
|
||||||
|
require("grug-far").with_visual_selection({
|
||||||
|
prefills = { paths = require("project").root() },
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
mode = "x",
|
||||||
|
desc = "Replace selection across project",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -1,15 +1,22 @@
|
|||||||
local function format_options(bufnr)
|
local formatters_by_ft = {
|
||||||
local oxfmt = vim.lsp.get_clients({
|
lua = { "stylua" },
|
||||||
bufnr = bufnr,
|
nix = { "nixfmt" },
|
||||||
name = "oxfmt",
|
javascript = { "oxfmt" },
|
||||||
method = "textDocument/formatting",
|
javascriptreact = { "oxfmt" },
|
||||||
})[1]
|
typescript = { "oxfmt" },
|
||||||
|
typescriptreact = { "oxfmt" },
|
||||||
return {
|
json = { "oxfmt" },
|
||||||
lsp_format = "fallback",
|
jsonc = { "oxfmt" },
|
||||||
name = oxfmt and "oxfmt" or nil,
|
css = { "oxfmt" },
|
||||||
}
|
html = { "oxfmt" },
|
||||||
end
|
svelte = { "oxfmt" },
|
||||||
|
astro = { lsp_format = "fallback" },
|
||||||
|
python = { "ruff_fix", "ruff_format" },
|
||||||
|
rust = { "rustfmt" },
|
||||||
|
toml = { "taplo" },
|
||||||
|
yaml = { "yamlfmt" },
|
||||||
|
typst = { "typstyle" },
|
||||||
|
}
|
||||||
|
|
||||||
require("lz.n").load({
|
require("lz.n").load({
|
||||||
{
|
{
|
||||||
@@ -18,40 +25,22 @@ require("lz.n").load({
|
|||||||
cmd = "ConformInfo",
|
cmd = "ConformInfo",
|
||||||
keys = {
|
keys = {
|
||||||
{
|
{
|
||||||
"<leader>f",
|
"<leader>cf",
|
||||||
function()
|
function()
|
||||||
local options = format_options(vim.api.nvim_get_current_buf())
|
require("conform").format({ async = true })
|
||||||
options.async = true
|
|
||||||
require("conform").format(options)
|
|
||||||
end,
|
end,
|
||||||
mode = "",
|
mode = { "n", "x" },
|
||||||
desc = "[F]ormat buffer",
|
desc = "Format selection or buffer",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
after = function()
|
after = function()
|
||||||
require("conform").setup({
|
require("conform").setup({
|
||||||
notify_on_error = true,
|
formatters_by_ft = formatters_by_ft,
|
||||||
format_on_save = function(bufnr)
|
format_on_save = function(bufnr)
|
||||||
local disable_filetypes = { c = true, cpp = true }
|
if formatters_by_ft[vim.bo[bufnr].filetype] then
|
||||||
if disable_filetypes[vim.bo[bufnr].filetype] then
|
return { timeout_ms = 500 }
|
||||||
return nil
|
|
||||||
else
|
|
||||||
local options = format_options(bufnr)
|
|
||||||
options.timeout_ms = 500
|
|
||||||
return options
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
formatters_by_ft = {
|
|
||||||
lua = { "stylua" },
|
|
||||||
python = { "ruff_fix", "ruff_format", "ruff_organize_imports" },
|
|
||||||
toml = { "taplo" },
|
|
||||||
yaml = { "yamlfmt" },
|
|
||||||
},
|
|
||||||
formatters = {
|
|
||||||
stylua = {
|
|
||||||
prepend_args = { "--indent-type", "Spaces", "--indent-width", "2" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
require("lz.n").load({
|
||||||
|
{
|
||||||
|
"kulala.nvim",
|
||||||
|
ft = { "http", "rest" },
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"<localleader>r",
|
||||||
|
function()
|
||||||
|
require("kulala").run()
|
||||||
|
end,
|
||||||
|
mode = { "n", "x" },
|
||||||
|
ft = { "http", "rest" },
|
||||||
|
desc = "Execute HTTP request",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>a",
|
||||||
|
function()
|
||||||
|
require("kulala").run_all()
|
||||||
|
end,
|
||||||
|
ft = { "http", "rest" },
|
||||||
|
desc = "Execute all HTTP requests",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<localleader>e",
|
||||||
|
function()
|
||||||
|
require("kulala").set_selected_env()
|
||||||
|
end,
|
||||||
|
ft = { "http", "rest" },
|
||||||
|
desc = "Select HTTP environment",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>rr",
|
||||||
|
function()
|
||||||
|
require("kulala").scratchpad()
|
||||||
|
end,
|
||||||
|
desc = "Open HTTP scratchpad",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>rc",
|
||||||
|
function()
|
||||||
|
require("kulala").from_curl()
|
||||||
|
end,
|
||||||
|
desc = "Import cURL request",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>ro",
|
||||||
|
function()
|
||||||
|
require("kulala").open()
|
||||||
|
end,
|
||||||
|
desc = "Open HTTP request",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
after = function()
|
||||||
|
require("kulala").setup({
|
||||||
|
kulala_core = { path = require("nix-info").settings.kulalaCorePath },
|
||||||
|
treesitter = { enable = false },
|
||||||
|
session = { restore = false },
|
||||||
|
ui = { winbar = false },
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -1,20 +1,8 @@
|
|||||||
require("lz.n").load({
|
require("lz.n").load({
|
||||||
{
|
{ "nvim-navic" },
|
||||||
"typst-preview.nvim",
|
{ "SchemaStore.nvim" },
|
||||||
ft = "typst",
|
|
||||||
after = function()
|
|
||||||
-- Setup typst-preview
|
|
||||||
require("typst-preview").setup({
|
|
||||||
-- Optionally configure things here
|
|
||||||
dependencies_bin = require("nix-info").settings.typstPreviewDependencies,
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>tp", "<cmd>TypstPreviewToggle<cr>", { desc = "[T]ypst [P]review Toggle" })
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"lazydev.nvim",
|
"lazydev.nvim",
|
||||||
cmd = "LazyDev",
|
|
||||||
ft = "lua",
|
ft = "lua",
|
||||||
after = function()
|
after = function()
|
||||||
require("lazydev").setup({
|
require("lazydev").setup({
|
||||||
@@ -27,163 +15,90 @@ require("lz.n").load({
|
|||||||
{
|
{
|
||||||
"nvim-lspconfig",
|
"nvim-lspconfig",
|
||||||
event = { "BufReadPre", "BufNewFile" },
|
event = { "BufReadPre", "BufNewFile" },
|
||||||
before = function()
|
|
||||||
require("lz.n").trigger_load("lazydev.nvim")
|
|
||||||
end,
|
|
||||||
after = function()
|
after = function()
|
||||||
local telescope_plugins = {
|
local highlight_group = vim.api.nvim_create_augroup("lux-lsp-highlight", { clear = true })
|
||||||
"project.nvim",
|
|
||||||
"telescope.nvim",
|
|
||||||
"telescope-fzf-native.nvim",
|
|
||||||
"telescope-ui-select.nvim",
|
|
||||||
}
|
|
||||||
|
|
||||||
local telescope_picker = function(picker)
|
|
||||||
return function()
|
|
||||||
require("lz.n").trigger_load(telescope_plugins)
|
|
||||||
require("telescope.builtin")[picker]()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local lsp_float = { border = "single" }
|
|
||||||
|
|
||||||
local navic_excluded_filetypes = {
|
|
||||||
[""] = true,
|
|
||||||
help = true,
|
|
||||||
minifiles = true,
|
|
||||||
TelescopePrompt = true,
|
|
||||||
Trouble = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
local function navic_enabled(bufnr)
|
|
||||||
return vim.bo[bufnr].buftype == "" and not navic_excluded_filetypes[vim.bo[bufnr].filetype]
|
|
||||||
end
|
|
||||||
|
|
||||||
_G.lux_navic_location = function()
|
|
||||||
local ok, navic = pcall(require, "nvim-navic")
|
|
||||||
if not ok or not navic.is_available() then
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
|
|
||||||
return navic.get_location()
|
|
||||||
end
|
|
||||||
|
|
||||||
local function update_winbar(winid, bufnr)
|
|
||||||
if not vim.api.nvim_win_is_valid(winid) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local is_float = vim.api.nvim_win_get_config(winid).relative ~= ""
|
|
||||||
local winbar = ""
|
|
||||||
if not is_float and vim.b[bufnr].lux_navic_attached and navic_enabled(bufnr) then
|
|
||||||
winbar = "%{%v:lua.lux_navic_location()%}"
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_set_option_value("winbar", winbar, { win = winid })
|
|
||||||
end
|
|
||||||
|
|
||||||
local function update_winbars_for_buffer(bufnr)
|
|
||||||
for _, winid in ipairs(vim.fn.win_findbuf(bufnr)) do
|
|
||||||
update_winbar(winid, bufnr)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter", "WinEnter" }, {
|
|
||||||
group = vim.api.nvim_create_augroup("lux-navic-winbar", { clear = true }),
|
|
||||||
callback = function(args)
|
|
||||||
update_winbar(vim.api.nvim_get_current_win(), args.buf)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("LspAttach", {
|
vim.api.nvim_create_autocmd("LspAttach", {
|
||||||
group = vim.api.nvim_create_augroup("lux-lsp-attach", { clear = true }),
|
group = vim.api.nvim_create_augroup("lux-lsp-attach", { clear = true }),
|
||||||
callback = function(args)
|
callback = function(args)
|
||||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
|
||||||
local bufnr = args.buf
|
local bufnr = args.buf
|
||||||
|
local map = function(mode, lhs, rhs, desc)
|
||||||
local map = function(keys, func, desc, mode)
|
vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc })
|
||||||
mode = mode or "n"
|
|
||||||
vim.keymap.set(mode, keys, func, { buffer = bufnr, desc = "LSP: " .. desc })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
map("<leader>rn", vim.lsp.buf.rename, "[R]e[n]ame")
|
map("n", "gd", function()
|
||||||
map("<leader>ca", vim.lsp.buf.code_action, "[C]ode [A]ction", { "n", "x" })
|
require("telescope.builtin").lsp_definitions()
|
||||||
map("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration")
|
end, "Go to definition")
|
||||||
map("K", function()
|
map("n", "gD", vim.lsp.buf.declaration, "Go to declaration")
|
||||||
vim.lsp.buf.hover(lsp_float)
|
map("n", "gr", function()
|
||||||
end, "Hover Documentation")
|
require("telescope.builtin").lsp_references()
|
||||||
map("<C-s>", function()
|
end, "Find references")
|
||||||
vim.lsp.buf.signature_help(lsp_float)
|
map("n", "gI", function()
|
||||||
end, "Signature Help", { "i", "s" })
|
require("telescope.builtin").lsp_implementations()
|
||||||
|
end, "Go to implementation")
|
||||||
|
map("n", "gy", function()
|
||||||
|
require("telescope.builtin").lsp_type_definitions()
|
||||||
|
end, "Go to type definition")
|
||||||
|
map("n", "K", vim.lsp.buf.hover, "Show hover documentation")
|
||||||
|
map({ "n", "x" }, "<leader>ca", vim.lsp.buf.code_action, "Apply code action")
|
||||||
|
map("n", "<leader>cr", vim.lsp.buf.rename, "Rename symbol")
|
||||||
|
|
||||||
map("gd", telescope_picker("lsp_definitions"), "[G]oto [D]efinition")
|
if client:supports_method("textDocument/documentSymbol", bufnr) then
|
||||||
map("gr", telescope_picker("lsp_references"), "[G]oto [R]eferences")
|
map("n", "gO", function()
|
||||||
map("gI", telescope_picker("lsp_implementations"), "[G]oto [I]mplementation")
|
require("telescope.builtin").lsp_document_symbols()
|
||||||
map("<leader>D", telescope_picker("lsp_type_definitions"), "Type [D]efinition")
|
end, "Find document symbols")
|
||||||
map("<leader>ds", telescope_picker("lsp_document_symbols"), "[D]ocument [S]ymbols")
|
require("nvim-navic").attach(client, bufnr)
|
||||||
map("<leader>ws", telescope_picker("lsp_dynamic_workspace_symbols"), "[W]orkspace [S]ymbols")
|
end
|
||||||
|
|
||||||
if client and client:supports_method("textDocument/documentSymbol", bufnr) and navic_enabled(bufnr) then
|
if client:supports_method("textDocument/documentHighlight", bufnr) then
|
||||||
require("lz.n").trigger_load("nvim-navic")
|
local autocmds = vim.api.nvim_get_autocmds({ group = highlight_group, buffer = bufnr })
|
||||||
local ok, navic = pcall(require, "nvim-navic")
|
if #autocmds == 0 then
|
||||||
if ok then
|
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
|
||||||
navic.attach(client, bufnr)
|
group = highlight_group,
|
||||||
vim.b[bufnr].lux_navic_attached = true
|
buffer = bufnr,
|
||||||
update_winbars_for_buffer(bufnr)
|
callback = vim.lsp.buf.document_highlight,
|
||||||
|
})
|
||||||
|
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
|
||||||
|
group = highlight_group,
|
||||||
|
buffer = bufnr,
|
||||||
|
callback = vim.lsp.buf.clear_references,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if client and client:supports_method("textDocument/documentHighlight", bufnr) then
|
if client:supports_method("textDocument/inlayHint", bufnr) then
|
||||||
local highlight_augroup = vim.api.nvim_create_augroup("lux-lsp-highlight", { clear = false })
|
vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
|
||||||
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
|
map("n", "<leader>uh", function()
|
||||||
buffer = bufnr,
|
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }), { bufnr = bufnr })
|
||||||
group = highlight_augroup,
|
end, "Toggle inlay hints")
|
||||||
callback = vim.lsp.buf.document_highlight,
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
|
|
||||||
buffer = bufnr,
|
|
||||||
group = highlight_augroup,
|
|
||||||
callback = vim.lsp.buf.clear_references,
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("LspDetach", {
|
|
||||||
group = vim.api.nvim_create_augroup("lux-lsp-detach", { clear = true }),
|
|
||||||
callback = function(event)
|
|
||||||
vim.lsp.buf.clear_references()
|
|
||||||
vim.api.nvim_clear_autocmds({ group = "lux-lsp-highlight", buffer = event.buf })
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if client and client:supports_method("textDocument/inlayHint", bufnr) then
|
if client.name == "tinymist" then
|
||||||
vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
|
vim.api.nvim_buf_create_user_command(bufnr, "TinymistPreview", function()
|
||||||
map("<leader>th", function()
|
client:exec_cmd({ command = "tinymist.startDefaultPreview" }, { bufnr = bufnr })
|
||||||
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }))
|
end, { desc = "Start Tinymist preview", force = true })
|
||||||
end, "[T]oggle Inlay [H]ints")
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
vim.diagnostic.config({
|
vim.api.nvim_create_autocmd("LspDetach", {
|
||||||
severity_sort = true,
|
group = vim.api.nvim_create_augroup("lux-lsp-detach", { clear = true }),
|
||||||
underline = true,
|
callback = function(args)
|
||||||
signs = {
|
local supports_highlights = vim
|
||||||
text = {
|
.iter(vim.lsp.get_clients({
|
||||||
[vim.diagnostic.severity.ERROR] = " ",
|
bufnr = args.buf,
|
||||||
[vim.diagnostic.severity.WARN] = " ",
|
method = "textDocument/documentHighlight",
|
||||||
[vim.diagnostic.severity.INFO] = " ",
|
}))
|
||||||
[vim.diagnostic.severity.HINT] = " ",
|
:any(function(client)
|
||||||
},
|
return client.id ~= args.data.client_id
|
||||||
},
|
end)
|
||||||
virtual_text = false,
|
|
||||||
virtual_lines = {
|
if not supports_highlights then
|
||||||
current_line = true,
|
vim.lsp.buf.clear_references()
|
||||||
},
|
vim.api.nvim_clear_autocmds({ group = highlight_group, buffer = args.buf })
|
||||||
float = {
|
end
|
||||||
border = "single",
|
end,
|
||||||
source = "if_many",
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
vim.lsp.config("lua_ls", {
|
vim.lsp.config("lua_ls", {
|
||||||
@@ -197,10 +112,8 @@ require("lz.n").load({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
vim.lsp.enable("lua_ls")
|
|
||||||
|
|
||||||
local settings = require("nix-info").settings
|
local settings = require("nix-info").settings
|
||||||
|
|
||||||
vim.lsp.config("nixd", {
|
vim.lsp.config("nixd", {
|
||||||
settings = {
|
settings = {
|
||||||
nixd = {
|
nixd = {
|
||||||
@@ -209,64 +122,53 @@ require("lz.n").load({
|
|||||||
nixos = { expr = settings.nixdExtras.nixos_options },
|
nixos = { expr = settings.nixdExtras.nixos_options },
|
||||||
["home-manager"] = { expr = settings.nixdExtras.home_manager_options },
|
["home-manager"] = { expr = settings.nixdExtras.home_manager_options },
|
||||||
},
|
},
|
||||||
formatting = { command = { "nixfmt" } },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
vim.lsp.enable("nixd")
|
|
||||||
|
|
||||||
vim.lsp.enable("dafny")
|
vim.lsp.config("jsonls", {
|
||||||
vim.lsp.enable("jsonls")
|
settings = {
|
||||||
|
json = {
|
||||||
|
schemas = require("schemastore").json.schemas(),
|
||||||
|
validate = { enable = true },
|
||||||
|
format = { enable = false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.lsp.config("yamlls", {
|
||||||
|
settings = {
|
||||||
|
yaml = {
|
||||||
|
schemas = require("schemastore").yaml.schemas(),
|
||||||
|
schemaStore = { enable = false, url = "" },
|
||||||
|
format = { enable = false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
vim.lsp.config("vtsls", {
|
vim.lsp.config("vtsls", {
|
||||||
settings = {
|
settings = {
|
||||||
vtsls = {
|
vtsls = { autoUseWorkspaceTsdk = true },
|
||||||
autoUseWorkspaceTsdk = true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
vim.lsp.enable("vtsls")
|
|
||||||
|
|
||||||
vim.lsp.enable("cssls")
|
vim.lsp.enable({
|
||||||
vim.lsp.enable("html")
|
"lua_ls",
|
||||||
vim.lsp.enable("emmet_language_server")
|
"nixd",
|
||||||
vim.lsp.enable("oxlint")
|
"jsonls",
|
||||||
|
"yamlls",
|
||||||
vim.lsp.config("oxfmt", {
|
"vtsls",
|
||||||
filetypes = vim.list_extend({ "svelte" }, vim.lsp.config.oxfmt.filetypes),
|
"cssls",
|
||||||
})
|
"html",
|
||||||
vim.lsp.enable("oxfmt")
|
"emmet_language_server",
|
||||||
|
"oxlint",
|
||||||
vim.lsp.enable("tailwindcss")
|
"tailwindcss",
|
||||||
vim.lsp.enable("rust_analyzer")
|
"rust_analyzer",
|
||||||
vim.lsp.enable("ty")
|
"ty",
|
||||||
vim.lsp.enable("ruff")
|
"ruff",
|
||||||
vim.lsp.enable("astro")
|
"astro",
|
||||||
vim.lsp.enable("svelte")
|
"svelte",
|
||||||
|
"tinymist",
|
||||||
vim.lsp.config("tinymist", {
|
|
||||||
settings = {
|
|
||||||
tinymist = {
|
|
||||||
formatterMode = "typstyle",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
vim.lsp.enable("tinymist")
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"trouble.nvim",
|
|
||||||
cmd = "Trouble",
|
|
||||||
keys = {
|
|
||||||
{ "<leader>xx", "<cmd>Trouble diagnostics toggle<cr>", desc = "Diagnostics (Trouble)" },
|
|
||||||
{ "<leader>xX", "<cmd>Trouble diagnostics toggle filter.buf=0<cr>", desc = "Buffer Diagnostics (Trouble)" },
|
|
||||||
},
|
|
||||||
after = function()
|
|
||||||
require("trouble").setup({
|
|
||||||
focus = true,
|
|
||||||
preview = {
|
|
||||||
border = "single",
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
require("oil").setup({})
|
||||||
|
vim.keymap.set("n", "<leader>e", function()
|
||||||
|
local name = vim.api.nvim_buf_get_name(0)
|
||||||
|
require("oil").open(name == "" and vim.fn.getcwd() or vim.fs.dirname(name))
|
||||||
|
end, { desc = "Open file directory" })
|
||||||
|
|
||||||
|
require("lz.n").load({
|
||||||
|
{ "plenary.nvim" },
|
||||||
|
{ "telescope-fzf-native.nvim" },
|
||||||
|
{ "telescope-ui-select.nvim" },
|
||||||
|
{
|
||||||
|
"telescope.nvim",
|
||||||
|
event = "VimEnter",
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"<leader>sf",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").find_files({ cwd = require("project").root() })
|
||||||
|
end,
|
||||||
|
desc = "Find project files",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sg",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").live_grep({ cwd = require("project").root() })
|
||||||
|
end,
|
||||||
|
desc = "Search project text",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sw",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").grep_string({ cwd = require("project").root() })
|
||||||
|
end,
|
||||||
|
desc = "Search cursor word",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sb",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").current_buffer_fuzzy_find()
|
||||||
|
end,
|
||||||
|
desc = "Search current buffer",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>so",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").oldfiles()
|
||||||
|
end,
|
||||||
|
desc = "Find recent files",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>ss",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").lsp_dynamic_workspace_symbols()
|
||||||
|
end,
|
||||||
|
desc = "Find workspace symbols",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sd",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").diagnostics()
|
||||||
|
end,
|
||||||
|
desc = "Find diagnostics",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sh",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").help_tags()
|
||||||
|
end,
|
||||||
|
desc = "Find help",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sc",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").commands()
|
||||||
|
end,
|
||||||
|
desc = "Find commands",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sk",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").keymaps()
|
||||||
|
end,
|
||||||
|
desc = "Find keymaps",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>sr",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").resume()
|
||||||
|
end,
|
||||||
|
desc = "Resume last search",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>bb",
|
||||||
|
function()
|
||||||
|
require("telescope.builtin").buffers()
|
||||||
|
end,
|
||||||
|
desc = "Find open buffers",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
after = function()
|
||||||
|
local actions = require("telescope.actions")
|
||||||
|
local promote = function(prompt_bufnr)
|
||||||
|
actions.smart_send_to_qflist(prompt_bufnr)
|
||||||
|
vim.cmd("Trouble qflist open")
|
||||||
|
end
|
||||||
|
local picker_mappings = {
|
||||||
|
["<C-j>"] = actions.move_selection_next,
|
||||||
|
["<C-k>"] = actions.move_selection_previous,
|
||||||
|
["<C-q>"] = promote,
|
||||||
|
}
|
||||||
|
|
||||||
|
require("telescope").setup({
|
||||||
|
defaults = {
|
||||||
|
mappings = { i = picker_mappings, n = picker_mappings },
|
||||||
|
},
|
||||||
|
extensions = {
|
||||||
|
["ui-select"] = require("telescope.themes").get_dropdown(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
require("telescope").load_extension("fzf")
|
||||||
|
require("telescope").load_extension("ui-select")
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
require("lz.n").load({
|
||||||
|
{
|
||||||
|
"zk-nvim",
|
||||||
|
cmd = { "ZkNew", "ZkNotes", "ZkTags", "ZkInsertLink", "ZkBacklinks", "ZkLinks" },
|
||||||
|
ft = "markdown",
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"<leader>nn",
|
||||||
|
function()
|
||||||
|
local title = vim.trim(vim.fn.input("Title: "))
|
||||||
|
if title ~= "" then
|
||||||
|
require("zk").new({ notebook_path = vim.env.ZK_NOTEBOOK_DIR, title = title })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
desc = "Create note",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>nf",
|
||||||
|
function()
|
||||||
|
require("zk").edit({ notebook_path = vim.env.ZK_NOTEBOOK_DIR }, { picker = "telescope" })
|
||||||
|
end,
|
||||||
|
desc = "Find notes",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"<leader>nt",
|
||||||
|
function()
|
||||||
|
require("zk.commands").get("ZkTags")({ notebook_path = vim.env.ZK_NOTEBOOK_DIR })
|
||||||
|
end,
|
||||||
|
desc = "Find note tags",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
after = function()
|
||||||
|
require("zk").setup({
|
||||||
|
picker = "telescope",
|
||||||
|
lsp = { config = { root_dir = vim.env.ZK_NOTEBOOK_DIR } },
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
|
group = vim.api.nvim_create_augroup("lux-notes-maps", { clear = true }),
|
||||||
|
pattern = "markdown",
|
||||||
|
callback = function(args)
|
||||||
|
local path = vim.api.nvim_buf_get_name(args.buf)
|
||||||
|
if require("zk.util").notebook_root(path) then
|
||||||
|
vim.keymap.set("n", "<leader>ni", "<cmd>ZkInsertLink<cr>", {
|
||||||
|
buffer = args.buf,
|
||||||
|
desc = "Insert note link",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
local telescope_plugins = {
|
|
||||||
"project.nvim",
|
|
||||||
"telescope.nvim",
|
|
||||||
"telescope-fzf-native.nvim",
|
|
||||||
"telescope-ui-select.nvim",
|
|
||||||
}
|
|
||||||
|
|
||||||
local function load_telescope()
|
|
||||||
require("lz.n").trigger_load(telescope_plugins)
|
|
||||||
return require("telescope.builtin")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function map_picker(lhs, picker, desc, opts)
|
|
||||||
vim.keymap.set("n", lhs, function()
|
|
||||||
load_telescope()[picker](opts or {})
|
|
||||||
end, { desc = desc })
|
|
||||||
end
|
|
||||||
|
|
||||||
map_picker("<leader>sh", "help_tags", "[S]earch [H]elp")
|
|
||||||
map_picker("<leader>sk", "keymaps", "[S]earch [K]eymaps")
|
|
||||||
map_picker("<leader>sf", "find_files", "[S]earch [F]iles")
|
|
||||||
map_picker("<leader>ss", "builtin", "[S]earch [S]elect Telescope")
|
|
||||||
map_picker("<leader>sw", "grep_string", "[S]earch current [W]ord")
|
|
||||||
map_picker("<leader>sg", "live_grep", "[S]earch by [G]rep")
|
|
||||||
map_picker("<leader>sd", "diagnostics", "[S]earch [D]iagnostics")
|
|
||||||
map_picker("<leader>sr", "resume", "[S]earch [R]esume")
|
|
||||||
map_picker("<leader>s.", "oldfiles", '[S]earch Recent Files ("." for repeat)')
|
|
||||||
map_picker("<leader><leader>", "buffers", "[ ] Find existing buffers")
|
|
||||||
map_picker("<leader>sn", "find_files", "[S]earch [N]eovim files", { cwd = vim.fn.stdpath("config") })
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>sp", function()
|
|
||||||
load_telescope()
|
|
||||||
require("telescope").extensions.projects.projects({})
|
|
||||||
end, { desc = "[S]earch [P]rojects" })
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>/", function()
|
|
||||||
local builtin = load_telescope()
|
|
||||||
builtin.current_buffer_fuzzy_find(require("telescope.themes").get_dropdown({
|
|
||||||
winblend = 10,
|
|
||||||
previewer = false,
|
|
||||||
}))
|
|
||||||
end, { desc = "[/] Fuzzily search in current buffer" })
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>s/", function()
|
|
||||||
load_telescope().live_grep({
|
|
||||||
grep_open_files = true,
|
|
||||||
prompt_title = "Live Grep in Open Files",
|
|
||||||
})
|
|
||||||
end, { desc = "[S]earch [/] in Open Files" })
|
|
||||||
|
|
||||||
require("lz.n").load({
|
|
||||||
{
|
|
||||||
"project.nvim",
|
|
||||||
event = "VimEnter",
|
|
||||||
after = function()
|
|
||||||
require("project").setup({
|
|
||||||
manual_mode = false,
|
|
||||||
lsp = { enabled = true },
|
|
||||||
patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "flake.nix" },
|
|
||||||
show_hidden = true,
|
|
||||||
scope_chdir = "global",
|
|
||||||
})
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"telescope-fzf-native.nvim",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"telescope-ui-select.nvim",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"telescope.nvim",
|
|
||||||
cmd = "Telescope",
|
|
||||||
before = function()
|
|
||||||
require("lz.n").trigger_load("project.nvim")
|
|
||||||
end,
|
|
||||||
after = function()
|
|
||||||
local actions = require("telescope.actions")
|
|
||||||
|
|
||||||
require("telescope").setup({
|
|
||||||
defaults = {
|
|
||||||
path_display = { "truncate" },
|
|
||||||
border = true,
|
|
||||||
borderchars = { "─", "│", "─", "│", "┌", "┐", "┘", "└" },
|
|
||||||
layout_strategy = "horizontal",
|
|
||||||
layout_config = {
|
|
||||||
prompt_position = "top",
|
|
||||||
},
|
|
||||||
sorting_strategy = "ascending",
|
|
||||||
mappings = {
|
|
||||||
i = {
|
|
||||||
["<C-k>"] = actions.move_selection_previous,
|
|
||||||
["<C-j>"] = actions.move_selection_next,
|
|
||||||
["<C-q>"] = actions.send_selected_to_qflist + actions.open_qflist,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extensions = {
|
|
||||||
["ui-select"] = {
|
|
||||||
require("telescope.themes").get_dropdown(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
require("lz.n").trigger_load({ "telescope-fzf-native.nvim", "telescope-ui-select.nvim" })
|
|
||||||
pcall(require("telescope").load_extension, "projects")
|
|
||||||
pcall(require("telescope").load_extension, "fzf")
|
|
||||||
pcall(require("telescope").load_extension, "ui-select")
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
local ok, treesitter = pcall(require, "nvim-treesitter")
|
|
||||||
|
|
||||||
if not ok then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
treesitter.setup({})
|
|
||||||
|
|
||||||
local group = vim.api.nvim_create_augroup("lux-treesitter", { clear = true })
|
|
||||||
local enableTreesitter = function(bufnr)
|
|
||||||
vim.schedule(function()
|
|
||||||
if not vim.api.nvim_buf_is_valid(bufnr) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if pcall(vim.treesitter.start, bufnr) then
|
|
||||||
vim.bo[bufnr].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter", "FileType" }, {
|
|
||||||
group = group,
|
|
||||||
pattern = "*",
|
|
||||||
callback = function(args)
|
|
||||||
enableTreesitter(args.buf)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
@@ -1,67 +1,50 @@
|
|||||||
require("lz.n").load({
|
require("lz.n").load({
|
||||||
{
|
|
||||||
"theme-loader",
|
|
||||||
event = "VimEnter",
|
|
||||||
load = function()
|
|
||||||
local settings = require("nix-info").settings
|
|
||||||
local theme_code = settings.themeSetup
|
|
||||||
|
|
||||||
local func, err = loadstring(theme_code)
|
|
||||||
if func then
|
|
||||||
func()
|
|
||||||
else
|
|
||||||
print("Error loading theme code: " .. err)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"kulala.nvim",
|
|
||||||
after = function()
|
|
||||||
require("kulala").setup({
|
|
||||||
global_keymaps = true,
|
|
||||||
global_keymaps_prefix = "<leader>R",
|
|
||||||
})
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"lualine.nvim",
|
"lualine.nvim",
|
||||||
event = "VimEnter",
|
event = "VimEnter",
|
||||||
after = function()
|
after = function()
|
||||||
local filename = {
|
local navic = require("nvim-navic")
|
||||||
"filename",
|
local breadcrumb = function()
|
||||||
path = 1,
|
if not navic.is_available() then
|
||||||
symbols = {
|
return ""
|
||||||
modified = "●",
|
end
|
||||||
readonly = "",
|
|
||||||
unnamed = "[No Name]",
|
local location = navic.get_location()
|
||||||
},
|
if vim.fn.strdisplaywidth(location) <= 60 then
|
||||||
}
|
return location
|
||||||
|
end
|
||||||
|
|
||||||
|
while vim.fn.strdisplaywidth(location) > 59 do
|
||||||
|
location = vim.fn.strcharpart(location, 0, vim.fn.strchars(location) - 1)
|
||||||
|
end
|
||||||
|
return location .. "…"
|
||||||
|
end
|
||||||
|
|
||||||
require("lualine").setup({
|
require("lualine").setup({
|
||||||
options = {
|
options = {
|
||||||
icons_enabled = true,
|
theme = "auto",
|
||||||
globalstatus = false,
|
|
||||||
component_separators = "",
|
component_separators = "",
|
||||||
section_separators = "",
|
section_separators = "",
|
||||||
theme = "kanagawa",
|
globalstatus = true,
|
||||||
},
|
},
|
||||||
sections = {
|
sections = {
|
||||||
lualine_a = { "mode" },
|
lualine_a = { "mode" },
|
||||||
lualine_b = { "branch", "diff", "diagnostics" },
|
lualine_b = { "branch" },
|
||||||
lualine_c = { filename },
|
lualine_c = { { "filename", path = 1 }, breadcrumb },
|
||||||
|
lualine_x = {
|
||||||
lualine_x = { "lsp_status" },
|
{ "kulala", icon = "HTTP" },
|
||||||
lualine_y = { "progress" },
|
{
|
||||||
|
"db_ui#statusline",
|
||||||
|
type = "vim_fun",
|
||||||
|
cond = function()
|
||||||
|
return vim.fn.exists("*db_ui#statusline") == 1
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
"diagnostics",
|
||||||
|
},
|
||||||
|
lualine_y = { "filetype" },
|
||||||
lualine_z = { "location" },
|
lualine_z = { "location" },
|
||||||
},
|
},
|
||||||
inactive_sections = {
|
|
||||||
lualine_a = {},
|
|
||||||
lualine_b = {},
|
|
||||||
lualine_c = { filename },
|
|
||||||
lualine_x = {},
|
|
||||||
lualine_y = {},
|
|
||||||
lualine_z = {},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
@@ -75,88 +58,82 @@ require("lz.n").load({
|
|||||||
change = { text = "│" },
|
change = { text = "│" },
|
||||||
delete = { text = "_" },
|
delete = { text = "_" },
|
||||||
topdelete = { text = "‾" },
|
topdelete = { text = "‾" },
|
||||||
changedelete = { text = "~" },
|
|
||||||
untracked = { text = "┆" },
|
|
||||||
},
|
},
|
||||||
signs_staged_enable = true,
|
|
||||||
on_attach = function(bufnr)
|
on_attach = function(bufnr)
|
||||||
local gs = package.loaded.gitsigns
|
local gs = require("gitsigns")
|
||||||
local map = function(mode, lhs, rhs, desc, opts)
|
local map_hunk = function(lhs, direction, desc)
|
||||||
opts = opts or {}
|
vim.keymap.set("n", lhs, function()
|
||||||
opts.buffer = bufnr
|
if vim.wo.diff then
|
||||||
opts.desc = desc
|
return lhs
|
||||||
vim.keymap.set(mode, lhs, rhs, opts)
|
end
|
||||||
|
vim.schedule(function()
|
||||||
|
gs.nav_hunk(direction)
|
||||||
|
end)
|
||||||
|
return "<Ignore>"
|
||||||
|
end, { buffer = bufnr, desc = desc, expr = true })
|
||||||
end
|
end
|
||||||
|
map_hunk("]h", "next", "Next git hunk")
|
||||||
map("n", "]h", function()
|
map_hunk("[h", "prev", "Previous git hunk")
|
||||||
if vim.wo.diff then
|
vim.keymap.set("n", "<leader>gp", gs.preview_hunk, { buffer = bufnr, desc = "Preview git hunk" })
|
||||||
return "]h"
|
vim.keymap.set("n", "<leader>gs", gs.stage_hunk, { buffer = bufnr, desc = "Stage git hunk" })
|
||||||
end
|
|
||||||
vim.schedule(function()
|
|
||||||
gs.nav_hunk("next")
|
|
||||||
end)
|
|
||||||
return "<Ignore>"
|
|
||||||
end, "Next git hunk", { expr = true })
|
|
||||||
|
|
||||||
map("n", "[h", function()
|
|
||||||
if vim.wo.diff then
|
|
||||||
return "[h"
|
|
||||||
end
|
|
||||||
vim.schedule(function()
|
|
||||||
gs.nav_hunk("prev")
|
|
||||||
end)
|
|
||||||
return "<Ignore>"
|
|
||||||
end, "Previous git hunk", { expr = true })
|
|
||||||
|
|
||||||
map("n", "<leader>hp", gs.preview_hunk, "Git [H]unk [P]review")
|
|
||||||
map("n", "<leader>hs", gs.stage_hunk, "Git [H]unk [S]tage")
|
|
||||||
map("n", "<leader>hr", gs.reset_hunk, "Git [H]unk [R]eset")
|
|
||||||
map("n", "<leader>hu", gs.undo_stage_hunk, "Git [H]unk [U]ndo stage")
|
|
||||||
map("n", "<leader>hS", gs.stage_buffer, "Git [H]unk [S]tage buffer")
|
|
||||||
map("n", "<leader>hR", gs.reset_buffer, "Git [H]unk [R]eset buffer")
|
|
||||||
map("v", "<leader>hs", function()
|
|
||||||
gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") })
|
|
||||||
end, "Git [H]unk [S]tage")
|
|
||||||
map("v", "<leader>hr", function()
|
|
||||||
gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") })
|
|
||||||
end, "Git [H]unk [R]eset")
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"diffview.nvim",
|
||||||
|
cmd = { "DiffviewOpen", "DiffviewClose", "DiffviewRefresh", "DiffviewFileHistory" },
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"<leader>gd",
|
||||||
|
function()
|
||||||
|
vim.cmd("DiffviewOpen -C" .. vim.fn.fnameescape(require("project").root()))
|
||||||
|
end,
|
||||||
|
desc = "Review project changes",
|
||||||
|
},
|
||||||
|
{ "<leader>gq", "<cmd>DiffviewClose<cr>", desc = "Close git review" },
|
||||||
|
{ "<leader>gr", "<cmd>DiffviewRefresh<cr>", desc = "Refresh git review" },
|
||||||
|
},
|
||||||
|
after = function()
|
||||||
|
require("diffview").setup({})
|
||||||
|
end,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"zen-mode.nvim",
|
"zen-mode.nvim",
|
||||||
cmd = "ZenMode",
|
cmd = "ZenMode",
|
||||||
|
keys = {
|
||||||
|
{ "<leader>uz", "<cmd>ZenMode<cr>", desc = "Toggle zen mode" },
|
||||||
|
},
|
||||||
after = function()
|
after = function()
|
||||||
require("zen-mode").setup({
|
require("zen-mode").setup({})
|
||||||
window = {
|
end,
|
||||||
options = {
|
},
|
||||||
linebreak = true,
|
{
|
||||||
},
|
"render-markdown.nvim",
|
||||||
},
|
ft = "markdown",
|
||||||
})
|
keys = {
|
||||||
|
{ "<leader>um", "<cmd>RenderMarkdown buf_toggle<cr>", desc = "Toggle Markdown rendering" },
|
||||||
|
},
|
||||||
|
after = function()
|
||||||
|
require("render-markdown").setup({})
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"which-key.nvim",
|
"which-key.nvim",
|
||||||
event = "VimEnter",
|
event = "VimEnter",
|
||||||
before = function()
|
|
||||||
require("lz.n").trigger_load("mini.nvim")
|
|
||||||
end,
|
|
||||||
after = function()
|
after = function()
|
||||||
require("which-key").setup({
|
require("which-key").setup({
|
||||||
preset = "modern",
|
preset = "helix",
|
||||||
delay = 200,
|
|
||||||
icons = {
|
|
||||||
mappings = true,
|
|
||||||
keys = {},
|
|
||||||
},
|
|
||||||
|
|
||||||
spec = {
|
spec = {
|
||||||
{ "<leader>b", group = "[B]uffer" },
|
{ "<leader>b", group = "Buffers" },
|
||||||
{ "<leader>s", group = "[S]earch" },
|
{ "<leader>c", group = "Code" },
|
||||||
{ "<leader>t", group = "[T]oggle" },
|
{ "<leader>d", group = "Diagnostics" },
|
||||||
{ "<leader>h", group = "Git [H]unk", mode = { "n", "v" } },
|
{ "<leader>g", group = "Git" },
|
||||||
|
{ "<leader>n", group = "Notes" },
|
||||||
|
{ "<leader>q", group = "Database" },
|
||||||
|
{ "<leader>r", group = "HTTP" },
|
||||||
|
{ "<leader>s", group = "Search" },
|
||||||
|
{ "<leader>u", group = "UI" },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
function M.root()
|
||||||
|
return vim.fs.root(0, { ".git" }) or vim.fn.getcwd()
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"Full lux module": {
|
||||||
|
"prefix": "luxmod",
|
||||||
|
"description": "Full lux module (NixOS and Home Manager)",
|
||||||
|
"body": [
|
||||||
|
"{ inputs, ... }:",
|
||||||
|
"{",
|
||||||
|
" lux.${1:moduleName} = {",
|
||||||
|
" nixos = { config, lib, pkgs, ... }: {",
|
||||||
|
" $2",
|
||||||
|
" };",
|
||||||
|
"",
|
||||||
|
" homeManager = { config, lib, pkgs, ... }: {",
|
||||||
|
" $3",
|
||||||
|
" };",
|
||||||
|
" };",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Lux NixOS module": {
|
||||||
|
"prefix": "luxnixos",
|
||||||
|
"description": "Lux NixOS-only module",
|
||||||
|
"body": [
|
||||||
|
"{ inputs, ... }:",
|
||||||
|
"{",
|
||||||
|
" lux.${1:moduleName}.nixos = { config, lib, pkgs, ... }: {",
|
||||||
|
" $0",
|
||||||
|
" };",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Lux Home Manager module": {
|
||||||
|
"prefix": "luxhm",
|
||||||
|
"description": "Lux Home Manager-only module",
|
||||||
|
"body": [
|
||||||
|
"{ inputs, ... }:",
|
||||||
|
"{",
|
||||||
|
" lux.${1:moduleName}.homeManager = { config, lib, pkgs, ... }: {",
|
||||||
|
" $0",
|
||||||
|
" };",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Den inline aspect": {
|
||||||
|
"prefix": "denaspect",
|
||||||
|
"description": "Den inline aspect",
|
||||||
|
"body": [
|
||||||
|
"(",
|
||||||
|
" { host, user, ... }: {",
|
||||||
|
" $0",
|
||||||
|
" }",
|
||||||
|
")"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
local ls = require("luasnip")
|
|
||||||
local s = ls.snippet
|
|
||||||
local t = ls.text_node
|
|
||||||
local i = ls.insert_node
|
|
||||||
|
|
||||||
return {
|
|
||||||
-- Full lux module (both nixos and homeManager)
|
|
||||||
s("luxmod", {
|
|
||||||
t({
|
|
||||||
"{ inputs, ... }:",
|
|
||||||
"{",
|
|
||||||
" lux."
|
|
||||||
}),
|
|
||||||
i(1, "moduleName"),
|
|
||||||
t({
|
|
||||||
" = {",
|
|
||||||
" nixos = { config, lib, pkgs, ... }: {",
|
|
||||||
" "
|
|
||||||
}),
|
|
||||||
i(2),
|
|
||||||
t({
|
|
||||||
"",
|
|
||||||
" };",
|
|
||||||
"",
|
|
||||||
" homeManager = { config, lib, pkgs, ... }: {",
|
|
||||||
" "
|
|
||||||
}),
|
|
||||||
i(3),
|
|
||||||
t({
|
|
||||||
"",
|
|
||||||
" };",
|
|
||||||
" };",
|
|
||||||
"}",
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
|
|
||||||
-- lux nixos only module
|
|
||||||
s("luxnixos", {
|
|
||||||
t({
|
|
||||||
"{ inputs, ... }:",
|
|
||||||
"{",
|
|
||||||
" lux."
|
|
||||||
}),
|
|
||||||
i(1, "moduleName"),
|
|
||||||
t({
|
|
||||||
".nixos = { config, lib, pkgs, ... }: {",
|
|
||||||
" "
|
|
||||||
}),
|
|
||||||
i(0),
|
|
||||||
t({
|
|
||||||
"",
|
|
||||||
" };",
|
|
||||||
"}",
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
|
|
||||||
-- lux homeManager only module
|
|
||||||
s("luxhm", {
|
|
||||||
t({
|
|
||||||
"{ inputs, ... }:",
|
|
||||||
"{",
|
|
||||||
" lux."
|
|
||||||
}),
|
|
||||||
i(1, "moduleName"),
|
|
||||||
t({
|
|
||||||
".homeManager = { config, lib, pkgs, ... }: {",
|
|
||||||
" "
|
|
||||||
}),
|
|
||||||
i(0),
|
|
||||||
t({
|
|
||||||
"",
|
|
||||||
" };",
|
|
||||||
"}",
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
|
|
||||||
-- den inline aspect
|
|
||||||
s("denaspect", {
|
|
||||||
t({
|
|
||||||
"(",
|
|
||||||
" { host, user, ... }: {",
|
|
||||||
" "
|
|
||||||
}),
|
|
||||||
i(0),
|
|
||||||
t({
|
|
||||||
"",
|
|
||||||
" }",
|
|
||||||
")"
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "lux-nix-snippets",
|
||||||
|
"contributes": {
|
||||||
|
"snippets": [
|
||||||
|
{
|
||||||
|
"language": "nix",
|
||||||
|
"path": "./nix.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,10 +11,12 @@ in
|
|||||||
networking.networkmanager.enable = true;
|
networking.networkmanager.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.openvpn = {
|
flake.modules.nixos.openvpn =
|
||||||
programs.openvpn3.enable = true;
|
{ pkgs, ... }:
|
||||||
services.resolved.enable = true;
|
{
|
||||||
};
|
networking.networkmanager.plugins = [ pkgs.networkmanager-openvpn ];
|
||||||
|
services.resolved.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
flake.modules.nixos.server-firewall =
|
flake.modules.nixos.server-firewall =
|
||||||
{ ... }:
|
{ ... }:
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
{
|
{
|
||||||
browser,
|
browser,
|
||||||
|
handy,
|
||||||
launcher,
|
launcher,
|
||||||
shortcutCommands,
|
swapMonitorWorkspaces,
|
||||||
terminal,
|
terminal,
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
spawnLocked = command: {
|
||||||
|
spawn-sh = command;
|
||||||
|
_props.allow-when-locked = true;
|
||||||
|
};
|
||||||
|
withCooldown = action: {
|
||||||
|
${action} = { };
|
||||||
|
_props.cooldown-ms = 150;
|
||||||
|
};
|
||||||
|
in
|
||||||
{
|
{
|
||||||
# Application and utility launchers
|
# Application and utility launchers
|
||||||
"Mod+Return" = {
|
"Mod+Return" = {
|
||||||
@@ -14,81 +25,54 @@
|
|||||||
spawn = browser;
|
spawn = browser;
|
||||||
_props.hotkey-overlay-title = "Browser";
|
_props.hotkey-overlay-title = "Browser";
|
||||||
};
|
};
|
||||||
|
"Mod+N" = {
|
||||||
|
spawn-sh = "open-daily-note";
|
||||||
|
_props.hotkey-overlay-title = "Daily Note";
|
||||||
|
};
|
||||||
"Mod+Space" = {
|
"Mod+Space" = {
|
||||||
_props.repeat = false;
|
_props.repeat = false;
|
||||||
spawn = launcher;
|
spawn = launcher;
|
||||||
_props.hotkey-overlay-title = "App Launcher";
|
_props.hotkey-overlay-title = "App Launcher";
|
||||||
};
|
};
|
||||||
"Mod+Ctrl+Return" = {
|
|
||||||
|
# Dictation
|
||||||
|
"Mod+D" = {
|
||||||
|
spawn = [
|
||||||
|
"systemctl"
|
||||||
|
"--user"
|
||||||
|
"start"
|
||||||
|
"handy-ptt.service"
|
||||||
|
];
|
||||||
_props.repeat = false;
|
_props.repeat = false;
|
||||||
spawn = shortcutCommands.nixosTerminal;
|
_props.hotkey-overlay-title = "Hold to Dictate";
|
||||||
_props.hotkey-overlay-title = "NixOS Config Terminal";
|
|
||||||
};
|
};
|
||||||
"Mod+Ctrl+Shift+Return" = {
|
"Mod+Shift+D" = {
|
||||||
|
spawn-sh = "systemctl --user stop handy-ptt.service && ${handy} --toggle-transcription";
|
||||||
_props.repeat = false;
|
_props.repeat = false;
|
||||||
spawn = shortcutCommands.nixosSwitch;
|
_props.hotkey-overlay-title = "Toggle Dictation";
|
||||||
_props.hotkey-overlay-title = "NixOS Switch";
|
|
||||||
};
|
};
|
||||||
"Mod+Ctrl+E" = {
|
"Mod+Ctrl+D" = {
|
||||||
|
spawn-sh = "systemctl --user stop handy-ptt.service && ${handy} --cancel";
|
||||||
_props.repeat = false;
|
_props.repeat = false;
|
||||||
spawn = shortcutCommands.editSecrets;
|
_props.hotkey-overlay-title = "Cancel Dictation";
|
||||||
_props.hotkey-overlay-title = "Edit Secrets";
|
|
||||||
};
|
|
||||||
"Mod+Ctrl+C" = {
|
|
||||||
_props.repeat = false;
|
|
||||||
spawn = shortcutCommands.pickColor;
|
|
||||||
_props.hotkey-overlay-title = "Pick Color";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Hardware media, volume, and brightness keys
|
# Hardware media, volume, and brightness keys
|
||||||
"XF86AudioPlay" = {
|
"XF86AudioPlay" = spawnLocked "playerctl play-pause";
|
||||||
spawn-sh = "playerctl play-pause";
|
"XF86AudioStop" = spawnLocked "playerctl stop";
|
||||||
_props.allow-when-locked = true;
|
"XF86AudioPrev" = spawnLocked "playerctl previous";
|
||||||
};
|
"XF86AudioNext" = spawnLocked "playerctl next";
|
||||||
"XF86AudioStop" = {
|
"XF86AudioRaiseVolume" = spawnLocked "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+";
|
||||||
spawn-sh = "playerctl stop";
|
"XF86AudioLowerVolume" = spawnLocked "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
|
||||||
_props.allow-when-locked = true;
|
"XF86AudioMute" = spawnLocked "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
|
||||||
};
|
"XF86AudioMicMute" = spawnLocked "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
|
||||||
"XF86AudioPrev" = {
|
"XF86MonBrightnessUp" = spawnLocked "brightnessctl s 5%+";
|
||||||
spawn-sh = "playerctl previous";
|
"XF86MonBrightnessDown" = spawnLocked "brightnessctl s 5%-";
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioNext" = {
|
|
||||||
spawn-sh = "playerctl next";
|
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioRaiseVolume" = {
|
|
||||||
spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+";
|
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioLowerVolume" = {
|
|
||||||
spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
|
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioMute" = {
|
|
||||||
spawn-sh = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
|
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioMicMute" = {
|
|
||||||
spawn-sh = "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
|
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86MonBrightnessUp" = {
|
|
||||||
spawn-sh = "brightnessctl s 5%+";
|
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86MonBrightnessDown" = {
|
|
||||||
spawn-sh = "brightnessctl s 5%-";
|
|
||||||
_props.allow-when-locked = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Screenshots
|
# Screenshots
|
||||||
"Mod+S".screenshot = { };
|
"Mod+S".screenshot = { };
|
||||||
"Mod+Ctrl+S".screenshot-screen = { };
|
|
||||||
"Mod+Alt+S".screenshot-window = { };
|
|
||||||
|
|
||||||
# Session and compositor controls
|
# Session and compositor controls
|
||||||
"Mod+Shift+Slash".show-hotkey-overlay = { };
|
|
||||||
"Mod+Escape" = {
|
"Mod+Escape" = {
|
||||||
toggle-keyboard-shortcuts-inhibit = { };
|
toggle-keyboard-shortcuts-inhibit = { };
|
||||||
_props.allow-inhibiting = false;
|
_props.allow-inhibiting = false;
|
||||||
@@ -97,9 +81,6 @@
|
|||||||
spawn-sh = "loginctl lock-session";
|
spawn-sh = "loginctl lock-session";
|
||||||
_props.hotkey-overlay-title = "Lock Screen";
|
_props.hotkey-overlay-title = "Lock Screen";
|
||||||
};
|
};
|
||||||
"Mod+Ctrl+Shift+Q".quit = { };
|
|
||||||
"Ctrl+Alt+Delete".quit = { };
|
|
||||||
"Mod+Shift+P".power-off-monitors = { };
|
|
||||||
|
|
||||||
# Overview and window close
|
# Overview and window close
|
||||||
"Mod+O" = {
|
"Mod+O" = {
|
||||||
@@ -112,81 +93,44 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Keyboard focus movement
|
# Keyboard focus movement
|
||||||
"Mod+Left".focus-column-or-monitor-left = { };
|
|
||||||
"Mod+Down".focus-window-down = { };
|
|
||||||
"Mod+Up".focus-window-up = { };
|
|
||||||
"Mod+Right".focus-column-or-monitor-right = { };
|
|
||||||
"Mod+H".focus-column-or-monitor-left = { };
|
"Mod+H".focus-column-or-monitor-left = { };
|
||||||
"Mod+J".focus-window-down = { };
|
"Mod+J".focus-window-down = { };
|
||||||
"Mod+K".focus-window-up = { };
|
"Mod+K".focus-window-up = { };
|
||||||
"Mod+L".focus-column-or-monitor-right = { };
|
"Mod+L".focus-column-or-monitor-right = { };
|
||||||
|
|
||||||
# Keyboard window and column movement
|
# Keyboard window and column movement
|
||||||
"Mod+Alt+Left".move-column-left-or-to-monitor-left = { };
|
|
||||||
"Mod+Alt+Down".move-window-down-or-to-workspace-down = { };
|
|
||||||
"Mod+Alt+Up".move-window-up-or-to-workspace-up = { };
|
|
||||||
"Mod+Alt+Right".move-column-right-or-to-monitor-right = { };
|
|
||||||
"Mod+Alt+H".move-column-left-or-to-monitor-left = { };
|
"Mod+Alt+H".move-column-left-or-to-monitor-left = { };
|
||||||
"Mod+Alt+J".move-window-down-or-to-workspace-down = { };
|
"Mod+Alt+J".move-window-down-or-to-workspace-down = { };
|
||||||
"Mod+Alt+K".move-window-up-or-to-workspace-up = { };
|
"Mod+Alt+K".move-window-up-or-to-workspace-up = { };
|
||||||
"Mod+Alt+L".move-column-right-or-to-monitor-right = { };
|
"Mod+Alt+L".move-column-right-or-to-monitor-right = { };
|
||||||
|
|
||||||
# First and last column navigation
|
|
||||||
"Mod+Home".focus-column-first = { };
|
|
||||||
"Mod+End".focus-column-last = { };
|
|
||||||
"Mod+Alt+Home".move-column-to-first = { };
|
|
||||||
"Mod+Alt+End".move-column-to-last = { };
|
|
||||||
|
|
||||||
# Move focus, columns, and workspaces across monitors
|
# Move focus, columns, and workspaces across monitors
|
||||||
"Mod+Tab".focus-monitor-next = { };
|
"Mod+Tab".focus-monitor-next = { };
|
||||||
"Mod+A" = {
|
"Mod+A" = {
|
||||||
_props.repeat = false;
|
_props.repeat = false;
|
||||||
spawn = shortcutCommands.swapMonitorWorkspaces;
|
spawn = swapMonitorWorkspaces;
|
||||||
_props.hotkey-overlay-title = "Swap Monitor Workspaces";
|
_props.hotkey-overlay-title = "Swap Monitor Workspaces";
|
||||||
};
|
};
|
||||||
"Mod+Alt+Tab".move-column-to-monitor-next = { };
|
"Mod+Alt+Tab".move-column-to-monitor-next = { };
|
||||||
"Mod+Shift+Tab".move-workspace-to-monitor-next = { };
|
"Mod+Shift+Tab".move-workspace-to-monitor-next = { };
|
||||||
|
|
||||||
"Mod+Shift+Left".focus-monitor-left = { };
|
|
||||||
"Mod+Shift+Down".focus-monitor-down = { };
|
|
||||||
"Mod+Shift+Up".focus-monitor-up = { };
|
|
||||||
"Mod+Shift+Right".focus-monitor-right = { };
|
|
||||||
|
|
||||||
# Linear workspace navigation
|
# Linear workspace navigation
|
||||||
"Mod+Page_Down".focus-workspace-down = { };
|
|
||||||
"Mod+Page_Up".focus-workspace-up = { };
|
|
||||||
"Mod+U".focus-workspace-down = { };
|
"Mod+U".focus-workspace-down = { };
|
||||||
"Mod+I".focus-workspace-up = { };
|
"Mod+I".focus-workspace-up = { };
|
||||||
|
|
||||||
# Move columns between adjacent workspaces
|
# Move columns between adjacent workspaces
|
||||||
"Mod+Alt+Page_Down".move-column-to-workspace-down = { };
|
|
||||||
"Mod+Alt+Page_Up".move-column-to-workspace-up = { };
|
|
||||||
"Mod+Alt+U".move-column-to-workspace-down = { };
|
"Mod+Alt+U".move-column-to-workspace-down = { };
|
||||||
"Mod+Alt+I".move-column-to-workspace-up = { };
|
"Mod+Alt+I".move-column-to-workspace-up = { };
|
||||||
|
|
||||||
# Reorder workspaces
|
# Reorder workspaces
|
||||||
"Mod+Shift+Page_Down".move-workspace-down = { };
|
|
||||||
"Mod+Shift+Page_Up".move-workspace-up = { };
|
|
||||||
"Mod+Shift+U".move-workspace-down = { };
|
"Mod+Shift+U".move-workspace-down = { };
|
||||||
"Mod+Shift+I".move-workspace-up = { };
|
"Mod+Shift+I".move-workspace-up = { };
|
||||||
|
|
||||||
# Mouse workspace navigation
|
# Mouse workspace navigation
|
||||||
"Mod+WheelScrollDown" = {
|
"Mod+WheelScrollDown" = withCooldown "focus-workspace-down";
|
||||||
focus-workspace-down = { };
|
"Mod+WheelScrollUp" = withCooldown "focus-workspace-up";
|
||||||
_props.cooldown-ms = 150;
|
"Mod+Alt+WheelScrollDown" = withCooldown "move-column-to-workspace-down";
|
||||||
};
|
"Mod+Alt+WheelScrollUp" = withCooldown "move-column-to-workspace-up";
|
||||||
"Mod+WheelScrollUp" = {
|
|
||||||
focus-workspace-up = { };
|
|
||||||
_props.cooldown-ms = 150;
|
|
||||||
};
|
|
||||||
"Mod+Alt+WheelScrollDown" = {
|
|
||||||
move-column-to-workspace-down = { };
|
|
||||||
_props.cooldown-ms = 150;
|
|
||||||
};
|
|
||||||
"Mod+Alt+WheelScrollUp" = {
|
|
||||||
move-column-to-workspace-up = { };
|
|
||||||
_props.cooldown-ms = 150;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Mouse column navigation and movement
|
# Mouse column navigation and movement
|
||||||
"Mod+WheelScrollRight".focus-column-or-monitor-right = { };
|
"Mod+WheelScrollRight".focus-column-or-monitor-right = { };
|
||||||
@@ -196,28 +140,6 @@
|
|||||||
"Mod+Shift+WheelScrollDown".focus-column-or-monitor-right = { };
|
"Mod+Shift+WheelScrollDown".focus-column-or-monitor-right = { };
|
||||||
"Mod+Shift+WheelScrollUp".focus-column-or-monitor-left = { };
|
"Mod+Shift+WheelScrollUp".focus-column-or-monitor-left = { };
|
||||||
|
|
||||||
# Direct workspace focus
|
|
||||||
"Mod+1".focus-workspace = 1;
|
|
||||||
"Mod+2".focus-workspace = 2;
|
|
||||||
"Mod+3".focus-workspace = 3;
|
|
||||||
"Mod+4".focus-workspace = 4;
|
|
||||||
"Mod+5".focus-workspace = 5;
|
|
||||||
"Mod+6".focus-workspace = 6;
|
|
||||||
"Mod+7".focus-workspace = 7;
|
|
||||||
"Mod+8".focus-workspace = 8;
|
|
||||||
"Mod+9".focus-workspace = 9;
|
|
||||||
|
|
||||||
# Move columns to numbered workspaces
|
|
||||||
"Mod+Ctrl+1".move-column-to-workspace = 1;
|
|
||||||
"Mod+Ctrl+2".move-column-to-workspace = 2;
|
|
||||||
"Mod+Ctrl+3".move-column-to-workspace = 3;
|
|
||||||
"Mod+Ctrl+4".move-column-to-workspace = 4;
|
|
||||||
"Mod+Ctrl+5".move-column-to-workspace = 5;
|
|
||||||
"Mod+Ctrl+6".move-column-to-workspace = 6;
|
|
||||||
"Mod+Ctrl+7".move-column-to-workspace = 7;
|
|
||||||
"Mod+Ctrl+8".move-column-to-workspace = 8;
|
|
||||||
"Mod+Ctrl+9".move-column-to-workspace = 9;
|
|
||||||
|
|
||||||
# Add and remove windows from columns
|
# Add and remove windows from columns
|
||||||
"Mod+BracketLeft".consume-or-expel-window-left = { };
|
"Mod+BracketLeft".consume-or-expel-window-left = { };
|
||||||
"Mod+BracketRight".consume-or-expel-window-right = { };
|
"Mod+BracketRight".consume-or-expel-window-right = { };
|
||||||
@@ -226,23 +148,14 @@
|
|||||||
|
|
||||||
# Column and window presentation modes
|
# Column and window presentation modes
|
||||||
"Mod+R".switch-preset-column-width = { };
|
"Mod+R".switch-preset-column-width = { };
|
||||||
"Mod+Shift+R".switch-preset-column-width-back = { };
|
|
||||||
"Mod+Ctrl+R".reset-window-height = { };
|
|
||||||
"Mod+Ctrl+Shift+R".switch-preset-window-height = { };
|
|
||||||
"Mod+F".maximize-column = { };
|
"Mod+F".maximize-column = { };
|
||||||
"Mod+Shift+F".fullscreen-window = { };
|
"Mod+Shift+F".fullscreen-window = { };
|
||||||
"Mod+M".maximize-window-to-edges = { };
|
|
||||||
"Mod+C".center-column = { };
|
|
||||||
|
|
||||||
# Manual column width and window height adjustments
|
# Manual column width and window height adjustments
|
||||||
"Mod+Shift+H".set-column-width = "-10%";
|
"Mod+Shift+H".set-column-width = "-10%";
|
||||||
"Mod+Shift+L".set-column-width = "+10%";
|
"Mod+Shift+L".set-column-width = "+10%";
|
||||||
"Mod+Shift+J".set-window-height = "+10%";
|
"Mod+Shift+J".set-window-height = "+10%";
|
||||||
"Mod+Shift+K".set-window-height = "-10%";
|
"Mod+Shift+K".set-window-height = "-10%";
|
||||||
"Mod+Minus".set-column-width = "-10%";
|
|
||||||
"Mod+Equal".set-column-width = "+10%";
|
|
||||||
"Mod+Shift+Minus".set-window-height = "-10%";
|
|
||||||
"Mod+Shift+Equal".set-window-height = "+10%";
|
|
||||||
|
|
||||||
# Floating and tabbed layout toggles
|
# Floating and tabbed layout toggles
|
||||||
"Mod+Alt+V".toggle-window-floating = { };
|
"Mod+Alt+V".toggle-window-floating = { };
|
||||||
|
|||||||
@@ -1,138 +1,37 @@
|
|||||||
{
|
{ pkgs }:
|
||||||
config,
|
pkgs.writeShellApplication {
|
||||||
lib,
|
name = "niri-shortcut-swap-monitor-workspaces";
|
||||||
pkgs,
|
runtimeInputs = [
|
||||||
}:
|
pkgs.jq
|
||||||
let
|
pkgs.niri
|
||||||
nixosConfigDir = config.facts.account.nixosConfigurationPath;
|
];
|
||||||
mkTerminalScript =
|
text = ''
|
||||||
{
|
focused_output="$(niri msg --json focused-output | jq -r '.name // empty')"
|
||||||
name,
|
if [ -z "$focused_output" ]; then
|
||||||
workdir ? nixosConfigDir,
|
exit 0
|
||||||
command ? null,
|
fi
|
||||||
runtimeInputs ? [ ],
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
args = lib.optionals (command != null) [
|
|
||||||
"--"
|
|
||||||
"${pkgs.bash}/bin/bash"
|
|
||||||
"-lc"
|
|
||||||
command
|
|
||||||
];
|
|
||||||
argString = lib.concatMapStringsSep " " lib.escapeShellArg args;
|
|
||||||
in
|
|
||||||
pkgs.writeShellApplication {
|
|
||||||
inherit name runtimeInputs;
|
|
||||||
checkPhase = "";
|
|
||||||
text = lib.concatStringsSep "\n" [
|
|
||||||
"# shellcheck disable=SC2016"
|
|
||||||
"cd ${lib.escapeShellArg workdir}"
|
|
||||||
"exec ${lib.escapeShellArgs config.desktop.commands.terminal} ${argString}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
scripts = {
|
|
||||||
nixosTerminal = mkTerminalScript {
|
|
||||||
name = "niri-shortcut-nixos-terminal";
|
|
||||||
};
|
|
||||||
|
|
||||||
nixosSwitch = mkTerminalScript {
|
niri msg action focus-monitor-next
|
||||||
name = "niri-shortcut-nixos-switch";
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.nh
|
|
||||||
];
|
|
||||||
command = ''
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
log_dir="''${XDG_STATE_HOME:-$HOME/.local/state}/nixos-switch"
|
target_output="$(niri msg --json focused-output | jq -r '.name // empty')"
|
||||||
mkdir -p "$log_dir"
|
if [ -z "$target_output" ] || [ "$target_output" = "$focused_output" ]; then
|
||||||
log="$log_dir/$(date +%Y%m%d-%H%M%S).log"
|
exit 0
|
||||||
status_file="$(mktemp)"
|
fi
|
||||||
|
|
||||||
printf 'Running nh os switch in %s\n\n' ${lib.escapeShellArg nixosConfigDir}
|
target_workspace_idx="$(
|
||||||
(
|
niri msg --json workspaces \
|
||||||
cd ${lib.escapeShellArg nixosConfigDir}
|
| jq -r --arg output "$target_output" '
|
||||||
nh os switch
|
first(.[] | select(.output == $output and .is_active) | .idx) // empty
|
||||||
printf '%s' "$?" > "$status_file"
|
'
|
||||||
) 2>&1 | tee "$log"
|
)"
|
||||||
|
if [ -z "$target_workspace_idx" ]; then
|
||||||
|
niri msg action focus-monitor "$focused_output"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
status="$(cat "$status_file")"
|
niri msg action focus-monitor "$focused_output"
|
||||||
rm -f "$status_file"
|
niri msg action move-workspace-to-monitor "$target_output"
|
||||||
|
niri msg action focus-workspace "$target_workspace_idx"
|
||||||
printf '\nLog: %s\n' "$log"
|
niri msg action move-workspace-to-monitor "$focused_output"
|
||||||
if [ "$status" -eq 0 ]; then
|
'';
|
||||||
printf 'NixOS switch completed successfully.\n'
|
|
||||||
else
|
|
||||||
printf 'NixOS switch failed with exit code %s.\n' "$status"
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf 'Press Enter to close...'
|
|
||||||
read -r _
|
|
||||||
exit "$status"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
editSecrets = mkTerminalScript {
|
|
||||||
name = "niri-shortcut-edit-secrets";
|
|
||||||
runtimeInputs = [ pkgs.sops ];
|
|
||||||
command = ''
|
|
||||||
sops edit ${lib.escapeShellArg "${nixosConfigDir}/modules/secrets/secrets.yaml"}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pickColor = pkgs.writeShellApplication {
|
|
||||||
name = "niri-shortcut-pick-color";
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.libnotify
|
|
||||||
pkgs.niri
|
|
||||||
pkgs.wl-clipboard
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
color="$(niri msg pick-color)"
|
|
||||||
printf '%s' "$color" | wl-copy
|
|
||||||
notify-send 'Color picked' "$color"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
swapMonitorWorkspaces = pkgs.writeShellApplication {
|
|
||||||
name = "niri-shortcut-swap-monitor-workspaces";
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.jq
|
|
||||||
pkgs.niri
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
focused_output="$(niri msg --json focused-output | jq -r '.name // empty')"
|
|
||||||
if [ -z "$focused_output" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
niri msg action focus-monitor-next
|
|
||||||
|
|
||||||
target_output="$(niri msg --json focused-output | jq -r '.name // empty')"
|
|
||||||
if [ -z "$target_output" ] || [ "$target_output" = "$focused_output" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
target_workspace_idx="$(
|
|
||||||
niri msg --json workspaces \
|
|
||||||
| jq -r --arg output "$target_output" '
|
|
||||||
first(.[] | select(.output == $output and .is_active) | .idx) // empty
|
|
||||||
'
|
|
||||||
)"
|
|
||||||
if [ -z "$target_workspace_idx" ]; then
|
|
||||||
niri msg action focus-monitor "$focused_output"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
niri msg action focus-monitor "$focused_output"
|
|
||||||
niri msg action move-workspace-to-monitor "$target_output"
|
|
||||||
niri msg action focus-workspace "$target_workspace_idx"
|
|
||||||
niri msg action move-workspace-to-monitor "$focused_output"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
commands = lib.mapAttrs (_: lib.getExe) scripts;
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
kanagawa = import ../_kanagawa.nix;
|
|
||||||
hmModules = config.flake.modules.homeManager;
|
hmModules = config.flake.modules.homeManager;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -28,14 +27,7 @@ in
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
palette = kanagawa.palette;
|
swapMonitorWorkspaces = import ./_shortcuts.nix { inherit pkgs; };
|
||||||
shortcuts = import ./_shortcuts.nix {
|
|
||||||
inherit
|
|
||||||
config
|
|
||||||
lib
|
|
||||||
pkgs
|
|
||||||
;
|
|
||||||
};
|
|
||||||
machine = config.facts.machine;
|
machine = config.facts.machine;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -47,12 +39,11 @@ in
|
|||||||
playerctl
|
playerctl
|
||||||
brightnessctl
|
brightnessctl
|
||||||
wireplumber
|
wireplumber
|
||||||
|
wtype
|
||||||
]
|
]
|
||||||
++ lib.attrValues shortcuts.scripts;
|
++ [ swapMonitorWorkspaces ];
|
||||||
};
|
};
|
||||||
|
|
||||||
dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
|
|
||||||
|
|
||||||
wayland.windowManager.niri = {
|
wayland.windowManager.niri = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
@@ -109,12 +100,7 @@ in
|
|||||||
focus-ring.off = { };
|
focus-ring.off = { };
|
||||||
default-column-width.proportion = 1. / 2.;
|
default-column-width.proportion = 1. / 2.;
|
||||||
|
|
||||||
border = {
|
border.width = 3;
|
||||||
width = 3;
|
|
||||||
active-color = palette.accents.blue;
|
|
||||||
inactive-color = palette.subtleBorder;
|
|
||||||
urgent-color = palette.accents.red;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
debug.honor-xdg-activation-with-invalid-serial = true;
|
debug.honor-xdg-activation-with-invalid-serial = true;
|
||||||
@@ -141,7 +127,8 @@ in
|
|||||||
launcher
|
launcher
|
||||||
terminal
|
terminal
|
||||||
;
|
;
|
||||||
shortcutCommands = shortcuts.commands;
|
swapMonitorWorkspaces = lib.getExe swapMonitorWorkspaces;
|
||||||
|
handy = lib.getExe pkgs.handy;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,28 +3,25 @@ let
|
|||||||
account = config.facts.account;
|
account = config.facts.account;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.nixos.nix =
|
flake.modules.nixos.nix = {
|
||||||
{ ... }:
|
nixpkgs.config.allowUnfree = true;
|
||||||
{
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
gc.automatic = true;
|
gc.automatic = true;
|
||||||
optimise.automatic = true;
|
optimise.automatic = true;
|
||||||
registry.nixpkgs.flake = inputs.nixpkgs;
|
channel.enable = false;
|
||||||
channel.enable = false;
|
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
trusted-users = [ "@wheel" ];
|
trusted-users = [ "@wheel" ];
|
||||||
use-xdg-base-directories = true;
|
use-xdg-base-directories = true;
|
||||||
|
|
||||||
experimental-features = [
|
experimental-features = [
|
||||||
"nix-command"
|
"nix-command"
|
||||||
"flakes"
|
"flakes"
|
||||||
];
|
];
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.nix =
|
flake.modules.homeManager.nix =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
homeDir = config.home.homeDirectory;
|
homeDir = config.home.homeDirectory;
|
||||||
wallpaper = "${homeDir}/media/images/wallpapers/green-leaves.png";
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
desktop.autostart = [ [ (lib.getExe config.programs.noctalia.package) ] ];
|
desktop.autostart = [ [ (lib.getExe config.programs.noctalia.package) ] ];
|
||||||
@@ -61,17 +60,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
desktop_widgets = {
|
desktop_widgets.enabled = false;
|
||||||
enabled = false;
|
|
||||||
schema_version = 2;
|
|
||||||
widget_order = [ ];
|
|
||||||
grid = {
|
|
||||||
cell_size = 16;
|
|
||||||
major_interval = 4;
|
|
||||||
visible = true;
|
|
||||||
};
|
|
||||||
widget = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
location.address = "Meterik, The Netherlands";
|
location.address = "Meterik, The Netherlands";
|
||||||
|
|
||||||
@@ -95,10 +84,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
shell = {
|
shell = {
|
||||||
font_family = "Lexend";
|
|
||||||
polkit_agent = true;
|
polkit_agent = true;
|
||||||
|
# Handy provides recording feedback; omit microphone activity popups/indicators.
|
||||||
|
privacy.mic_filter_regex = ".*";
|
||||||
screen_time_enabled = true;
|
screen_time_enabled = true;
|
||||||
settings_show_advanced = true;
|
|
||||||
animation.speed = 1.5;
|
animation.speed = 1.5;
|
||||||
screen_corners = {
|
screen_corners = {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
@@ -108,9 +97,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
theme = {
|
theme = {
|
||||||
builtin = "Kanagawa";
|
|
||||||
community_palette = "Kanagawa Paper";
|
|
||||||
wallpaper_scheme = "m3-content";
|
|
||||||
templates = {
|
templates = {
|
||||||
enable_builtin_templates = false;
|
enable_builtin_templates = false;
|
||||||
enable_community_templates = false;
|
enable_community_templates = false;
|
||||||
@@ -119,15 +105,12 @@
|
|||||||
|
|
||||||
wallpaper = {
|
wallpaper = {
|
||||||
directory = "${homeDir}/media/images/wallpapers";
|
directory = "${homeDir}/media/images/wallpapers";
|
||||||
default.path = wallpaper;
|
|
||||||
last.path = wallpaper;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
weather.refresh_minutes = 15;
|
weather.refresh_minutes = 15;
|
||||||
|
|
||||||
widget = {
|
widget = {
|
||||||
bluetooth.hide_when_no_connected_device = true;
|
bluetooth.hide_when_no_connected_device = true;
|
||||||
clock.format = "{:%H:%M}";
|
|
||||||
media = {
|
media = {
|
||||||
art_size = 90.0;
|
art_size = 90.0;
|
||||||
max_length = 800;
|
max_length = 800;
|
||||||
|
|||||||
@@ -19,6 +19,17 @@ in
|
|||||||
|
|
||||||
[tool]
|
[tool]
|
||||||
fzf-preview = "bat --plain --color=always {-1}"
|
fzf-preview = "bat --plain --color=always {-1}"
|
||||||
|
|
||||||
|
[group.daily]
|
||||||
|
paths = ["daily"]
|
||||||
|
|
||||||
|
[group.daily.note]
|
||||||
|
filename = "{{format-date now '%Y-%m-%d'}}"
|
||||||
|
extension = "md"
|
||||||
|
template = "daily.md"
|
||||||
|
|
||||||
|
[alias]
|
||||||
|
daily = 'nvim + "$(zk new --no-input --print-path "$ZK_NOTEBOOK_DIR/daily")"'
|
||||||
'';
|
'';
|
||||||
noteTemplate = ''
|
noteTemplate = ''
|
||||||
---
|
---
|
||||||
@@ -27,49 +38,43 @@ in
|
|||||||
|
|
||||||
# {{title}}
|
# {{title}}
|
||||||
'';
|
'';
|
||||||
|
openDailyNote = pkgs.writeShellApplication {
|
||||||
|
name = "open-daily-note";
|
||||||
|
text = ''
|
||||||
|
exec ${lib.getExe config.programs.kitty.package} --detach \
|
||||||
|
--directory "${home}/sync/notes" \
|
||||||
|
${lib.getExe pkgs.zsh} -lic 'zk daily'
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [
|
home.packages = [
|
||||||
ripgrep-all
|
openDailyNote
|
||||||
zk
|
(pkgs.makeDesktopItem {
|
||||||
|
name = "notes";
|
||||||
|
desktopName = "Notes";
|
||||||
|
icon = "text-editor";
|
||||||
|
exec = "nvim .";
|
||||||
|
path = "${home}/sync/notes";
|
||||||
|
terminal = true;
|
||||||
|
})
|
||||||
|
pkgs.ripgrep-all
|
||||||
|
pkgs.zk
|
||||||
];
|
];
|
||||||
|
|
||||||
home.file = {
|
home.file = {
|
||||||
"sync/notes/.zk/config.toml".text = zkConfig;
|
"sync/notes/.zk/config.toml".text = zkConfig;
|
||||||
|
"sync/notes/.zk/templates/daily.md".text = "";
|
||||||
"sync/notes/.zk/templates/default.md".text = noteTemplate;
|
"sync/notes/.zk/templates/default.md".text = noteTemplate;
|
||||||
"sync/work/notes/.zk/config.toml".text = zkConfig;
|
|
||||||
"sync/work/notes/.zk/templates/default.md".text = noteTemplate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
home.activation.createNotesLayout = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
home.activation.createNotesLayout = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
${pkgs.coreutils}/bin/mkdir -p \
|
${pkgs.coreutils}/bin/mkdir -p \
|
||||||
"${home}/sync/notes/transcripts" \
|
"${home}/sync/notes/daily" \
|
||||||
"${home}/sync/recordings/inbox" \
|
"${home}/sync/notes/meetings" \
|
||||||
"${home}/sync/recordings/processing" \
|
"${home}/sync/notes/transcripts"
|
||||||
"${home}/sync/recordings/archive" \
|
|
||||||
"${home}/sync/recordings/failed" \
|
|
||||||
"${home}/sync/work/notes/meetings" \
|
|
||||||
"${home}/sync/work/notes/transcripts" \
|
|
||||||
"${home}/sync/work/recordings/inbox" \
|
|
||||||
"${home}/sync/work/recordings/processing" \
|
|
||||||
"${home}/sync/work/recordings/archive" \
|
|
||||||
"${home}/sync/work/recordings/failed"
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs.helix.languages = {
|
|
||||||
language-server.zk = {
|
|
||||||
command = lib.getExe pkgs.zk;
|
|
||||||
args = [ "lsp" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
language = [
|
|
||||||
{
|
|
||||||
name = "markdown";
|
|
||||||
roots = [ ".zk" ];
|
|
||||||
language-servers = [ "zk" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.notes =
|
flake.modules.nixos.notes =
|
||||||
|
|||||||
@@ -12,16 +12,13 @@ in
|
|||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
pinentryPackage = pkgs.pinentry-gnome3;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
programs.rbw = {
|
programs.rbw = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
base_url = facts.services.vaultwarden.origin;
|
base_url = facts.services.vaultwarden.origin;
|
||||||
email = account.emails.${account.primaryEmail}.address;
|
email = account.emails.${account.primaryEmail}.address;
|
||||||
pinentry = pinentryPackage;
|
pinentry = pkgs.pinentry-gnome3;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,15 @@ let
|
|||||||
homeModules = config.flake.modules.homeManager;
|
homeModules = config.flake.modules.homeManager;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
flake.modules.nixos.evolution =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.evolution = {
|
||||||
|
enable = true;
|
||||||
|
plugins = [ pkgs.evolution-ews ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.email =
|
flake.modules.homeManager.email =
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
@@ -21,7 +30,6 @@ in
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
enable = true;
|
|
||||||
inherit address;
|
inherit address;
|
||||||
realName = account.realName;
|
realName = account.realName;
|
||||||
userName = address;
|
userName = address;
|
||||||
@@ -40,7 +48,6 @@ in
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
enable = true;
|
|
||||||
inherit address;
|
inherit address;
|
||||||
realName = account.realName;
|
realName = account.realName;
|
||||||
userName = address;
|
userName = address;
|
||||||
@@ -49,13 +56,11 @@ in
|
|||||||
authentication = "plain";
|
authentication = "plain";
|
||||||
host = "taylor.mxrouting.net";
|
host = "taylor.mxrouting.net";
|
||||||
port = 993;
|
port = 993;
|
||||||
tls.enable = true;
|
|
||||||
};
|
};
|
||||||
smtp = {
|
smtp = {
|
||||||
authentication = "plain";
|
authentication = "plain";
|
||||||
host = "taylor.mxrouting.net";
|
host = "taylor.mxrouting.net";
|
||||||
port = 465;
|
port = 465;
|
||||||
tls.enable = true;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
mkEmailAccount =
|
mkEmailAccount =
|
||||||
@@ -93,9 +98,6 @@ in
|
|||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
calendarsPath = "${config.xdg.dataHome}/calendars";
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [ homeModules.sops ];
|
imports = [ homeModules.sops ];
|
||||||
|
|
||||||
@@ -126,16 +128,11 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
accounts.calendar = {
|
accounts.calendar = {
|
||||||
basePath = calendarsPath;
|
basePath = "${config.xdg.dataHome}/calendars";
|
||||||
accounts.radicale = {
|
accounts.radicale = {
|
||||||
primary = true;
|
primary = true;
|
||||||
primaryCollection = "personal";
|
primaryCollection = "personal";
|
||||||
|
|
||||||
local = {
|
|
||||||
type = "filesystem";
|
|
||||||
fileExt = ".ics";
|
|
||||||
};
|
|
||||||
|
|
||||||
remote = {
|
remote = {
|
||||||
url = "${facts.services.radicale.origin}/";
|
url = "${facts.services.radicale.origin}/";
|
||||||
type = "caldav";
|
type = "caldav";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
flake.modules.nixos.plymouth =
|
flake.modules.nixos.plymouth =
|
||||||
{ pkgs, ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
boot = {
|
boot = {
|
||||||
consoleLogLevel = 3;
|
consoleLogLevel = 3;
|
||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
plymouth = {
|
plymouth = {
|
||||||
enable = true;
|
enable = true;
|
||||||
theme = "spinner_alt";
|
|
||||||
themePackages = [ pkgs.adi1090x-plymouth-themes ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
|
||||||
homeModules = config.flake.modules.homeManager;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
flake.modules.nixos.podman = {
|
flake.modules.nixos.podman =
|
||||||
home-manager.sharedModules = [ homeModules.podman ];
|
{ lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
home-manager.sharedModules = [ config.flake.modules.homeManager.podman ];
|
||||||
|
|
||||||
virtualisation.podman.enable = true;
|
virtualisation.podman.enable = true;
|
||||||
};
|
virtualisation.containers.containersConf.settings.engine.compose_providers = [
|
||||||
|
(lib.getExe pkgs.podman-compose)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.podman =
|
flake.modules.homeManager.podman =
|
||||||
{ osConfig, pkgs, ... }:
|
{ osConfig, pkgs, ... }:
|
||||||
|
|||||||
@@ -7,9 +7,7 @@
|
|||||||
printing = {
|
printing = {
|
||||||
enable = true;
|
enable = true;
|
||||||
browsed.enable = true;
|
browsed.enable = true;
|
||||||
drivers = with pkgs; [
|
drivers = [ pkgs.cnijfilter2 ];
|
||||||
cnijfilter2
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
avahi = {
|
avahi = {
|
||||||
|
|||||||
@@ -1,25 +1,10 @@
|
|||||||
{
|
{
|
||||||
flake.modules.nixos.sddm =
|
flake.modules.nixos.sddm = {
|
||||||
{
|
services.displayManager.sddm = {
|
||||||
pkgs,
|
enable = true;
|
||||||
...
|
enableHidpi = true;
|
||||||
}:
|
wayland.enable = true;
|
||||||
{
|
wayland.compositor = "kwin";
|
||||||
services.displayManager.sddm = {
|
|
||||||
enable = true;
|
|
||||||
enableHidpi = true;
|
|
||||||
wayland.enable = true;
|
|
||||||
wayland.compositor = "kwin";
|
|
||||||
theme = "${
|
|
||||||
pkgs.sddm-astronaut.override { embeddedTheme = "purple_leaves"; }
|
|
||||||
}/share/sddm/themes/sddm-astronaut-theme";
|
|
||||||
extraPackages = with pkgs; [
|
|
||||||
kdePackages.qtmultimedia
|
|
||||||
];
|
|
||||||
settings.Theme = {
|
|
||||||
CursorTheme = "phinger-cursors-light";
|
|
||||||
CursorSize = 24;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,17 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
|
||||||
service = config.facts.services.actual;
|
|
||||||
nixosModules = config.flake.modules.nixos;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
flake.modules.nixos.actual = {
|
flake.modules.nixos.actual = {
|
||||||
imports = [ nixosModules.caddy ];
|
imports = [ config.flake.modules.nixos.caddy ];
|
||||||
|
|
||||||
services.actual = {
|
services.actual = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = false;
|
|
||||||
settings = {
|
settings = {
|
||||||
hostname = "127.0.0.1";
|
hostname = "127.0.0.1";
|
||||||
port = 3000;
|
port = 3000;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.caddy.virtualHosts.${service.domain}.extraConfig = "reverse_proxy 127.0.0.1:3000";
|
services.caddy.virtualHosts.${config.facts.services.actual.domain}.extraConfig =
|
||||||
|
"reverse_proxy 127.0.0.1:3000";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -19,9 +19,6 @@ in
|
|||||||
ROOT_URL = "${service.origin}/";
|
ROOT_URL = "${service.origin}/";
|
||||||
HTTP_PORT = 3001;
|
HTTP_PORT = 3001;
|
||||||
HTTP_ADDR = "127.0.0.1";
|
HTTP_ADDR = "127.0.0.1";
|
||||||
|
|
||||||
START_SSH_SERVER = false;
|
|
||||||
SSH_PORT = 22;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
service.DISABLE_REGISTRATION = true;
|
service.DISABLE_REGISTRATION = true;
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
account = config.facts.account;
|
account = config.facts.account;
|
||||||
personalPublicKeys =
|
personalPublicKeys = map (machine: machine.sshKeys.personal.publicKey) (
|
||||||
machines:
|
lib.filter (machine: machine.sshKeys ? personal) (builtins.attrValues config.facts.machines)
|
||||||
map (machine: machine.sshKeys.personal.publicKey) (
|
);
|
||||||
lib.filter (machine: machine.sshKeys ? personal) (builtins.attrValues machines)
|
|
||||||
);
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.nixos.sudo-ssh-agent-auth = {
|
flake.modules.nixos.sudo-ssh-agent-auth = {
|
||||||
@@ -15,18 +13,16 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.openssh =
|
flake.modules.nixos.openssh = {
|
||||||
{ ... }:
|
services.openssh = {
|
||||||
{
|
enable = true;
|
||||||
services.openssh = {
|
settings = {
|
||||||
enable = true;
|
PermitRootLogin = "no";
|
||||||
settings = {
|
PasswordAuthentication = false;
|
||||||
PermitRootLogin = "no";
|
AllowUsers = [ account.name ];
|
||||||
PasswordAuthentication = false;
|
|
||||||
AllowUsers = [ account.name ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.${account.name}.openssh.authorizedKeys.keys = personalPublicKeys config.facts.machines;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
users.users.${account.name}.openssh.authorizedKeys.keys = personalPublicKeys;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
|
||||||
service = config.facts.services.radicale;
|
|
||||||
nixosModules = config.flake.modules.nixos;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
flake.modules.nixos.radicale = {
|
flake.modules.nixos.radicale = {
|
||||||
imports = [ nixosModules.caddy ];
|
imports = [ config.flake.modules.nixos.caddy ];
|
||||||
|
|
||||||
services.radicale = {
|
services.radicale = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -17,15 +13,12 @@ in
|
|||||||
htpasswd_filename = "/var/lib/radicale/users";
|
htpasswd_filename = "/var/lib/radicale/users";
|
||||||
htpasswd_encryption = "bcrypt";
|
htpasswd_encryption = "bcrypt";
|
||||||
};
|
};
|
||||||
|
|
||||||
storage.filesystem_folder = "/var/lib/radicale/collections";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.caddy.virtualHosts.${service.domain}.extraConfig = ''
|
services.caddy.virtualHosts.${config.facts.services.radicale.domain}.extraConfig = ''
|
||||||
reverse_proxy 127.0.0.1:5232 {
|
reverse_proxy 127.0.0.1:5232 {
|
||||||
header_up X-Script-Name /
|
header_up X-Script-Name /
|
||||||
header_up X-Forwarded-For {remote}
|
|
||||||
header_up X-Remote-User {http.auth.user.id}
|
header_up X-Remote-User {http.auth.user.id}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
let
|
||||||
service = config.facts.services.vaultwarden;
|
service = config.facts.services.vaultwarden;
|
||||||
nixosModules = config.flake.modules.nixos;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.nixos.vaultwarden = {
|
flake.modules.nixos.vaultwarden = {
|
||||||
imports = [ nixosModules.caddy ];
|
imports = [ config.flake.modules.nixos.caddy ];
|
||||||
|
|
||||||
services.vaultwarden = {
|
services.vaultwarden = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -1,222 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
flake.modules.nixos.vps-insights =
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
localAddress = "127.0.0.1";
|
|
||||||
grafanaDataDir = config.services.grafana.dataDir;
|
|
||||||
lokiDataDir = config.services.loki.dataDir;
|
|
||||||
lokiUrl = "http://${localAddress}:3100";
|
|
||||||
prometheusUrl = "http://${localAddress}:9090";
|
|
||||||
hasCaddy = config.services.caddy.enable;
|
|
||||||
hasOpenSSH = config.services.openssh.enable;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
environment = {
|
|
||||||
etc."alloy/config.alloy".text = ''
|
|
||||||
loki.relabel "journal" {
|
|
||||||
forward_to = []
|
|
||||||
|
|
||||||
rule {
|
|
||||||
source_labels = ["__journal__systemd_unit"]
|
|
||||||
target_label = "unit"
|
|
||||||
}
|
|
||||||
|
|
||||||
rule {
|
|
||||||
source_labels = ["__journal_syslog_identifier"]
|
|
||||||
target_label = "syslog_identifier"
|
|
||||||
}
|
|
||||||
|
|
||||||
rule {
|
|
||||||
source_labels = ["__journal_priority_keyword"]
|
|
||||||
target_label = "level"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loki.source.journal "system" {
|
|
||||||
forward_to = [loki.write.local.receiver]
|
|
||||||
relabel_rules = loki.relabel.journal.rules
|
|
||||||
max_age = "24h"
|
|
||||||
labels = {
|
|
||||||
host = "${config.networking.hostName}",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loki.write "local" {
|
|
||||||
endpoint {
|
|
||||||
url = "${lokiUrl}/loki/api/v1/push"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
systemPackages = with pkgs; [
|
|
||||||
goaccess
|
|
||||||
lynis
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
# Keep local system logs available for Loki and manual inspection.
|
|
||||||
journald.extraConfig = ''
|
|
||||||
Storage=persistent
|
|
||||||
SystemMaxUse=1G
|
|
||||||
MaxRetentionSec=30day
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Detect and block common attacks against SSH and Caddy.
|
|
||||||
crowdsec = {
|
|
||||||
enable = true;
|
|
||||||
hub.collections = [ "crowdsecurity/linux" ] ++ lib.optional hasCaddy "crowdsecurity/caddy";
|
|
||||||
localConfig.acquisitions =
|
|
||||||
lib.optional hasOpenSSH {
|
|
||||||
source = "journalctl";
|
|
||||||
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
|
|
||||||
labels.type = "syslog";
|
|
||||||
}
|
|
||||||
++ lib.optional hasCaddy {
|
|
||||||
filenames = [ "/var/log/caddy/*.log" ];
|
|
||||||
labels.type = "caddy";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
crowdsec-firewall-bouncer = {
|
|
||||||
enable = true;
|
|
||||||
registerBouncer.bouncerName = "${config.networking.hostName}-firewall-bouncer";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Keep Grafana local and separate from Actual's port.
|
|
||||||
grafana = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
analytics.reporting_enabled = false;
|
|
||||||
server = {
|
|
||||||
http_addr = localAddress;
|
|
||||||
http_port = 3002;
|
|
||||||
};
|
|
||||||
security = {
|
|
||||||
admin_password = "$__file{${grafanaDataDir}/admin-password}";
|
|
||||||
secret_key = "$__file{${grafanaDataDir}/secret-key}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
provision.datasources.settings = {
|
|
||||||
prune = true;
|
|
||||||
datasources = [
|
|
||||||
{
|
|
||||||
name = "Prometheus";
|
|
||||||
type = "prometheus";
|
|
||||||
uid = "prometheus";
|
|
||||||
url = prometheusUrl;
|
|
||||||
isDefault = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "Loki";
|
|
||||||
type = "loki";
|
|
||||||
uid = "loki";
|
|
||||||
url = lokiUrl;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Store local logs in Loki and feed them from journald through Alloy.
|
|
||||||
loki = {
|
|
||||||
enable = true;
|
|
||||||
configuration = {
|
|
||||||
analytics.reporting_enabled = false;
|
|
||||||
auth_enabled = false;
|
|
||||||
|
|
||||||
server = {
|
|
||||||
http_listen_address = localAddress;
|
|
||||||
http_listen_port = 3100;
|
|
||||||
grpc_listen_address = localAddress;
|
|
||||||
grpc_listen_port = 9096;
|
|
||||||
};
|
|
||||||
|
|
||||||
common = {
|
|
||||||
path_prefix = lokiDataDir;
|
|
||||||
replication_factor = 1;
|
|
||||||
instance_interface_names = [ "lo" ];
|
|
||||||
ring = {
|
|
||||||
instance_addr = localAddress;
|
|
||||||
kvstore.store = "inmemory";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
schema_config.configs = [
|
|
||||||
{
|
|
||||||
from = "2025-01-01";
|
|
||||||
store = "tsdb";
|
|
||||||
object_store = "filesystem";
|
|
||||||
schema = "v13";
|
|
||||||
index = {
|
|
||||||
prefix = "index_";
|
|
||||||
period = "24h";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
storage_config.filesystem.directory = "${lokiDataDir}/chunks";
|
|
||||||
|
|
||||||
compactor = {
|
|
||||||
working_directory = "${lokiDataDir}/compactor";
|
|
||||||
retention_enabled = true;
|
|
||||||
delete_request_store = "filesystem";
|
|
||||||
};
|
|
||||||
|
|
||||||
limits_config.retention_period = "720h";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
alloy = {
|
|
||||||
enable = true;
|
|
||||||
extraFlags = [ "--server.http.listen-addr=${localAddress}:12345" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Collect basic VPS health metrics for Grafana.
|
|
||||||
prometheus = {
|
|
||||||
enable = true;
|
|
||||||
listenAddress = localAddress;
|
|
||||||
retentionTime = "30d";
|
|
||||||
scrapeConfigs = [
|
|
||||||
{
|
|
||||||
job_name = "prometheus";
|
|
||||||
static_configs = [
|
|
||||||
{
|
|
||||||
targets = [ "${localAddress}:9090" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
job_name = "node";
|
|
||||||
static_configs = [
|
|
||||||
{
|
|
||||||
targets = [ "${localAddress}:9100" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
exporters.node = {
|
|
||||||
enable = true;
|
|
||||||
listenAddress = localAddress;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.grafana.preStart = ''
|
|
||||||
umask 077
|
|
||||||
|
|
||||||
if [ ! -s ${grafanaDataDir}/admin-password ]; then
|
|
||||||
${pkgs.openssl}/bin/openssl rand -base64 32 > ${grafanaDataDir}/admin-password
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -s ${grafanaDataDir}/secret-key ]; then
|
|
||||||
${pkgs.openssl}/bin/openssl rand -hex 32 > ${grafanaDataDir}/secret-key
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
flake.modules.homeManager.sharepoint-reference =
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
rcloneConfig = "${config.xdg.configHome}/rclone/rclone.conf";
|
||||||
|
destination = "${config.xdg.dataHome}/yookr-reference/sharepoint";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.user.services.sharepoint-reference-sync = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Refresh the local SharePoint reference mirror";
|
||||||
|
ConditionPathExists = rcloneConfig;
|
||||||
|
# Let an in-flight sync finish; activation must not restart and wait for it.
|
||||||
|
X-SwitchMethod = "keep-old";
|
||||||
|
};
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
UMask = "0077";
|
||||||
|
ExecStart = [
|
||||||
|
"${lib.getExe pkgs.rclone} --config ${rcloneConfig} sync company-sharepoint: ${destination}/Algemeen --max-delete 100"
|
||||||
|
"${lib.getExe pkgs.rclone} --config ${rcloneConfig} sync company-sharepoint-projecten: ${destination}/Projecten --max-delete 100"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.timers.sharepoint-reference-sync = {
|
||||||
|
Unit.Description = "Refresh the local SharePoint reference mirror hourly";
|
||||||
|
|
||||||
|
Timer = {
|
||||||
|
OnCalendar = "hourly";
|
||||||
|
Persistent = true;
|
||||||
|
RandomizedDelaySec = "10m";
|
||||||
|
};
|
||||||
|
|
||||||
|
Install.WantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.nixos.sharepoint-reference = {
|
||||||
|
home-manager.sharedModules = [ config.flake.modules.homeManager.sharepoint-reference ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,10 +7,6 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
gardenctl = "${config.home.homeDirectory}/.garden/gardenctl";
|
|
||||||
uuidgen = lib.getExe' pkgs.util-linux "uuidgen";
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
STARSHIP_CACHE = "${config.xdg.cacheHome}/starship";
|
STARSHIP_CACHE = "${config.xdg.cacheHome}/starship";
|
||||||
@@ -26,7 +22,6 @@
|
|||||||
enable = true;
|
enable = true;
|
||||||
dotDir = "${config.xdg.configHome}/zsh";
|
dotDir = "${config.xdg.configHome}/zsh";
|
||||||
|
|
||||||
enableCompletion = true;
|
|
||||||
completionInit = ''
|
completionInit = ''
|
||||||
autoload -U compinit
|
autoload -U compinit
|
||||||
compinit -C
|
compinit -C
|
||||||
@@ -54,24 +49,10 @@
|
|||||||
|
|
||||||
historySubstringSearch.enable = true;
|
historySubstringSearch.enable = true;
|
||||||
|
|
||||||
history = {
|
history.path = "${config.xdg.dataHome}/zsh_history";
|
||||||
ignoreDups = true;
|
|
||||||
save = 10000;
|
|
||||||
size = 10000;
|
|
||||||
path = "${config.xdg.dataHome}/zsh_history";
|
|
||||||
};
|
|
||||||
|
|
||||||
profileExtra = lib.optionalString (config.home.sessionPath != [ ]) ''
|
|
||||||
export PATH="$PATH''${PATH:+:}${lib.concatStringsSep ":" config.home.sessionPath}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
initContent = ''
|
initContent = ''
|
||||||
source <(${gardenctl} completion zsh)
|
source <(gardenctl rc zsh --no-completion)
|
||||||
if [ -z "$GCTL_SESSION_ID" ] && [ -z "$TERM_SESSION_ID" ]; then
|
|
||||||
export GCTL_SESSION_ID=$(${uuidgen})
|
|
||||||
fi
|
|
||||||
|
|
||||||
eval $(${gardenctl} kubectl-env zsh)
|
|
||||||
|
|
||||||
bindkey -v
|
bindkey -v
|
||||||
|
|
||||||
@@ -127,19 +108,8 @@
|
|||||||
|
|
||||||
programs.starship = {
|
programs.starship = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableZshIntegration = true;
|
|
||||||
settings = {
|
settings = {
|
||||||
add_newline = true;
|
format = "$nix_shell$hostname$directory$git_branch$git_state$line_break$character";
|
||||||
|
|
||||||
format = lib.concatStrings [
|
|
||||||
"$nix_shell"
|
|
||||||
"$hostname"
|
|
||||||
"$directory"
|
|
||||||
"$git_branch"
|
|
||||||
"$git_state"
|
|
||||||
"$line_break"
|
|
||||||
"$character"
|
|
||||||
];
|
|
||||||
|
|
||||||
directory = {
|
directory = {
|
||||||
truncation_length = 99;
|
truncation_length = 99;
|
||||||
@@ -156,8 +126,6 @@
|
|||||||
format = "([$state( $progress_current/$progress_total)]($style)) ";
|
format = "([$state( $progress_current/$progress_total)]($style)) ";
|
||||||
style = "bright-black";
|
style = "bright-black";
|
||||||
};
|
};
|
||||||
|
|
||||||
line_break.disabled = false;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,15 +134,9 @@
|
|||||||
extraOptions = [ "--group-directories-first" ];
|
extraOptions = [ "--group-directories-first" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.zoxide = {
|
programs.zoxide.enable = true;
|
||||||
enable = true;
|
|
||||||
enableZshIntegration = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.fzf = {
|
programs.fzf.enable = true;
|
||||||
enable = true;
|
|
||||||
enableZshIntegration = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.bottom.enable = true;
|
programs.bottom.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
name: context7-mcp
|
||||||
|
description: This skill should be used when the user asks about libraries, frameworks, API references, or needs code examples. Activates for setup questions, code generation involving libraries, or mentions of specific frameworks like React, Vue, Next.js, Prisma, Supabase, etc.
|
||||||
|
---
|
||||||
|
|
||||||
|
When the user asks about libraries, frameworks, or needs code examples, use Context7 to fetch current documentation instead of relying on training data.
|
||||||
|
|
||||||
|
## When to Use This Skill
|
||||||
|
|
||||||
|
Activate this skill when the user:
|
||||||
|
|
||||||
|
- Asks setup or configuration questions ("How do I configure Next.js middleware?")
|
||||||
|
- Requests code involving libraries ("Write a Prisma query for...")
|
||||||
|
- Needs API references ("What are the Supabase auth methods?")
|
||||||
|
- Mentions specific frameworks (React, Vue, Svelte, Express, Tailwind, etc.)
|
||||||
|
|
||||||
|
## How to Fetch Documentation
|
||||||
|
|
||||||
|
### Step 1: Resolve the Library ID
|
||||||
|
|
||||||
|
Call `resolve-library-id` with:
|
||||||
|
|
||||||
|
- `libraryName`: The library name extracted from the user's question
|
||||||
|
- `query`: The user's full question (improves relevance ranking)
|
||||||
|
|
||||||
|
### Step 2: Select the Best Match
|
||||||
|
|
||||||
|
From the resolution results, choose based on:
|
||||||
|
|
||||||
|
- Exact or closest name match to what the user asked for
|
||||||
|
- Higher benchmark scores indicate better documentation quality
|
||||||
|
- If the user mentioned a version (e.g., "React 19"), prefer version-specific IDs
|
||||||
|
|
||||||
|
### Step 3: Fetch the Documentation
|
||||||
|
|
||||||
|
Call `query-docs` with:
|
||||||
|
|
||||||
|
- `libraryId`: The selected Context7 library ID (e.g., `/vercel/next.js`)
|
||||||
|
- `query`: The user's specific question, scoped to a single concept
|
||||||
|
|
||||||
|
If the user's question spans multiple distinct concepts (e.g. routing and auth and caching), make a separate `query-docs` call per concept with the same library ID, unless the question is about how the concepts interact — combined queries dilute ranking and return shallow results for each topic.
|
||||||
|
|
||||||
|
### Step 4: Use the Documentation
|
||||||
|
|
||||||
|
Incorporate the fetched documentation into your response:
|
||||||
|
|
||||||
|
- Answer the user's question using current, accurate information
|
||||||
|
- Include relevant code examples from the docs
|
||||||
|
- Cite the library version when relevant
|
||||||
|
|
||||||
|
## Guidelines
|
||||||
|
|
||||||
|
- **Be specific**: Pass the user's full question as the query for better results, but keep each query to a single concept
|
||||||
|
- **One topic per query**: Split multi-topic questions into separate `query-docs` calls — resolve the library ID once, then query per concept, unless the question is about how the concepts interact
|
||||||
|
- **Version awareness**: When users mention versions ("Next.js 15", "React 19"), use version-specific library IDs if available from the resolution step
|
||||||
|
- **Prefer official sources**: When multiple matches exist, prefer official/primary packages over community forks
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: nixos-maintainer
|
||||||
|
description: Maintain this NixOS and Home Manager flake by inspecting, changing, simplifying, or validating its configuration. Use for system configuration work in the NixOS repository, not generic Nix questions or unrelated projects.
|
||||||
|
---
|
||||||
|
|
||||||
|
# NixOS Maintainer
|
||||||
|
|
||||||
|
Read the applicable `AGENTS.md` and the complete current owner of the behavior
|
||||||
|
before editing. Trace its imports through the host, profile, and capability
|
||||||
|
modules so the change lands at the narrowest shared level that matches its real
|
||||||
|
scope.
|
||||||
|
|
||||||
|
Prefer an existing module or native NixOS/Home Manager option. Keep mutable,
|
||||||
|
secret, credential, and application-owned state outside the Nix store. Verify
|
||||||
|
unfamiliar pinned interfaces against the exact package source or current primary
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
Preserve unrelated work. Format touched Nix files and use the narrowest useful
|
||||||
|
evaluation for configuration changes. Build affected hosts only when needed to
|
||||||
|
resolve a concrete concern or explicitly requested; instruction-only edits do
|
||||||
|
not need system builds. Do not add tests or migration/compatibility code by
|
||||||
|
default. Explain manual steps for breaking changes.
|
||||||
|
|
||||||
|
Do not switch or boot a generation unless the user explicitly requests activation.
|
||||||
@@ -41,15 +41,6 @@ in
|
|||||||
devices = builtins.attrNames syncDevices;
|
devices = builtins.attrNames syncDevices;
|
||||||
ignorePatterns = [ "**/.zk" ];
|
ignorePatterns = [ "**/.zk" ];
|
||||||
};
|
};
|
||||||
bruno = {
|
|
||||||
path =
|
|
||||||
if config.facts.machine.name == "orion" then
|
|
||||||
"${config.home.homeDirectory}/bruno"
|
|
||||||
else
|
|
||||||
"${config.xdg.userDirs.projects}/bruno";
|
|
||||||
label = "bruno";
|
|
||||||
devices = builtins.attrNames syncDevices;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
devices = syncDevices;
|
devices = syncDevices;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,103 +1,27 @@
|
|||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
let
|
||||||
kanagawa = import ./_kanagawa.nix;
|
|
||||||
homeModules = config.flake.modules.homeManager;
|
homeModules = config.flake.modules.homeManager;
|
||||||
|
|
||||||
kittySingleInstance =
|
|
||||||
pkgs:
|
|
||||||
pkgs.symlinkJoin {
|
|
||||||
name = "kitty-single";
|
|
||||||
paths = [ pkgs.kitty ];
|
|
||||||
meta = pkgs.kitty.meta;
|
|
||||||
buildInputs = [ pkgs.makeWrapper ];
|
|
||||||
postBuild = ''
|
|
||||||
wrapProgram $out/bin/kitty --add-flags "-1"
|
|
||||||
rm $out/share/applications/kitty.desktop
|
|
||||||
sed 's/Exec=kitty/Exec=kitty -1/g' ${pkgs.kitty}/share/applications/kitty.desktop > $out/share/applications/kitty.desktop
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.homeManager.terminal-foot =
|
|
||||||
{
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
palette = kanagawa.palette;
|
|
||||||
hex = lib.removePrefix "#";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
programs.foot = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
main = {
|
|
||||||
font = "JetBrains Mono:style=Medium:size=11:fontfeatures=-liga:fontfeatures=-calt";
|
|
||||||
font-bold = "JetBrains Mono:style=Bold:size=11:fontfeatures=-liga:fontfeatures=-calt";
|
|
||||||
font-italic = "JetBrains Mono:style=Medium Italic:size=11:fontfeatures=-liga:fontfeatures=-calt";
|
|
||||||
font-bold-italic = "JetBrains Mono:style=Bold Italic:size=11:fontfeatures=-liga:fontfeatures=-calt";
|
|
||||||
gamma-correct-blending = "yes";
|
|
||||||
pad = "3x3";
|
|
||||||
};
|
|
||||||
|
|
||||||
tweak.box-drawing-base-thickness = 0.1;
|
|
||||||
|
|
||||||
bell.system = "no";
|
|
||||||
|
|
||||||
scrollback.lines = 10000;
|
|
||||||
|
|
||||||
text-bindings."\\x0a" = "Shift+Return Shift+KP_Enter";
|
|
||||||
|
|
||||||
colors-dark = {
|
|
||||||
background = hex palette.background;
|
|
||||||
foreground = hex palette.foreground;
|
|
||||||
selection-background = hex palette.selectionBackground;
|
|
||||||
selection-foreground = hex palette.selectionForeground;
|
|
||||||
urls = hex palette.url;
|
|
||||||
cursor = "${hex palette.background} ${hex palette.cursor}";
|
|
||||||
|
|
||||||
regular0 = hex palette.terminal.color0;
|
|
||||||
regular1 = hex palette.terminal.color1;
|
|
||||||
regular2 = hex palette.terminal.color2;
|
|
||||||
regular3 = hex palette.terminal.color3;
|
|
||||||
regular4 = hex palette.terminal.color4;
|
|
||||||
regular5 = hex palette.terminal.color5;
|
|
||||||
regular6 = hex palette.terminal.color6;
|
|
||||||
regular7 = hex palette.terminal.color7;
|
|
||||||
|
|
||||||
bright0 = hex palette.terminal.color8;
|
|
||||||
bright1 = hex palette.terminal.color9;
|
|
||||||
bright2 = hex palette.terminal.color10;
|
|
||||||
bright3 = hex palette.terminal.color11;
|
|
||||||
bright4 = hex palette.terminal.color12;
|
|
||||||
bright5 = hex palette.terminal.color13;
|
|
||||||
bright6 = hex palette.terminal.color14;
|
|
||||||
bright7 = hex palette.terminal.color15;
|
|
||||||
|
|
||||||
"16" = hex palette.terminal.color16;
|
|
||||||
"17" = hex palette.terminal.color17;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
flake.modules.homeManager.terminal-kitty =
|
flake.modules.homeManager.terminal-kitty =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
theme = kanagawa;
|
kitty = pkgs.symlinkJoin {
|
||||||
palette = theme.palette;
|
name = "kitty-single";
|
||||||
kitty = kittySingleInstance pkgs;
|
paths = [ pkgs.kitty ];
|
||||||
|
meta = pkgs.kitty.meta;
|
||||||
|
buildInputs = [ pkgs.makeWrapper ];
|
||||||
|
postBuild = ''
|
||||||
|
wrapProgram $out/bin/kitty --add-flags "-1"
|
||||||
|
rm $out/share/applications/kitty.desktop
|
||||||
|
sed 's/^Exec=kitty/Exec=kitty -1/' ${pkgs.kitty}/share/applications/kitty.desktop > $out/share/applications/kitty.desktop
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
programs.kitty = {
|
programs.kitty = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = kitty;
|
package = kitty;
|
||||||
font = {
|
|
||||||
name = "JetBrains Mono";
|
|
||||||
size = 11;
|
|
||||||
};
|
|
||||||
settings = {
|
settings = {
|
||||||
disable_ligatures = "always";
|
disable_ligatures = "always";
|
||||||
scrollback_lines = 10000;
|
scrollback_lines = 10000;
|
||||||
@@ -107,48 +31,6 @@ in
|
|||||||
update_check_interval = 0;
|
update_check_interval = 0;
|
||||||
};
|
};
|
||||||
keybindings."shift+enter" = "send_text all \\x0a";
|
keybindings."shift+enter" = "send_text all \\x0a";
|
||||||
extraConfig = ''
|
|
||||||
# Nerd Fonts v3.4.0
|
|
||||||
symbol_map U+e000-U+e00a,U+e0a0-U+e0a2,U+e0a3,U+e0b0-U+e0b3,U+e0b4-U+e0c8,U+e0ca,U+e0cc-U+e0d7,U+e200-U+e2a9,U+e300-U+e3e3,U+e5fa-U+e6b7,U+e700-U+e8ef,U+ea60-U+ec1e,U+ed00-U+efce,U+f000-U+f2ff,U+f300-U+f381,U+f400-U+f533,U+f0001-U+f1af0 Symbols Nerd Font Mono
|
|
||||||
|
|
||||||
## name: ${theme.displayName}
|
|
||||||
## license: MIT
|
|
||||||
## author: Tommaso Laurenzi
|
|
||||||
## upstream: https://github.com/rebelot/kanagawa.nvim/
|
|
||||||
|
|
||||||
background ${palette.background}
|
|
||||||
foreground ${palette.foreground}
|
|
||||||
selection_background ${palette.selectionBackground}
|
|
||||||
selection_foreground ${palette.selectionForeground}
|
|
||||||
url_color ${palette.url}
|
|
||||||
cursor ${palette.cursor}
|
|
||||||
|
|
||||||
active_tab_background ${palette.background}
|
|
||||||
active_tab_foreground ${palette.selectionForeground}
|
|
||||||
inactive_tab_background ${palette.background}
|
|
||||||
inactive_tab_foreground ${palette.muted}
|
|
||||||
|
|
||||||
color0 ${palette.terminal.color0}
|
|
||||||
color1 ${palette.terminal.color1}
|
|
||||||
color2 ${palette.terminal.color2}
|
|
||||||
color3 ${palette.terminal.color3}
|
|
||||||
color4 ${palette.terminal.color4}
|
|
||||||
color5 ${palette.terminal.color5}
|
|
||||||
color6 ${palette.terminal.color6}
|
|
||||||
color7 ${palette.terminal.color7}
|
|
||||||
|
|
||||||
color8 ${palette.terminal.color8}
|
|
||||||
color9 ${palette.terminal.color9}
|
|
||||||
color10 ${palette.terminal.color10}
|
|
||||||
color11 ${palette.terminal.color11}
|
|
||||||
color12 ${palette.terminal.color12}
|
|
||||||
color13 ${palette.terminal.color13}
|
|
||||||
color14 ${palette.terminal.color14}
|
|
||||||
color15 ${palette.terminal.color15}
|
|
||||||
|
|
||||||
color16 ${palette.terminal.color16}
|
|
||||||
color17 ${palette.terminal.color17}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
systemd.user.services.kitty-daemon = {
|
systemd.user.services.kitty-daemon = {
|
||||||
Unit = {
|
Unit = {
|
||||||
@@ -166,19 +48,6 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.primary-terminal-foot =
|
|
||||||
{ config, lib, ... }:
|
|
||||||
{
|
|
||||||
imports = [ homeModules.terminal-foot ];
|
|
||||||
|
|
||||||
desktop.commands.terminal = [ (lib.getExe config.programs.foot.package) ];
|
|
||||||
|
|
||||||
xdg.terminal-exec = {
|
|
||||||
enable = true;
|
|
||||||
settings.default = [ "foot.desktop" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
flake.modules.homeManager.primary-terminal-kitty =
|
flake.modules.homeManager.primary-terminal-kitty =
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,91 +1,2 @@
|
|||||||
{ config, ... }:
|
# Select a complete theme module: plugins, assets and behavior as well as colors.
|
||||||
let
|
{ imports = [ ./_themes/kanagawa.nix ]; }
|
||||||
hmModules = config.flake.modules.homeManager;
|
|
||||||
cursor = {
|
|
||||||
name = "phinger-cursors-light";
|
|
||||||
packageName = "phinger-cursors";
|
|
||||||
size = 24;
|
|
||||||
};
|
|
||||||
mkCursor = pkgs: cursor // { package = pkgs.${cursor.packageName}; };
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.modules.nixos.theme =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
let
|
|
||||||
cursorTheme = mkCursor pkgs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home-manager.sharedModules = [ hmModules.theme ];
|
|
||||||
environment.systemPackages = [ cursorTheme.package ];
|
|
||||||
};
|
|
||||||
|
|
||||||
flake.modules.homeManager.theme =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
let
|
|
||||||
cursorTheme = mkCursor pkgs;
|
|
||||||
version = "unstable-2025-10-23";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "Fausto-Korpsvart";
|
|
||||||
repo = "Kanagawa-GKT-Theme";
|
|
||||||
rev = "55ca4ba249eba21f861b9866b71ab41bb8930318";
|
|
||||||
hash = "sha256-UdMoMx2DoovcxSp/zBZ3PRv/Qpj+prd0uPm1gmdak2E=";
|
|
||||||
};
|
|
||||||
kanagawaGtkTheme = pkgs.stdenvNoCC.mkDerivation {
|
|
||||||
pname = "kanagawa-gtk-theme";
|
|
||||||
inherit src version;
|
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgs.sassc ];
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
mkdir -p "$out/share/themes"
|
|
||||||
bash ./themes/install.sh \
|
|
||||||
--dest "$out/share/themes" \
|
|
||||||
--name Kanagawa \
|
|
||||||
--color dark
|
|
||||||
|
|
||||||
rm -r "$out/share/themes/Kanagawa-Dark/gtk-2.0"
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.pointerCursor = {
|
|
||||||
enable = true;
|
|
||||||
inherit (cursorTheme)
|
|
||||||
name
|
|
||||||
package
|
|
||||||
size
|
|
||||||
;
|
|
||||||
dotIcons.enable = false;
|
|
||||||
gtk.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
gtk = {
|
|
||||||
enable = true;
|
|
||||||
theme = {
|
|
||||||
name = "Kanagawa-Dark";
|
|
||||||
package = kanagawaGtkTheme;
|
|
||||||
};
|
|
||||||
gtk4.theme = null;
|
|
||||||
iconTheme = {
|
|
||||||
name = "Kanagawa";
|
|
||||||
package = pkgs.kanagawa-icon-theme.overrideAttrs (_: {
|
|
||||||
inherit src version;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
qt = {
|
|
||||||
enable = true;
|
|
||||||
platformTheme.name = "gtk3";
|
|
||||||
};
|
|
||||||
|
|
||||||
xdg.systemDirs.data = [
|
|
||||||
"${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}"
|
|
||||||
"${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
|
||||||
homeModules = config.flake.modules.homeManager;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
flake.modules.homeManager.transcription =
|
flake.modules.homeManager.transcription =
|
||||||
{
|
{
|
||||||
@@ -37,6 +34,7 @@ in
|
|||||||
${builtins.readFile ./_diarize-transcript.py}
|
${builtins.readFile ./_diarize-transcript.py}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
whisper = pkgs.whisper-cpp;
|
||||||
prepareDiarizationModel = pkgs.writeShellApplication {
|
prepareDiarizationModel = pkgs.writeShellApplication {
|
||||||
name = "prepare-transcription-diarization-model";
|
name = "prepare-transcription-diarization-model";
|
||||||
runtimeInputs = with pkgs; [
|
runtimeInputs = with pkgs; [
|
||||||
@@ -72,18 +70,28 @@ in
|
|||||||
diarizeTranscript
|
diarizeTranscript
|
||||||
ffmpeg
|
ffmpeg
|
||||||
findutils
|
findutils
|
||||||
whisper-cpp-vulkan
|
whisper
|
||||||
];
|
];
|
||||||
text = builtins.readFile ./_transcribe-recordings.sh;
|
text = builtins.readFile ./_transcribe-recordings.sh;
|
||||||
};
|
};
|
||||||
|
home = config.home.homeDirectory;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = with pkgs; [
|
home.packages = [
|
||||||
ffmpeg
|
pkgs.ffmpeg
|
||||||
prepareDiarizationModel
|
prepareDiarizationModel
|
||||||
whisper-cpp-vulkan
|
whisper
|
||||||
];
|
];
|
||||||
|
|
||||||
|
home.activation.createTranscriptionLayout = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
${pkgs.coreutils}/bin/mkdir -p \
|
||||||
|
"${home}/sync/notes/transcripts" \
|
||||||
|
"${home}/sync/recordings/inbox" \
|
||||||
|
"${home}/sync/recordings/processing" \
|
||||||
|
"${home}/sync/recordings/archive" \
|
||||||
|
"${home}/sync/recordings/failed"
|
||||||
|
'';
|
||||||
|
|
||||||
systemd.user.services.transcribe-recordings = {
|
systemd.user.services.transcribe-recordings = {
|
||||||
Unit.Description = "Transcribe synchronized recordings with whisper.cpp";
|
Unit.Description = "Transcribe synchronized recordings with whisper.cpp";
|
||||||
|
|
||||||
@@ -91,7 +99,8 @@ in
|
|||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = lib.getExe transcribeRecordings;
|
ExecStart = lib.getExe transcribeRecordings;
|
||||||
Environment = [
|
Environment = [
|
||||||
"TRANSCRIBE_ENGINE_VERSION=${pkgs.whisper-cpp-vulkan.version}"
|
"TRANSCRIBE_ENGINE_ACCELERATION=CPU"
|
||||||
|
"TRANSCRIBE_ENGINE_VERSION=${whisper.version}"
|
||||||
"TRANSCRIBE_MODEL=${model}"
|
"TRANSCRIBE_MODEL=${model}"
|
||||||
''"TRANSCRIBE_MODEL_NAME=${modelName} multilingual"''
|
''"TRANSCRIBE_MODEL_NAME=${modelName} multilingual"''
|
||||||
"TRANSCRIBE_MODEL_SHA256=${modelSha256}"
|
"TRANSCRIBE_MODEL_SHA256=${modelSha256}"
|
||||||
@@ -99,26 +108,25 @@ in
|
|||||||
"TRANSCRIBE_DIARIZATION_MODEL=${diarizationModel}"
|
"TRANSCRIBE_DIARIZATION_MODEL=${diarizationModel}"
|
||||||
"TRANSCRIBE_DIARIZATION_MODEL_NAME=${diarizationModelName}"
|
"TRANSCRIBE_DIARIZATION_MODEL_NAME=${diarizationModelName}"
|
||||||
"TRANSCRIBE_DIARIZATION_MODEL_REVISION=${diarizationModelRevision}"
|
"TRANSCRIBE_DIARIZATION_MODEL_REVISION=${diarizationModelRevision}"
|
||||||
"TRANSCRIBE_SYNC_ROOT=${config.home.homeDirectory}/sync"
|
"TRANSCRIBE_SYNC_ROOT=${home}/sync"
|
||||||
];
|
];
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 60;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Install.WantedBy = [ "default.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.user.timers.transcribe-recordings = {
|
systemd.user.paths.transcribe-recordings = {
|
||||||
Unit.Description = "Transcribe new recordings every two minutes";
|
Unit.Description = "Watch for synchronized recordings";
|
||||||
|
|
||||||
Timer = {
|
Path.PathChanged = "${home}/sync/recordings/inbox";
|
||||||
OnCalendar = "*:0/2";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Install.WantedBy = [ "timers.target" ];
|
Install.WantedBy = [ "paths.target" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.transcription =
|
flake.modules.nixos.transcription = {
|
||||||
{ ... }:
|
home-manager.sharedModules = [ config.flake.modules.homeManager.transcription ];
|
||||||
{
|
};
|
||||||
home-manager.sharedModules = [ homeModules.transcription ];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
+133
-11
@@ -1,10 +1,7 @@
|
|||||||
{ config, inputs, ... }:
|
{ config, inputs, ... }:
|
||||||
let
|
|
||||||
homeModules = config.flake.modules.homeManager;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
flake.modules.nixos.walker = {
|
flake.modules.nixos.walker = {
|
||||||
home-manager.sharedModules = [ homeModules.walker ];
|
home-manager.sharedModules = [ config.flake.modules.homeManager.walker ];
|
||||||
|
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
extra-substituters = [
|
extra-substituters = [
|
||||||
@@ -19,8 +16,33 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.homeManager.walker =
|
flake.modules.homeManager.walker =
|
||||||
{ lib, pkgs, ... }:
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
|
homeDir = config.home.homeDirectory;
|
||||||
|
projectRoots = [
|
||||||
|
{
|
||||||
|
scope = "work";
|
||||||
|
path = "${homeDir}/yookr/projects";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++
|
||||||
|
map
|
||||||
|
(scope: {
|
||||||
|
inherit scope;
|
||||||
|
path = "${config.xdg.userDirs.projects}/${scope}";
|
||||||
|
})
|
||||||
|
[
|
||||||
|
"own"
|
||||||
|
"ext"
|
||||||
|
"forks"
|
||||||
|
];
|
||||||
|
walkerDefaults = builtins.fromTOML (builtins.readFile "${inputs.walker}/resources/config.toml");
|
||||||
|
|
||||||
launcher = pkgs.writeShellApplication {
|
launcher = pkgs.writeShellApplication {
|
||||||
name = "walker-launcher";
|
name = "walker-launcher";
|
||||||
runtimeInputs = [ pkgs.libressl.nc ];
|
runtimeInputs = [ pkgs.libressl.nc ];
|
||||||
@@ -28,22 +50,122 @@ in
|
|||||||
exec nc -U "$XDG_RUNTIME_DIR/walker/walker.sock"
|
exec nc -U "$XDG_RUNTIME_DIR/walker/walker.sock"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
openProject = pkgs.writeShellApplication {
|
||||||
|
name = "open-project";
|
||||||
|
text = ''
|
||||||
|
project_path="''${1:-}"
|
||||||
|
if [[ -z "$project_path" ]]; then
|
||||||
|
IFS= read -r project_path || [[ -n "$project_path" ]]
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec ${lib.getExe config.xdg.terminal-exec.package} --dir="$project_path" \
|
||||||
|
${lib.getExe pkgs.zsh} -lic 'nvim .; exec zsh -l'
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ inputs.walker.homeManagerModules.default ];
|
imports = [ inputs.walker.homeManagerModules.default ];
|
||||||
|
|
||||||
desktop.commands.launcher = [ (lib.getExe launcher) ];
|
desktop.commands.launcher = [ (lib.getExe launcher) ];
|
||||||
|
home.packages = [ openProject ];
|
||||||
|
|
||||||
|
xdg.configFile."elephant/menus/projects.lua".text = ''
|
||||||
|
Name = "projects"
|
||||||
|
NamePretty = "Projects"
|
||||||
|
Description = "Projects and workspaces"
|
||||||
|
Icon = "folder"
|
||||||
|
Action = "${lib.getExe openProject}"
|
||||||
|
SearchName = true
|
||||||
|
RefreshOnChange = {
|
||||||
|
${lib.concatMapStringsSep "\n " (root: ''"${root.path}",'') projectRoots}
|
||||||
|
}
|
||||||
|
|
||||||
|
local roots = {
|
||||||
|
${lib.concatMapStringsSep "\n " (
|
||||||
|
root: ''{ scope = "${root.scope}", path = "${root.path}" },''
|
||||||
|
) projectRoots}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function repositories(root)
|
||||||
|
return io.popen(
|
||||||
|
"${lib.getExe pkgs.findutils} " .. root ..
|
||||||
|
" -mindepth 1 \\( -type d \\( -name .archive -o -name .worktrees \\) -prune \\)" ..
|
||||||
|
" -o \\( -name .git -print \\) 2>/dev/null"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetEntries()
|
||||||
|
local entries = {
|
||||||
|
{
|
||||||
|
Text = "Yookr",
|
||||||
|
Subtext = "Company workspace",
|
||||||
|
Value = "${homeDir}/yookr",
|
||||||
|
Keywords = { "work", "company", "workbench" },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, root in ipairs(roots) do
|
||||||
|
local handle = repositories(root.path)
|
||||||
|
if handle then
|
||||||
|
for git_path in handle:lines() do
|
||||||
|
local project = git_path:gsub("/%.git$", "")
|
||||||
|
local relative = project:sub(#root.path + 2)
|
||||||
|
table.insert(entries, {
|
||||||
|
Text = project:match("([^/]+)$"),
|
||||||
|
Subtext = root.scope .. " · " .. relative,
|
||||||
|
Value = project,
|
||||||
|
Keywords = { root.scope, relative, project },
|
||||||
|
})
|
||||||
|
end
|
||||||
|
handle:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return entries
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
|
||||||
programs.walker = {
|
programs.walker = {
|
||||||
enable = true;
|
enable = true;
|
||||||
runAsService = true;
|
runAsService = true;
|
||||||
|
|
||||||
config.providers.prefixes = [
|
config.theme = "constellation";
|
||||||
{
|
themes.constellation = {
|
||||||
provider = "bitwarden";
|
layouts.layout =
|
||||||
prefix = "?";
|
lib.replaceStrings
|
||||||
}
|
[ ''<property name="height-request">570</property>'' ]
|
||||||
];
|
[ ''<property name="height-request">460</property>'' ]
|
||||||
|
(builtins.readFile "${inputs.walker}/resources/themes/default/layout.xml");
|
||||||
|
style = lib.mkBefore (
|
||||||
|
builtins.readFile "${inputs.walker}/resources/themes/default/style.css"
|
||||||
|
+ ''
|
||||||
|
.box-wrapper {
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
.search-container, .item-box, .preview { border-radius: 6px; }
|
||||||
|
.input { padding: 8px 10px; }
|
||||||
|
.item-box { padding: 5px 8px; }
|
||||||
|
.large-icons { -gtk-icon-size: 24px; }
|
||||||
|
.item-image-text { font-size: 24px; }
|
||||||
|
.item-subtext { opacity: 0.75; }
|
||||||
|
.item-quick-activation { padding: 3px 5px; }
|
||||||
|
.keybinds { padding-top: 6px; }
|
||||||
|
.keybind-bind { opacity: 0.65; }
|
||||||
|
''
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
config.providers = {
|
||||||
|
default = walkerDefaults.providers.default ++ [ "menus:projects" ];
|
||||||
|
prefixes = walkerDefaults.providers.prefixes ++ [
|
||||||
|
{
|
||||||
|
provider = "bitwarden";
|
||||||
|
prefix = "?";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,18 @@
|
|||||||
{
|
{
|
||||||
flake.modules.nixos.yookr-dev =
|
flake.modules.nixos.yookr-dev = {
|
||||||
{ config, ... }:
|
security.pki.certificateFiles = [
|
||||||
{
|
./yookr-dev/zenith-rootCA.pem
|
||||||
security.pki.certificateFiles = [
|
./yookr-dev/polaris-rootCA.pem
|
||||||
./yookr-dev/zenith-rootCA.pem
|
];
|
||||||
./yookr-dev/polaris-rootCA.pem
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [
|
||||||
5173
|
5173
|
||||||
5174
|
5174
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.extraHosts = ''
|
networking.extraHosts = ''
|
||||||
127.0.0.1 local.management.yookr.org
|
127.0.0.1 local.management.yookr.org
|
||||||
127.0.0.1 local.dashboard.yookr.org
|
127.0.0.1 local.dashboard.yookr.org
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
flake.modules.homeManager.zed = {
|
|
||||||
programs.zed-editor.enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
+1
-3
@@ -266,9 +266,7 @@ in
|
|||||||
machines
|
machines
|
||||||
topology
|
topology
|
||||||
;
|
;
|
||||||
services = lib.mapAttrs (_: service: {
|
services = lib.mapAttrs (_: service: removeAttrs service [ "origin" ]) osConfig.facts.services;
|
||||||
inherit (service) scheme domain;
|
|
||||||
}) osConfig.facts.services;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,15 +7,10 @@
|
|||||||
let
|
let
|
||||||
mkHost =
|
mkHost =
|
||||||
name: machine:
|
name: machine:
|
||||||
{ pkgs, ... }:
|
hostArgs@{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
account = config.facts.account;
|
account = config.facts.account;
|
||||||
machineFacts = machine // {
|
services = lib.mapAttrs (_: service: removeAttrs service [ "origin" ]) config.facts.services;
|
||||||
inherit name;
|
|
||||||
};
|
|
||||||
services = lib.mapAttrs (_: service: {
|
|
||||||
inherit (service) scheme domain;
|
|
||||||
}) config.facts.services;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
@@ -30,7 +25,9 @@ let
|
|||||||
topology
|
topology
|
||||||
;
|
;
|
||||||
inherit services;
|
inherit services;
|
||||||
machine = machineFacts;
|
machine = machine // {
|
||||||
|
inherit name;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.hostName = name;
|
networking.hostName = name;
|
||||||
@@ -38,9 +35,12 @@ let
|
|||||||
|
|
||||||
programs.zsh.enable = true;
|
programs.zsh.enable = true;
|
||||||
|
|
||||||
|
sops.secrets.hashed-password.neededForUsers = true;
|
||||||
|
|
||||||
users.users.${account.name} = {
|
users.users.${account.name} = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
home = account.homeDirectory;
|
home = account.homeDirectory;
|
||||||
|
hashedPasswordFile = hostArgs.config.sops.secrets.hashed-password.path;
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"wheel"
|
"wheel"
|
||||||
"networkmanager"
|
"networkmanager"
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
type = "gpt";
|
type = "gpt";
|
||||||
partitions = {
|
partitions = {
|
||||||
boot = {
|
boot = {
|
||||||
name = "boot";
|
|
||||||
size = "1M";
|
size = "1M";
|
||||||
type = "EF02";
|
type = "EF02";
|
||||||
};
|
};
|
||||||
@@ -25,7 +24,6 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
root = {
|
root = {
|
||||||
name = "root";
|
|
||||||
size = "100%";
|
size = "100%";
|
||||||
content = {
|
content = {
|
||||||
type = "lvm_pv";
|
type = "lvm_pv";
|
||||||
@@ -43,7 +41,6 @@
|
|||||||
type = "filesystem";
|
type = "filesystem";
|
||||||
format = "ext4";
|
format = "ext4";
|
||||||
mountpoint = "/";
|
mountpoint = "/";
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,16 +7,9 @@
|
|||||||
boot.initrd.availableKernelModules = [
|
boot.initrd.availableKernelModules = [
|
||||||
"ata_piix"
|
"ata_piix"
|
||||||
"uhci_hcd"
|
"uhci_hcd"
|
||||||
"virtio_pci"
|
|
||||||
"virtio_scsi"
|
|
||||||
"sd_mod"
|
"sd_mod"
|
||||||
"sr_mod"
|
"sr_mod"
|
||||||
];
|
];
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
let
|
||||||
nixosModules = config.flake.modules.nixos;
|
nixosModules = config.flake.modules.nixos;
|
||||||
account = config.facts.account;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
facts.machines.orion = {
|
facts.machines.orion = {
|
||||||
@@ -11,28 +10,26 @@ in
|
|||||||
stateVersion = "24.05";
|
stateVersion = "24.05";
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.orion =
|
flake.modules.nixos.orion = {
|
||||||
{ ... }:
|
imports = [
|
||||||
{
|
nixosModules.host-base
|
||||||
imports = [
|
|
||||||
nixosModules.host-base
|
|
||||||
|
|
||||||
nixosModules.sops-host-ssh-key
|
nixosModules.sops-host-ssh-key
|
||||||
nixosModules.openssh
|
nixosModules.openssh
|
||||||
nixosModules.caddy
|
nixosModules.caddy
|
||||||
nixosModules.server-firewall
|
nixosModules.server-firewall
|
||||||
nixosModules.sudo-ssh-agent-auth
|
nixosModules.sudo-ssh-agent-auth
|
||||||
# nixosModules.vps-insights
|
nixosModules.vaultwarden
|
||||||
nixosModules.vaultwarden
|
nixosModules.radicale
|
||||||
nixosModules.radicale
|
nixosModules.actual
|
||||||
nixosModules.actual
|
nixosModules.gitea
|
||||||
nixosModules.gitea
|
nixosModules.transcription
|
||||||
./_hardware.nix
|
./_hardware.nix
|
||||||
./_disk.nix
|
./_disk.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.enableAllTerminfo = true;
|
environment.enableAllTerminfo = true;
|
||||||
|
|
||||||
users.users.${account.name}.linger = true;
|
users.users.${config.facts.account.name}.linger = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{ lib, modulesPath, ... }:
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
@@ -17,9 +12,7 @@
|
|||||||
"usb_storage"
|
"usb_storage"
|
||||||
"sd_mod"
|
"sd_mod"
|
||||||
];
|
];
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = "/dev/disk/by-uuid/bda7f8b9-2b3d-4190-8518-baa50490227e";
|
device = "/dev/disk/by-uuid/bda7f8b9-2b3d-4190-8518-baa50490227e";
|
||||||
@@ -35,10 +28,5 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
|
||||||
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
|
||||||
}
|
}
|
||||||
@@ -9,48 +9,40 @@ in
|
|||||||
{
|
{
|
||||||
facts.machines.polaris = {
|
facts.machines.polaris = {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
sshKeys = {
|
sshKeys.personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEVORk45HKkX7gaGGp90KsVyUy6t+fKhbWN/grjkf3cQ kiri@polaris";
|
||||||
personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEVORk45HKkX7gaGGp90KsVyUy6t+fKhbWN/grjkf3cQ kiri@polaris";
|
sshKeys.work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5DMV6EQzsscgEOE0912mNglUHTEl+LPnaWYjj0y57B kiri@polaris#work";
|
||||||
work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5DMV6EQzsscgEOE0912mNglUHTEl+LPnaWYjj0y57B kiri@polaris#work";
|
|
||||||
};
|
|
||||||
|
|
||||||
syncthingId = "6HBAKXB-DB3B4H2-BODCAXF-KD23H5W-6X5LGLC-ZJHZHLG-7U7YMGO-BB6IXQ3";
|
syncthingId = "6HBAKXB-DB3B4H2-BODCAXF-KD23H5W-6X5LGLC-ZJHZHLG-7U7YMGO-BB6IXQ3";
|
||||||
|
|
||||||
stateVersion = "24.05";
|
stateVersion = "24.05";
|
||||||
|
|
||||||
displays = {
|
displays = {
|
||||||
"LG Electronics LG ULTRAGEAR 103NTYT8R290" = {
|
"LG Electronics LG ULTRAGEAR 103NTYT8R290" = { };
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
"LG Electronics LG ULTRAGEAR 103NTJJ8R332" = {
|
"LG Electronics LG ULTRAGEAR 103NTJJ8R332" = {
|
||||||
primary = true;
|
primary = true;
|
||||||
x = 2560;
|
x = 2560;
|
||||||
y = 0;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.polaris =
|
flake.modules.nixos.polaris = {
|
||||||
{ ... }:
|
imports = [
|
||||||
{
|
nixosModules.workstation-base
|
||||||
imports = [
|
nixosModules.openssh
|
||||||
nixosModules.workstation-base
|
nixosModules.steam
|
||||||
nixosModules.openssh
|
./_hardware.nix
|
||||||
nixosModules.steam
|
]
|
||||||
./_hardware.nix
|
++ (with inputs.nixos-hardware.nixosModules; [
|
||||||
]
|
common-pc
|
||||||
++ (with inputs.nixos-hardware.nixosModules; [
|
common-pc-ssd
|
||||||
common-pc
|
common-cpu-amd
|
||||||
common-pc-ssd
|
common-gpu-amd
|
||||||
common-cpu-amd
|
]);
|
||||||
common-gpu-amd
|
|
||||||
]);
|
|
||||||
|
|
||||||
services.openssh.openFirewall = false;
|
services.openssh.openFirewall = false;
|
||||||
networking.firewall.extraInputRules = ''
|
networking.firewall.extraInputRules = ''
|
||||||
ip saddr 192.168.178.0/24 tcp dport 22 accept
|
ip saddr 192.168.178.0/24 tcp dport 22 accept
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -10,9 +10,6 @@
|
|||||||
"usb_storage"
|
"usb_storage"
|
||||||
"sd_mod"
|
"sd_mod"
|
||||||
];
|
];
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = "/dev/disk/by-uuid/6d8f6f33-c9d9-4e90-b496-d5b3ef5e9aeb";
|
device = "/dev/disk/by-uuid/6d8f6f33-c9d9-4e90-b496-d5b3ef5e9aeb";
|
||||||
@@ -28,9 +25,5 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
|
||||||
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
}
|
}
|
||||||
@@ -10,10 +10,8 @@ in
|
|||||||
facts.machines.zenith = {
|
facts.machines.zenith = {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
|
|
||||||
sshKeys = {
|
sshKeys.personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQy4k04gU7UpjBgyUQ57kUwxOdt79LvMCiCekXZeZhd kiri@zenith";
|
||||||
personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQy4k04gU7UpjBgyUQ57kUwxOdt79LvMCiCekXZeZhd kiri@zenith";
|
sshKeys.work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHJz5uHKm0/TiMNh/cmzrODHNZ8NgEEZe+47XnJwQGk kiri@zenith#work";
|
||||||
work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHJz5uHKm0/TiMNh/cmzrODHNZ8NgEEZe+47XnJwQGk kiri@zenith#work";
|
|
||||||
};
|
|
||||||
|
|
||||||
syncthingId = "5VMGBZJ-NNAVCLY-YWHCJLM-EJ3SCFC-EOGCECD-DGXC7EL-J5NXAAG-4JDEMQG";
|
syncthingId = "5VMGBZJ-NNAVCLY-YWHCJLM-EJ3SCFC-EOGCECD-DGXC7EL-J5NXAAG-4JDEMQG";
|
||||||
|
|
||||||
@@ -25,24 +23,30 @@ in
|
|||||||
height = 1920;
|
height = 1920;
|
||||||
refresh = 120.002;
|
refresh = 120.002;
|
||||||
};
|
};
|
||||||
|
"Philips Consumer Electronics Company PHL 346E2C UK02053006144" = {
|
||||||
|
x = 2048;
|
||||||
|
width = 3440;
|
||||||
|
height = 1440;
|
||||||
|
refresh = 99.982;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
stateVersion = "24.05";
|
stateVersion = "24.05";
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.zenith =
|
flake.modules.nixos.zenith = {
|
||||||
{ ... }:
|
imports = [
|
||||||
{
|
nixosModules.workstation-base
|
||||||
imports = [
|
nixosModules.laptop-power
|
||||||
nixosModules.workstation-base
|
nixosModules.sharepoint-reference
|
||||||
nixosModules.laptop-power
|
./_hardware.nix
|
||||||
nixosModules.transcription
|
inputs.nixos-hardware.nixosModules.lenovo-yoga-7-14ARH7-amdgpu
|
||||||
{
|
];
|
||||||
hardware.enableRedistributableFirmware = true;
|
|
||||||
services.fwupd.enable = true;
|
services.fwupd.enable = true;
|
||||||
}
|
services.teamviewer.enable = true;
|
||||||
./_hardware.nix
|
# Temporary Xorg session for remote support.
|
||||||
inputs.nixos-hardware.nixosModules.lenovo-yoga-7-14ARH7-amdgpu
|
# services.xserver.enable = true;
|
||||||
];
|
# services.xserver.desktopManager.xfce.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -14,8 +14,7 @@ in
|
|||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
nixosModules.nix
|
nixosModules.nix
|
||||||
nixosModules.locale
|
nixosModules.locale
|
||||||
nixosModules.sops-password
|
nixosModules.sops
|
||||||
nixosModules.helix-cache
|
|
||||||
];
|
];
|
||||||
|
|
||||||
home-manager = {
|
home-manager = {
|
||||||
@@ -26,7 +25,7 @@ in
|
|||||||
hmModules.facts
|
hmModules.facts
|
||||||
hmModules.syncthing
|
hmModules.syncthing
|
||||||
hmModules.shell
|
hmModules.shell
|
||||||
hmModules.primary-editor-helix
|
hmModules.primary-editor-neovim
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,22 @@
|
|||||||
let
|
let
|
||||||
nixosModules = config.flake.modules.nixos;
|
nixosModules = config.flake.modules.nixos;
|
||||||
homeModules = config.flake.modules.homeManager;
|
homeModules = config.flake.modules.homeManager;
|
||||||
account = config.facts.account;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.nixos.workstation-base = {
|
flake.modules.nixos.workstation-base = {
|
||||||
imports = [
|
imports = [
|
||||||
nixosModules.host-base
|
nixosModules.host-base
|
||||||
|
|
||||||
|
nixosModules.adb
|
||||||
nixosModules.audio
|
nixosModules.audio
|
||||||
nixosModules.bluetooth
|
nixosModules.bluetooth
|
||||||
nixosModules.flatpak
|
nixosModules.flatpak
|
||||||
nixosModules.fonts
|
nixosModules.fonts
|
||||||
|
nixosModules.evolution
|
||||||
nixosModules.network-manager
|
nixosModules.network-manager
|
||||||
nixosModules.nftables-firewall
|
nixosModules.nftables-firewall
|
||||||
nixosModules.niri
|
nixosModules.niri
|
||||||
|
nixosModules.handy
|
||||||
nixosModules.notes
|
nixosModules.notes
|
||||||
nixosModules.plymouth
|
nixosModules.plymouth
|
||||||
nixosModules.printing
|
nixosModules.printing
|
||||||
@@ -30,12 +32,10 @@ in
|
|||||||
nixosModules.yookr-dev
|
nixosModules.yookr-dev
|
||||||
];
|
];
|
||||||
|
|
||||||
services.dbus.implementation = "broker";
|
|
||||||
|
|
||||||
programs.nix-ld.enable = true;
|
programs.nix-ld.enable = true;
|
||||||
environment.localBinInPath = true;
|
environment.localBinInPath = true;
|
||||||
|
|
||||||
home-manager.users.${account.name}.imports = [
|
home-manager.users.${config.facts.account.name}.imports = [
|
||||||
homeModules.workstation-base
|
homeModules.workstation-base
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@@ -44,9 +44,9 @@ in
|
|||||||
imports = [
|
imports = [
|
||||||
homeModules.passwords
|
homeModules.passwords
|
||||||
homeModules.clipboard
|
homeModules.clipboard
|
||||||
|
homeModules.handy
|
||||||
homeModules.desktop-commands
|
homeModules.desktop-commands
|
||||||
homeModules.dev-tools
|
homeModules.dev-tools
|
||||||
homeModules.zed
|
|
||||||
homeModules.xdg
|
homeModules.xdg
|
||||||
homeModules.workstation-apps
|
homeModules.workstation-apps
|
||||||
homeModules.vivaldi
|
homeModules.vivaldi
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
keys:
|
|
||||||
- &admin age122w85pqj508ukv0rd388mahecgfckmpgnsgz0zcyec37ljae2epsdnvxpl
|
|
||||||
- &orion age1upsxyevxdv3xax8jhnffclryuve70k63cjrca69ffds4h2m3nvuql59ufw
|
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: secrets.yaml$
|
- path_regex: secrets.yaml$
|
||||||
key_groups:
|
age: >-
|
||||||
- age:
|
age122w85pqj508ukv0rd388mahecgfckmpgnsgz0zcyec37ljae2epsdnvxpl,
|
||||||
- *admin
|
age1upsxyevxdv3xax8jhnffclryuve70k63cjrca69ffds4h2m3nvuql59ufw
|
||||||
- *orion
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
account = config.facts.account;
|
|
||||||
nixosModules = config.flake.modules.nixos;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.modules.nixos.sops-password =
|
|
||||||
{ config, ... }:
|
|
||||||
{
|
|
||||||
imports = [ nixosModules.sops ];
|
|
||||||
|
|
||||||
sops.secrets.hashed-password.neededForUsers = true;
|
|
||||||
|
|
||||||
users.users.${account.name}.hashedPasswordFile = config.sops.secrets.hashed-password.path;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -15,23 +15,18 @@ in
|
|||||||
sops.defaultSopsFile = ./secrets.yaml;
|
sops.defaultSopsFile = ./secrets.yaml;
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.sops-admin-key-file =
|
flake.modules.nixos.sops-admin-key-file = {
|
||||||
{ lib, ... }:
|
imports = [ nixosModules.sops ];
|
||||||
let
|
|
||||||
adminKeyDir = builtins.dirOf sopsAdminKeyPath;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ nixosModules.sops ];
|
|
||||||
|
|
||||||
home-manager.sharedModules = [ hmModules.sops ];
|
home-manager.sharedModules = [ hmModules.sops ];
|
||||||
|
|
||||||
sops.age.keyFile = sopsAdminKeyPath;
|
sops.age.keyFile = sopsAdminKeyPath;
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d ${adminKeyDir} 0750 root wheel -"
|
"d ${builtins.dirOf sopsAdminKeyPath} 0750 root wheel -"
|
||||||
"z ${sopsAdminKeyPath} 0640 root wheel -"
|
"z ${sopsAdminKeyPath} 0640 root wheel -"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.sops-host-ssh-key = {
|
flake.modules.nixos.sops-host-ssh-key = {
|
||||||
imports = [ nixosModules.sops ];
|
imports = [ nixosModules.sops ];
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- Configured startup: nvim --headless -i NONE '+lua local ok,e=pcall(dofile,"tests/neovim-ergonomics.lua"); if not ok then print(e); vim.cmd.cquit() end' '+qa!'
|
||||||
|
assert(vim.o.linebreak)
|
||||||
|
vim.api.nvim_buf_set_lines(0, 0, -1, false, { string.rep("word ", 80), "two", "three", "four" })
|
||||||
|
vim.cmd("normal gg0j")
|
||||||
|
assert(vim.fn.line(".") == 1 and vim.fn.col(".") > 1)
|
||||||
|
vim.cmd("normal k")
|
||||||
|
assert(vim.fn.line(".") == 1 and vim.fn.col(".") == 1)
|
||||||
|
vim.cmd("normal 3j")
|
||||||
|
assert(vim.fn.line(".") == 4)
|
||||||
|
vim.cmd("normal 3k")
|
||||||
|
assert(vim.fn.line(".") == 1)
|
||||||
|
assert(vim.fn.maparg("j", "o") == "")
|
||||||
|
vim.bo.buftype = "nofile"
|
||||||
|
vim.cmd("normal j")
|
||||||
|
assert(vim.fn.line(".") == 2)
|
||||||
|
vim.cmd("doautocmd InsertEnter")
|
||||||
|
assert(vim.deep_equal(require("blink.cmp.config").keymap["<Esc>"], { "cancel", "fallback" }))
|
||||||
|
print("Neovim motion and completion configuration smoke check passed")
|
||||||
Loaded 100 of 101 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user