[Sync] adopt unified stow layout from the private repo
Mirrors the private dots tree at 900bdda: one shared base plus per-host overlays, replacing the old flat .config/ layout (last synced 2026-06-28). - packages: common/ gui/ wm/ lw/ fl/ + install.sh and bin/ tooling (dotsync, reconcile-hyde.sh) - new README (layout, deploy order, HyDE dependency), plus ToDo.md and HYDE-UPDATE.md - current HyDE waybar rig (layouts/, cava), pi agent extensions, claude/ config, tmux, presenterm, aichat roles - drops stale duplicates and generated cruft that should never have been tracked: the second top-level .pi/ copy, btop.log, zellij config.kdl.bak, fish_variables, nvim codecompanion.lua - .pi/agent/auth.json is gitignored now; auth.json.example ships instead - fl/ and wm/ hypr themes/ stay untracked (HyDE-generated per machine, per the root .gitignore)
@@ -0,0 +1,55 @@
|
||||
# see https://github.com/sigoden/aichat/blob/main/config.example.yaml
|
||||
keybindings: vi
|
||||
editor: nvim
|
||||
model: local:Qwen3-Coder-30B-Instruct-UD-Q3_K_XL
|
||||
|
||||
# Sessions: persist REPL sessions and keep more history before summarizing.
|
||||
# The default compress_threshold (4000) summarizes far too early for 24k+ windows.
|
||||
save_session: true
|
||||
compress_threshold: 16000
|
||||
|
||||
# REPL prompts show live context usage (needs max_input_tokens, set per model below)
|
||||
left_prompt: '{color.green}{?session {session}{?role /}}{role}{color.cyan}{?rag @{rag}}{color.reset}> '
|
||||
right_prompt: '{color.purple}{?session {consume_tokens}/{max_input_tokens} }{color.reset}'
|
||||
|
||||
# NOTE: temperature/top_p are intentionally unset — the LAN server applies tuned
|
||||
# per-model sampling via --jinja (e.g. GLM 0.6/0.95); a global value would clobber it.
|
||||
|
||||
# max_input_tokens = real ctx-size (from the router) minus output headroom.
|
||||
clients:
|
||||
# LAN access (fast; only reachable on the home network)
|
||||
- type: openai-compatible
|
||||
name: local
|
||||
api_base: http://192.168.0.204:11343/v1
|
||||
models: &lan_models
|
||||
- name: Qwen3-Coder-30B-Instruct-UD-Q3_K_XL
|
||||
max_input_tokens: 30000 # ctx 32768
|
||||
- name: Qwen3-Coder-Next-UD-IQ3_XXS
|
||||
max_input_tokens: 128000 # ctx 131072
|
||||
- name: Qwen3.6-35B-A3B-MTP-UD-IQ3_XXS
|
||||
max_input_tokens: 22000 # ctx 24576
|
||||
supports_vision: true
|
||||
- name: Qwen3.6-35B-A3B-Thinking
|
||||
max_input_tokens: 22000 # ctx 24576
|
||||
supports_vision: true
|
||||
- name: Qwen3.5-9B-UD-Q6_K_XL
|
||||
max_input_tokens: 30000 # ctx 32768
|
||||
supports_vision: true
|
||||
- name: gemma-4-26B-A4B-it-UD-IQ4_XS
|
||||
max_input_tokens: 22000 # ctx 24576
|
||||
supports_vision: true
|
||||
- name: gemma-4-E4B-it-UD-Q8_K_XL
|
||||
max_input_tokens: 62000 # ctx 65536
|
||||
supports_vision: true
|
||||
- name: GLM-4.7-Flash-UD-Q4_K_XL
|
||||
max_input_tokens: 22000 # ctx 24576
|
||||
- name: gpt-oss-20b
|
||||
max_input_tokens: 62000 # ctx 65536
|
||||
- name: gpt-oss-20b-low
|
||||
max_input_tokens: 62000 # ctx 65536
|
||||
# Remote access via duskadiy.com (reachable from anywhere; no key required)
|
||||
# Same server, same model ids — reuse the list above via a YAML anchor.
|
||||
- type: openai-compatible
|
||||
name: duskadiy
|
||||
api_base: https://llm.duskadiy.com/api/v1
|
||||
models: *lan_models
|
||||
@@ -0,0 +1,663 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Name: One Half Dark
|
||||
Author: Son A. Pham <sp@sonpham.me>
|
||||
Url: https://github.com/sonph/onehalf
|
||||
License: The MIT License (MIT)
|
||||
|
||||
A dark Sublime Text color scheme based on Atom's One. See
|
||||
github.com/sonph/onehalf for installation instructions, a light color
|
||||
scheme, and versions for other editors/terminals such as Vim or iTerm.
|
||||
|
||||
Red: #e06c75
|
||||
Green: #98c379
|
||||
Yellow: #e5c07b
|
||||
Blue: #61afef
|
||||
Purple: #c678dd
|
||||
Cyan: #56b6c2
|
||||
White: #dcdfe4
|
||||
Black: #282c34
|
||||
Fg: #dcdfe4
|
||||
Bg: #282c34
|
||||
Comment: #5c6370
|
||||
Gutter foreground: #919baa
|
||||
Gutter background: #282c34
|
||||
Selection: #474e5d
|
||||
-->
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>OneHalfLight</string>
|
||||
<key>semanticClass</key>
|
||||
<string>theme.dark.one_half_dark</string>
|
||||
<key>uuid</key>
|
||||
<string></string>
|
||||
<key>colorSpaceName</key>
|
||||
<string>sRGB</string>
|
||||
<key>author</key>
|
||||
<string>Son A. Pham <sp@sonpham.me></string>
|
||||
<key>comment</key>
|
||||
<string>A dark iTerm color scheme based on Atom's One. See github.com/sonph/onehalf for installation instructions, a light color scheme, and versions for other editors/terminals such as (Neo)Vim and Sublime Text.</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
<key>background</key>
|
||||
<string>#282c34</string>
|
||||
<key>bracketsOptions</key>
|
||||
<string>underline</string>
|
||||
<key>caret</key>
|
||||
<string>#a3b3cc</string>
|
||||
<key>gutter</key>
|
||||
<string>#282c34</string>
|
||||
<key>gutterForeground</key>
|
||||
<string>#919baa</string>
|
||||
<key>invisibles</key>
|
||||
<string>#5c6370</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#313640</string>
|
||||
<key>selection</key>
|
||||
<string>#474e5d</string>
|
||||
<key>selectionBorder</key>
|
||||
<string>#474e5d</string>
|
||||
<key>tagsForeground</key>
|
||||
<string></string>
|
||||
<key>tagsOptions</key>
|
||||
<string>stippled_underline</string>
|
||||
<key>bracketContentsOptions</key>
|
||||
<string>underline</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comments</string>
|
||||
<key>scope</key>
|
||||
<string>comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#5c6370</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Text</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Delimiters</string>
|
||||
<key>scope</key>
|
||||
<string>none</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Operators</string>
|
||||
<key>scope</key>
|
||||
<string>keyword.operator</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keywords</string>
|
||||
<key>scope</key>
|
||||
<string>keyword</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#c678dd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variables</string>
|
||||
<key>scope</key>
|
||||
<string>variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Functions</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.function, meta.require, support.function.any-method</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#61afef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Classes</string>
|
||||
<key>scope</key>
|
||||
<string>support.class, entity.name.class, entity.name.type.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Classes</string>
|
||||
<key>scope</key>
|
||||
<string>meta.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Methods</string>
|
||||
<key>scope</key>
|
||||
<string>keyword.other.special-method</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#61afef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage</string>
|
||||
<key>scope</key>
|
||||
<string>storage</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#c678dd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Support</string>
|
||||
<key>scope</key>
|
||||
<string>support.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#61afef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Strings, Inherited Class</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Integers</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Floats</string>
|
||||
<key>scope</key>
|
||||
<string>none</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Boolean</string>
|
||||
<key>scope</key>
|
||||
<string>none</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Constants</string>
|
||||
<key>scope</key>
|
||||
<string>constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>HTML: Tags</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>HTML: Tag attributes</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Attribute IDs</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name.id, punctuation.definition.entity</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Selector</string>
|
||||
<key>scope</key>
|
||||
<string>meta.selector</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#c678dd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Headings</string>
|
||||
<key>scope</key>
|
||||
<string>markup.heading punctuation.definition.heading, entity.name.section</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#61afef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Bold</string>
|
||||
<key>scope</key>
|
||||
<string>markup.bold, punctuation.definition.bold</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#c678dd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Italic</string>
|
||||
<key>scope</key>
|
||||
<string>markup.italic, punctuation.definition.italic</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#c678dd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Code</string>
|
||||
<key>scope</key>
|
||||
<string>markup.raw.inline</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Link Text</string>
|
||||
<key>scope</key>
|
||||
<string>string.other.link, punctuation.definition.string.end.markdown</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Link Url</string>
|
||||
<key>scope</key>
|
||||
<string>meta.link</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Lists</string>
|
||||
<key>scope</key>
|
||||
<string>markup.list</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Quotes</string>
|
||||
<key>scope</key>
|
||||
<string>markup.quote</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Java Source</string>
|
||||
<key>scope</key>
|
||||
<string>source.java meta.class.java meta.method.java</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Java Class Body</string>
|
||||
<key>scope</key>
|
||||
<string>source.java meta.class.java meta.class.body.java</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Function Arguments</string>
|
||||
<key>scope</key>
|
||||
<string>source.js meta.function.js variable.parameter.function.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: New Variables</string>
|
||||
<key>scope</key>
|
||||
<string>source.js variable.other.readwrite.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Variables</string>
|
||||
<key>scope</key>
|
||||
<string>source.js variable.other.object.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Variables in Function Calls</string>
|
||||
<key>scope</key>
|
||||
<string>source.js meta.function-call.method.js variable.other.readwrite.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: New Block Variables</string>
|
||||
<key>scope</key>
|
||||
<string>source.js meta.block.js variable.other.readwrite.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Block Variables</string>
|
||||
<key>scope</key>
|
||||
<string>source.js meta.block.js variable.other.object.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Block Variables in Function Calls</string>
|
||||
<key>scope</key>
|
||||
<string>source.js meta.block.js meta.function-call.method.js variable.other.readwrite.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Function Calls</string>
|
||||
<key>scope</key>
|
||||
<string>source.js meta.function-call.method.js variable.function.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Properties</string>
|
||||
<key>scope</key>
|
||||
<string>source.js meta.property.object.js entity.name.function.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#61afef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Javascript: Prototypes</string>
|
||||
<key>scope</key>
|
||||
<string>source.js support.constant.prototype.js</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Separator</string>
|
||||
<key>scope</key>
|
||||
<string>meta.separator</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Inserted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inserted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Deleted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.deleted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Changed</string>
|
||||
<key>scope</key>
|
||||
<string>markup.changed</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e5c07b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Regular Expressions</string>
|
||||
<key>scope</key>
|
||||
<string>string.regexp</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Escape Characters</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character.escape</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#56b6c2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Embedded</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.section.embedded, variable.interpolation</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Illegal</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.illegal</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#e06c75</string>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Broken</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.broken</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#e5c07b</string>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Deprecated</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.deprecated</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#e5c07b</string>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Unimplemented</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.unimplemented</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#c678dd</string>
|
||||
<key>foreground</key>
|
||||
<string>#dcdfe4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
temperature: 0.2
|
||||
---
|
||||
You are a terse coding assistant.
|
||||
|
||||
- Lead with the code, as a single fenced block.
|
||||
- Add at most 1–2 short sentences of explanation, and only if genuinely needed. No preamble, no "here is", no closing summary.
|
||||
- Match the language and style implied by the question; if unspecified, infer the most likely one.
|
||||
- If the request is ambiguous, make the most reasonable assumption and state it in one line above the code.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
temperature: 0.2
|
||||
---
|
||||
You write a git commit message from a diff. Output ONLY the message — no preamble, no code fences, no explanation.
|
||||
|
||||
- Subject: `[Scope] imperative summary`, where Scope is a short tag inferred from the changed paths, matching the style of recent `git log` (e.g. [Waybar], [Fish], [LLM]). Keep it under 70 characters.
|
||||
- Imperative mood ("add", "fix", "rename"), never past tense.
|
||||
- For a non-trivial change, leave a blank line then add 1–4 terse bullets ("- ...") covering what changed and why. Omit the body for small, self-explanatory changes.
|
||||
- Describe only what the diff actually shows; do not invent rationale or files.
|
||||
|
||||
The user's input is the diff (typically `git diff --cached`).
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
temperature: 0.1
|
||||
---
|
||||
You translate a request into a single shell command for the fish shell on Arch Linux. Output ONLY the command on one line — no code fence, no explanation.
|
||||
|
||||
- Use fish syntax, not bash. Notably: `set -x VAR value` (not `export`), `$status` (not `$?`), the `test` / `string` / `math` builtins, and `(cmd)` for command substitution (not `$(cmd)`). `&&` / `||` work in modern fish.
|
||||
- Package management is pacman / yay (`yay -S`, `pacman -Qi`, `pacman -Qo`). Clipboard is Wayland: `wl-copy` / `wl-paste`.
|
||||
- Prefer one pipeline. If several steps are unavoidable, chain them with `; and`.
|
||||
- If it can't be done safely in one command, output a single `# ...` comment saying why instead.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
temperature: 0.2
|
||||
---
|
||||
You review a code diff for defects. Be concise and specific.
|
||||
|
||||
- Focus on correctness bugs, edge cases, error handling, security issues, and clear regressions. Skip style and formatting nits unless they cause a bug.
|
||||
- Format each finding as `file:line — issue — why it matters`, most severe first.
|
||||
- Reference exact identifiers and lines from the diff; do not speculate about code you cannot see.
|
||||
- If nothing substantive is wrong, say so in one line rather than inventing issues.
|
||||
|
||||
The user's input is the diff (typically `git diff`).
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
model: local:gemma-4-E4B-it-UD-Q8_K_XL
|
||||
temperature: 0.1
|
||||
---
|
||||
You translate a request into a single shell command for the fish shell on Arch Linux. Output ONLY the command on one line — no code fence, no explanation.
|
||||
|
||||
- Use fish syntax, not bash. Notably: `set -x VAR value` (not `export`), `$status` (not `$?`), the `test` / `string` / `math` builtins, and `(cmd)` for command substitution (not `$(cmd)`). `&&` / `||` work in modern fish.
|
||||
- Package management is pacman / yay (`yay -S`, `pacman -Qi`, `pacman -Qo`). Clipboard is Wayland: `wl-copy` / `wl-paste`.
|
||||
- Prefer one pipeline. If several steps are unavoidable, chain them with `; and`.
|
||||
- If it can't be done safely in one command, output a single `# ...` comment saying why instead.
|
||||
@@ -0,0 +1,34 @@
|
||||
# This is `bat`s configuration file. Each line either contains a comment or
|
||||
# a command-line option that you want to pass to `bat` by default. You can
|
||||
# run `bat --help` to get a list of all possible configuration options.
|
||||
|
||||
# Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes`
|
||||
# for a list of all available themes
|
||||
# Custom theme lives in ./themes/ — run `bat cache --build` after changing it
|
||||
--theme="OneHalfDark"
|
||||
--style="numbers,changes,header,snip"
|
||||
|
||||
# Enable this to use italic text on the terminal. This is not supported on all
|
||||
# terminal emulators (like tmux, by default):
|
||||
--italic-text=always
|
||||
|
||||
# Uncomment the following line to disable automatic paging:
|
||||
#--paging=never
|
||||
|
||||
# Uncomment the following line if you are using less version >= 551 and want to
|
||||
# enable mouse scrolling support in `bat` when running inside tmux. This might
|
||||
# disable text selection, unless you press shift.
|
||||
--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse --ignore-case"
|
||||
|
||||
# Syntax mappings: map a certain filename pattern to a language.
|
||||
# Example 1: use the C++ syntax for Arduino .ino files
|
||||
# Example 2: Use ".gitignore"-style highlighting for ".ignore" files
|
||||
--map-syntax "*.ino:C++"
|
||||
--map-syntax ".ignore:Git Ignore"
|
||||
--map-syntax "**/hypr/**/*.conf:INI"
|
||||
--map-syntax "**/kitty/*.conf:INI"
|
||||
--map-syntax "*.ctl:INI"
|
||||
--map-syntax ".inputrc:bash"
|
||||
--map-syntax "**/cava/config:INI"
|
||||
--map-syntax "**/mpv/*.conf:INI"
|
||||
--map-syntax "**/btop/btop.conf:INI"
|
||||
@@ -0,0 +1,260 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>One Dark (NvChad base46)</string>
|
||||
<key>uuid</key>
|
||||
<string>3c1e2b84-9d5f-4a7c-8b2e-6f4a1d9c7e5b</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#1e222a</string>
|
||||
<key>foreground</key>
|
||||
<string>#abb2bf</string>
|
||||
<key>caret</key>
|
||||
<string>#abb2bf</string>
|
||||
<key>selection</key>
|
||||
<string>#3e4451</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#252931</string>
|
||||
<key>gutterForeground</key>
|
||||
<string>#545862</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment, punctuation.definition.comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#6f737b</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Number, constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric, constant.language, constant.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#d19a66</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Escape character</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character.escape</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#a3b8ef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword, storage</string>
|
||||
<key>scope</key>
|
||||
<string>keyword, storage</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#c882e7</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Operator</string>
|
||||
<key>scope</key>
|
||||
<string>keyword.operator</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#abb2bf</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.function, support.function, meta.function-call.generic</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#61afef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Class, type</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.class, entity.name.type, entity.name.struct, entity.name.enum, support.type, support.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e7c787</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable, variable.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function parameter</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Attribute</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#d19a66</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.tag, meta.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup heading</string>
|
||||
<key>scope</key>
|
||||
<string>markup.heading, entity.name.section</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
<key>fontStyle</key>
|
||||
<string>bold</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup bold</string>
|
||||
<key>scope</key>
|
||||
<string>markup.bold</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>bold</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup italic</string>
|
||||
<key>scope</key>
|
||||
<string>markup.italic</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup link</string>
|
||||
<key>scope</key>
|
||||
<string>markup.underline.link, string.other.link</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#61afef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup quote</string>
|
||||
<key>scope</key>
|
||||
<string>markup.quote</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#6f737b</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Diff inserted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inserted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#98c379</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Diff deleted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.deleted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#e06c75</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid</string>
|
||||
<key>scope</key>
|
||||
<string>invalid, invalid.illegal</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffffff</string>
|
||||
<key>background</key>
|
||||
<string>#be5046</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,262 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Synthwave 84</string>
|
||||
<key>uuid</key>
|
||||
<string>7b2c3a10-4b6e-4d8f-9c1a-2e5f8d7a9b3c</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#262335</string>
|
||||
<key>foreground</key>
|
||||
<string>#ffffff</string>
|
||||
<key>caret</key>
|
||||
<string>#f97e72</string>
|
||||
<key>selection</key>
|
||||
<string>#463465</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#2a2139</string>
|
||||
<key>gutterForeground</key>
|
||||
<string>#848bbd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment, punctuation.definition.comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#848bbd</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff8b39</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Number, constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric, constant.language, constant.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#f97e72</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Escape character</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character.escape</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#36f9f6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword, storage</string>
|
||||
<key>scope</key>
|
||||
<string>keyword, storage, keyword.operator</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fede5d</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage type</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type, storage.modifier</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fede5d</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.function, support.function, meta.function-call.generic</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#36f9f6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Class, type</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.class, entity.name.type, entity.name.struct, entity.name.enum, support.type, support.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fe4450</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable, variable.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff7edb</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function parameter</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff7edb</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Attribute</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fede5d</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.tag, meta.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#72f1b8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup heading</string>
|
||||
<key>scope</key>
|
||||
<string>markup.heading, entity.name.section</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fe4450</string>
|
||||
<key>fontStyle</key>
|
||||
<string>bold</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup bold</string>
|
||||
<key>scope</key>
|
||||
<string>markup.bold</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>bold</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup italic</string>
|
||||
<key>scope</key>
|
||||
<string>markup.italic</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup link</string>
|
||||
<key>scope</key>
|
||||
<string>markup.underline.link, string.other.link</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#36f9f6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup quote</string>
|
||||
<key>scope</key>
|
||||
<string>markup.quote</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#848bbd</string>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Diff inserted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inserted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#72f1b8</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Diff deleted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.deleted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#fe4450</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid</string>
|
||||
<key>scope</key>
|
||||
<string>invalid, invalid.illegal</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffffff</string>
|
||||
<key>background</key>
|
||||
<string>#fe4450</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,286 @@
|
||||
#? Config file for btop v.1.4.7
|
||||
|
||||
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
|
||||
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
|
||||
color_theme = "Default"
|
||||
|
||||
#* If the theme set background should be shown, set to False if you want terminal background transparency.
|
||||
theme_background = false
|
||||
|
||||
#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
|
||||
truecolor = true
|
||||
|
||||
#* Set to true to force tty mode regardless if a real tty has been detected or not.
|
||||
#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols.
|
||||
force_tty = false
|
||||
|
||||
#* Option to disable presets. Either the default preset, custom presets, or all presets.
|
||||
#* "Off" All presets are enabled.
|
||||
#* "Default" preset is disabled.#* "Custom" presets are disabled.#* "All" presets are disabled.
|
||||
disable_presets = "Off"
|
||||
|
||||
#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets.
|
||||
#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box.
|
||||
#* Use whitespace " " as separator between different presets.
|
||||
#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty"
|
||||
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"
|
||||
|
||||
#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists.
|
||||
#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
|
||||
vim_keys = true
|
||||
|
||||
#* Disable all mouse events.
|
||||
disable_mouse = false
|
||||
|
||||
#* Rounded corners on boxes, is ignored if TTY mode is ON.
|
||||
rounded_corners = true
|
||||
|
||||
#* Use terminal synchronized output sequences to reduce flickering on supported terminals.
|
||||
terminal_sync = true
|
||||
|
||||
#* Default symbols to use for graph creation, "braille", "block" or "tty".
|
||||
#* "braille" offers the highest resolution but might not be included in all fonts.
|
||||
#* "block" has half the resolution of braille but uses more common characters.
|
||||
#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY.
|
||||
#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view.
|
||||
graph_symbol = "braille"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_cpu = "default"
|
||||
|
||||
# Graph symbol to use for graphs in gpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_gpu = "default"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_mem = "default"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_net = "default"
|
||||
|
||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||
graph_symbol_proc = "default"
|
||||
|
||||
#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace.
|
||||
shown_boxes = "proc cpu mem net"
|
||||
|
||||
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
|
||||
update_ms = 2000
|
||||
|
||||
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct",
|
||||
#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly.
|
||||
proc_sorting = "cpu lazy"
|
||||
|
||||
#* Reverse sorting order, True or False.
|
||||
proc_reversed = false
|
||||
|
||||
#* Show processes as a tree.
|
||||
proc_tree = true
|
||||
|
||||
#* Use the cpu graph colors in the process list.
|
||||
proc_colors = true
|
||||
|
||||
#* Use a darkening gradient in the process list.
|
||||
proc_gradient = true
|
||||
|
||||
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
|
||||
proc_per_core = false
|
||||
|
||||
#* Show process memory as bytes instead of percent.
|
||||
proc_mem_bytes = true
|
||||
|
||||
#* Show cpu graph for each process.
|
||||
proc_cpu_graphs = true
|
||||
|
||||
#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate)
|
||||
proc_info_smaps = false
|
||||
|
||||
#* Show proc box on left side of screen instead of right.
|
||||
proc_left = false
|
||||
|
||||
#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop).
|
||||
proc_filter_kernel = false
|
||||
|
||||
#* Should the process list follow the selected process when detailed view is open.
|
||||
proc_follow_detailed = true
|
||||
|
||||
#* In tree-view, always accumulate child process resources in the parent process.
|
||||
proc_aggregate = false
|
||||
|
||||
#* Should cpu and memory usage display be preserved for dead processes when paused.
|
||||
keep_dead_proc_usage = false
|
||||
|
||||
#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available.
|
||||
#* Select from a list of detected attributes from the options menu.
|
||||
cpu_graph_upper = "Auto"
|
||||
|
||||
#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available.
|
||||
#* Select from a list of detected attributes from the options menu.
|
||||
cpu_graph_lower = "Auto"
|
||||
|
||||
#* If gpu info should be shown in the cpu box. Available values = "Auto", "On" and "Off".
|
||||
show_gpu_info = "Auto"
|
||||
|
||||
#* Toggles if the lower CPU graph should be inverted.
|
||||
cpu_invert_lower = true
|
||||
|
||||
#* Set to True to completely disable the lower CPU graph.
|
||||
cpu_single_graph = false
|
||||
|
||||
#* Show cpu box at bottom of screen instead of top.
|
||||
cpu_bottom = false
|
||||
|
||||
#* Shows the system uptime in the CPU box.
|
||||
show_uptime = true
|
||||
|
||||
#* Shows the CPU package current power consumption in watts. Requires running `make setcap` or `make setuid` or running with sudo.
|
||||
show_cpu_watts = true
|
||||
|
||||
#* Show cpu temperature.
|
||||
check_temp = true
|
||||
|
||||
#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
|
||||
cpu_sensor = "Auto"
|
||||
|
||||
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found.
|
||||
show_coretemp = true
|
||||
|
||||
#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core.
|
||||
#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine.
|
||||
#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries.
|
||||
#* Example: "4:0 5:1 6:3"
|
||||
cpu_core_map = ""
|
||||
|
||||
#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine".
|
||||
temp_scale = "celsius"
|
||||
|
||||
#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024.
|
||||
base_10_sizes = false
|
||||
|
||||
#* Show CPU frequency.
|
||||
show_cpu_freq = true
|
||||
|
||||
#* How to calculate CPU frequency, available values: "first", "range", "lowest", "highest" and "average".
|
||||
freq_mode = "first"
|
||||
|
||||
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
|
||||
#* Special formatting: /host = hostname | /user = username | /uptime = system uptime
|
||||
clock_format = "%X"
|
||||
|
||||
#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
|
||||
background_update = true
|
||||
|
||||
#* Custom cpu model name, empty string to disable.
|
||||
custom_cpu_name = ""
|
||||
|
||||
#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ".
|
||||
#* Only disks matching the filter will be shown. Prepend exclude= to only show disks not matching the filter. Examples: disk_filter="/boot /home/user", disks_filter="exclude=/boot /home/user"
|
||||
disks_filter = ""
|
||||
|
||||
#* Show graphs instead of meters for memory values.
|
||||
mem_graphs = true
|
||||
|
||||
#* Show mem box below net box instead of above.
|
||||
mem_below_net = false
|
||||
|
||||
#* Count ZFS ARC in cached and available memory.
|
||||
zfs_arc_cached = true
|
||||
|
||||
#* If swap memory should be shown in memory box.
|
||||
show_swap = true
|
||||
|
||||
#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
|
||||
swap_disk = true
|
||||
|
||||
#* If mem box should be split to also show disks info.
|
||||
show_disks = true
|
||||
|
||||
#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
|
||||
only_physical = true
|
||||
|
||||
#* Read disks list from /etc/fstab. This also disables only_physical.
|
||||
use_fstab = true
|
||||
|
||||
#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool)
|
||||
zfs_hide_datasets = false
|
||||
|
||||
#* Set to true to show available disk space for privileged users.
|
||||
disk_free_priv = false
|
||||
|
||||
#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view.
|
||||
show_io_stat = true
|
||||
|
||||
#* Toggles io mode for disks, showing big graphs for disk read/write speeds.
|
||||
io_mode = false
|
||||
|
||||
#* Set to True to show combined read/write io graphs in io mode.
|
||||
io_graph_combined = false
|
||||
|
||||
#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ".
|
||||
#* Example: "/mnt/media:100 /:20 /boot:1".
|
||||
io_graph_speeds = ""
|
||||
|
||||
#* Swap the positions of the upload and download speed graphs. When true, upload will be on top.
|
||||
swap_upload_download = false
|
||||
|
||||
#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False.
|
||||
net_download = 100
|
||||
|
||||
net_upload = 100
|
||||
|
||||
#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
|
||||
net_auto = true
|
||||
|
||||
#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
|
||||
net_sync = true
|
||||
|
||||
#* Starts with the Network Interface specified here.
|
||||
net_iface = ""
|
||||
|
||||
#* "True" shows bitrates in base 10 (Kbps, Mbps). "False" shows bitrates in binary sizes (Kibps, Mibps, etc.). "Auto" uses base_10_sizes.
|
||||
base_10_bitrate = "Auto"
|
||||
|
||||
#* Show battery stats in top right if battery is present.
|
||||
show_battery = true
|
||||
|
||||
#* Which battery to use if multiple are present. "Auto" for auto detection.
|
||||
selected_battery = "Auto"
|
||||
|
||||
#* Show power stats of battery next to charge indicator.
|
||||
show_battery_watts = true
|
||||
|
||||
#* Set loglevel for "~/.local/state/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
|
||||
#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
|
||||
log_level = "WARNING"
|
||||
|
||||
#* Automatically save current settings to config file on exit.
|
||||
save_config_on_exit = false
|
||||
|
||||
#* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards.
|
||||
nvml_measure_pcie_speeds = true
|
||||
|
||||
#* Measure PCIe throughput on AMD cards, may impact performance on certain cards.
|
||||
rsmi_measure_pcie_speeds = true
|
||||
|
||||
#* Horizontally mirror the GPU graph.
|
||||
gpu_mirror_graph = true
|
||||
|
||||
#* Set which GPU vendors to show. Available values are "nvidia amd intel apple"
|
||||
shown_gpus = "nvidia amd intel"
|
||||
|
||||
#* Custom gpu0 model name, empty string to disable.
|
||||
custom_gpu_name0 = ""
|
||||
|
||||
#* Custom gpu1 model name, empty string to disable.
|
||||
custom_gpu_name1 = ""
|
||||
|
||||
#* Custom gpu2 model name, empty string to disable.
|
||||
custom_gpu_name2 = ""
|
||||
|
||||
#* Custom gpu3 model name, empty string to disable.
|
||||
custom_gpu_name3 = ""
|
||||
|
||||
#* Custom gpu4 model name, empty string to disable.
|
||||
custom_gpu_name4 = ""
|
||||
|
||||
#* Custom gpu5 model name, empty string to disable.
|
||||
custom_gpu_name5 = ""
|
||||
@@ -0,0 +1,309 @@
|
||||
## Configuration file for CAVA.
|
||||
# Remove the ; to change parameters.
|
||||
|
||||
[general]
|
||||
|
||||
# Smoothing mode. Can be 'normal', 'scientific' or 'waves'. DEPRECATED as of 0.6.0
|
||||
# mode = scientific # deprecated since cava 0.6.0, ignored
|
||||
|
||||
# Accepts only non-negative values.
|
||||
framerate = 60
|
||||
|
||||
# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off
|
||||
# new as of 0.6.0 autosens of low values (dynamic range)
|
||||
# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. DEPRECATED as of 0.6.0
|
||||
autosens = 1
|
||||
; overshoot = 20
|
||||
|
||||
# Manual sensitivity in %. If autosens is enabled, this will only be the initial value.
|
||||
# 200 means double height. Accepts only non-negative values.
|
||||
; sensitivity = 100
|
||||
|
||||
# The number of bars (0-512). 0 sets it to auto (fill up console).
|
||||
# Bars' width and space between bars in number of characters.
|
||||
; bars = 0
|
||||
; bar_width = 2
|
||||
; bar_spacing = 1
|
||||
# bar_height is only used for output in "noritake" format
|
||||
; bar_height = 32
|
||||
|
||||
# For SDL width and space between bars is in pixels, defaults are:
|
||||
; bar_width = 20
|
||||
; bar_spacing = 5
|
||||
|
||||
# sdl_glsl have these default values, they are only used to calculate max number of bars.
|
||||
; bar_width = 1
|
||||
; bar_spacing = 0
|
||||
|
||||
# ceter bars in terminal, if there is space.
|
||||
; center_align = 1
|
||||
|
||||
# max height of bars in terminal, in percent of terminal height.
|
||||
; max_height = 100
|
||||
|
||||
|
||||
# Lower and higher cutoff frequencies for lowest and highest bars
|
||||
# the bandwidth of the visualizer.
|
||||
# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
|
||||
# Cava will automatically increase the higher cutoff if a too low band is specified.
|
||||
; lower_cutoff_freq = 50
|
||||
; higher_cutoff_freq = 10000
|
||||
|
||||
|
||||
# Seconds with no input before cava goes to sleep mode. Cava will not perform FFT or drawing and
|
||||
# only check for input once per second. Cava will wake up once input is detected. 0 = disable.
|
||||
; sleep_timer = 0
|
||||
|
||||
|
||||
[input]
|
||||
|
||||
# Audio capturing method. Possible methods are: 'fifo', 'portaudio', 'pipewire', 'alsa', 'pulse', 'sndio', 'oss', 'jack' or 'shmem'
|
||||
# Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with.
|
||||
# On Mac it defaults to 'portaudio' or 'fifo'
|
||||
# On windows this is automatic and no input settings are needed.
|
||||
#
|
||||
# All input methods uses the same config variable 'source'
|
||||
# to define where it should get the audio.
|
||||
#
|
||||
# For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
|
||||
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
|
||||
#
|
||||
# For pipewire 'source' will be the object name or object.serial of the device to capture from.
|
||||
# Both input and output devices are supported. To capture the monitor source of a sink node, append '.monitor' to the sink's object name.
|
||||
#
|
||||
# For alsa 'source' will be the capture device.
|
||||
# For fifo 'source' will be the path to fifo-file.
|
||||
# For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address
|
||||
#
|
||||
# For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'.
|
||||
# README.md contains further information on how to setup CAVA for sndio.
|
||||
#
|
||||
# For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device.
|
||||
# README.md contains further information on how to setup CAVA for OSS on FreeBSD.
|
||||
#
|
||||
# For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'.
|
||||
# README.md contains further information on how to setup CAVA for JACK.
|
||||
#
|
||||
; method = pulse
|
||||
; source = auto
|
||||
|
||||
; method = pipewire
|
||||
; source = auto
|
||||
|
||||
; method = alsa
|
||||
; source = hw:Loopback,1
|
||||
|
||||
; method = fifo
|
||||
; source = /tmp/mpd.fifo
|
||||
|
||||
; method = shmem
|
||||
; source = /squeezelite-AA:BB:CC:DD:EE:FF
|
||||
|
||||
; method = portaudio
|
||||
; source = auto
|
||||
|
||||
; method = sndio
|
||||
; source = default
|
||||
|
||||
; method = oss
|
||||
; source = /dev/dsp
|
||||
|
||||
; method = jack
|
||||
; source = default
|
||||
|
||||
# The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' can be configured for some input methods:
|
||||
# sample_rate: fifo, pipewire, sndio, oss
|
||||
# sample_bits: fifo, pipewire, sndio, oss
|
||||
# channels: sndio, oss, jack
|
||||
# autoconnect: jack
|
||||
# Other methods ignore these settings.
|
||||
#
|
||||
# For 'sndio' and 'oss' they are only preferred values, i.e. if the values are not supported
|
||||
# by the chosen audio device, the device will use other supported values instead.
|
||||
# Example: 48000, 32 and 2, but the device only supports 44100, 16 and 1, then it
|
||||
# will use 44100, 16 and 1.
|
||||
#
|
||||
; sample_rate = 44100
|
||||
; sample_bits = 16
|
||||
; channels = 2
|
||||
; autoconnect = 2
|
||||
|
||||
|
||||
[output]
|
||||
|
||||
# Output method. Can be 'ncurses', 'noncurses', 'raw', 'noritake', 'sdl'
|
||||
# or 'sdl_glsl'.
|
||||
# 'noncurses' (default) uses a buffer and cursor movements to only print
|
||||
# changes from frame to frame in the terminal. Uses less resources and is less
|
||||
# prone to tearing (vsync issues) than 'ncurses'.
|
||||
#
|
||||
# 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data
|
||||
# stream of the bar heights that can be used to send to other applications.
|
||||
# 'raw' defaults to 1024 bars stereo (512 bars mono), which can be adjusted in the 'bars' option above.
|
||||
#
|
||||
# 'noritake' outputs a bitmap in the format expected by a Noritake VFD display
|
||||
# in graphic mode. It only support the 3000 series graphical VFDs for now.
|
||||
#
|
||||
# 'sdl' uses the Simple DirectMedia Layer to render in a graphical context.
|
||||
# 'sdl_glsl' uses SDL to create an OpenGL context. Write your own shaders or
|
||||
# use one of the predefined ones.
|
||||
; method = noncurses
|
||||
|
||||
# Orientation of the visualization. Can be 'bottom', 'top', 'left', 'right' or
|
||||
# 'horizontal'. Default is 'bottom'. 'left and 'right' are only supported on sdl
|
||||
# and ncruses output. 'horizontal' (bars go up and down from center) is only supported
|
||||
# on noncurses output.
|
||||
# Note: many fonts have weird or missing glyphs for characters used in orientations
|
||||
# other than 'bottom', which can make output not look right.
|
||||
; orientation = bottom
|
||||
|
||||
# Visual channels. Can be 'stereo' or 'mono'.
|
||||
# 'stereo' mirrors both channels with low frequencies in center.
|
||||
# 'mono' outputs left to right lowest to highest frequencies.
|
||||
# 'mono_option' set mono to either take input from 'left', 'right' or 'average'.
|
||||
# set 'reverse' to 1 to display frequencies the other way around.
|
||||
; channels = stereo
|
||||
; mono_option = average
|
||||
; reverse = 0
|
||||
|
||||
# Raw output target.
|
||||
# On Linux, a fifo will be created if target does not exist.
|
||||
# On Windows, a named pipe will be created if target does not exist.
|
||||
; raw_target = /dev/stdout
|
||||
|
||||
# Raw data format. Can be 'binary' or 'ascii'.
|
||||
; data_format = binary
|
||||
|
||||
# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
|
||||
; bit_format = 16bit
|
||||
|
||||
# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
|
||||
; ascii_max_range = 1000
|
||||
|
||||
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters.
|
||||
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
|
||||
; bar_delimiter = 59
|
||||
; frame_delimiter = 10
|
||||
|
||||
# sdl window size and position. -1,-1 is centered.
|
||||
; sdl_width = 1024
|
||||
; sdl_height = 512
|
||||
; sdl_x = -1
|
||||
; sdl_y= -1
|
||||
; sdl_full_screen = 0
|
||||
|
||||
# set label on bars on the x-axis. Can be 'frequency' or 'none'. Default: 'none'
|
||||
# 'frequency' displays the lower cut off frequency of the bar above.
|
||||
# Only supported on ncurses and noncurses output.
|
||||
; xaxis = none
|
||||
|
||||
# enable synchronized sync. 1 = on, 0 = off
|
||||
# removes flickering in alacritty terminal emulator.
|
||||
# defaults to off since the behaviour in other terminal emulators is unknown
|
||||
; synchronized_sync = 0
|
||||
|
||||
# Shaders for sdl_glsl, located in $HOME/.config/cava/shaders
|
||||
; vertex_shader = pass_through.vert
|
||||
; fragment_shader = bar_spectrum.frag
|
||||
|
||||
; for glsl output mode, keep rendering even if no audio
|
||||
; continuous_rendering = 0
|
||||
|
||||
# disable console blank (screen saver) in tty
|
||||
# (Not supported on FreeBSD)
|
||||
; disable_blanking = 0
|
||||
|
||||
# show a flat bar at the bottom of the screen when idle, 1 = on, 0 = off
|
||||
; show_idle_bar_heads = 1
|
||||
|
||||
# show waveform instead of frequency spectrum, 1 = on, 0 = off
|
||||
; waveform = 0
|
||||
|
||||
[color]
|
||||
|
||||
# Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
|
||||
# Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires
|
||||
# a terminal that can change color definitions such as Gnome-terminal or rxvt.
|
||||
# default is to keep current terminal color
|
||||
; background = default
|
||||
; foreground = default
|
||||
|
||||
# SDL and sdl_glsl only support hex code colors, these are the default:
|
||||
; background = '#111111'
|
||||
; foreground = '#D34b11'
|
||||
# ; foreground = '#D34b11'
|
||||
|
||||
# Gradient mode, only hex defined colors are supported,
|
||||
# background must also be defined in hex or remain commented out. 1 = on, 0 = off.
|
||||
# You can define as many as 8 different colors. They range from bottom to top of screen
|
||||
gradient = 1
|
||||
gradient_color_1 = '#d34b11'
|
||||
gradient_color_2 = '#cc5933'
|
||||
gradient_color_3 = '#cc8033'
|
||||
gradient_color_4 = '#cca633'
|
||||
gradient_color_5 = '#cccc33'
|
||||
gradient_color_6 = '#a6cc33'
|
||||
gradient_color_7 = '#80cc33'
|
||||
gradient_color_8 = '#59cc33'
|
||||
|
||||
# Horizontal is only supported on noncurses output.
|
||||
# Only one color will be calculated per bar.
|
||||
; horizontal_gradient = 1
|
||||
; horizontal_gradient_color_1 = '#c45161'
|
||||
; horizontal_gradient_color_2 = '#e094a0'
|
||||
; horizontal_gradient_color_3 = '#f2b6c0'
|
||||
; horizontal_gradient_color_4 = '#f2dde1'
|
||||
; horizontal_gradient_color_5 = '#cbc7d8'
|
||||
; horizontal_gradient_color_6 = '#8db7d2'
|
||||
; horizontal_gradient_color_7 = '#5e62a9'
|
||||
; horizontal_gradient_color_8 = '#434279'
|
||||
|
||||
|
||||
# If both vertical and horizontal gradient is enabled, vertical will be blended in this direction.
|
||||
# Can be 'up', 'down', 'left' or 'right'. 'up' means the vertical gradient will be blended in from
|
||||
# bottom to top. I.e. the bottom will be only the horizontal
|
||||
# and top will be only the color of the vertical gradient.
|
||||
; blend_direction = 'up'
|
||||
|
||||
# use theme file instead of defining colors in this file
|
||||
# themes are located in $HOME/.config/cava/themes
|
||||
; theme = 'none'
|
||||
|
||||
|
||||
[smoothing]
|
||||
|
||||
# Percentage value for integral smoothing. Takes values from 0 - 100.
|
||||
# Higher values means smoother, but less precise. 0 to disable.
|
||||
# DEPRECATED as of 0.8.0, use noise_reduction instead
|
||||
; integral = 77
|
||||
|
||||
# Disables or enables the so-called "Monstercat smoothing" with or without "waves". Set to 0 to disable.
|
||||
; monstercat = 0
|
||||
; waves = 0
|
||||
|
||||
# Set gravity percentage for "drop off". Higher values means bars will drop faster.
|
||||
# Accepts only non-negative values. 50 means half gravity, 200 means double. Set to 0 to disable "drop off".
|
||||
# DEPRECATED as of 0.8.0, use noise_reduction instead
|
||||
; gravity = 100
|
||||
|
||||
|
||||
# In bar height, bars that would have been lower that this will not be drawn.
|
||||
# DEPRECATED as of 0.8.0
|
||||
; ignore = 0
|
||||
|
||||
# Noise reduction, int 0 - 100. default 77
|
||||
# the raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth
|
||||
# 100 will be very slow and smooth, 0 will be fast but noisy.
|
||||
; noise_reduction = 77
|
||||
|
||||
|
||||
[eq]
|
||||
|
||||
# This one is tricky. You can have as much keys as you want.
|
||||
# Remember to uncomment more than one key! More keys = more precision.
|
||||
# Look at readme.md on github for further explanations and examples.
|
||||
; 1 = 1 # bass
|
||||
; 2 = 1
|
||||
; 3 = 1 # midtone
|
||||
; 4 = 1
|
||||
; 5 = 1 # treble
|
||||
@@ -0,0 +1,79 @@
|
||||
#version 330
|
||||
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// bar values. defaults to left channels first (low to high), then right (high to low).
|
||||
uniform float bars[512];
|
||||
|
||||
uniform int bars_count; // number of bars (left + right) (configurable)
|
||||
uniform int bar_width; // bar width (configurable), not used here
|
||||
uniform int bar_spacing; // space bewteen bars (configurable)
|
||||
|
||||
uniform vec3 u_resolution; // window resolution
|
||||
|
||||
//colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
|
||||
uniform vec3 bg_color; // background color
|
||||
uniform vec3 fg_color; // foreground color
|
||||
|
||||
uniform int gradient_count;
|
||||
uniform vec3 gradient_colors[8]; // gradient colors
|
||||
|
||||
vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max)
|
||||
{
|
||||
//create color based on fraction of this color and next color
|
||||
float yr = (y - y_min) / (y_max - y_min);
|
||||
return col_1 * (1.0 - yr) + col_2 * yr;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// find which bar to use based on where we are on the x axis
|
||||
float x = u_resolution.x * fragCoord.x;
|
||||
int bar = int(bars_count * fragCoord.x);
|
||||
|
||||
//calculate a bar size
|
||||
float bar_size = u_resolution.x / bars_count;
|
||||
|
||||
//the y coordinate and bar values are the same
|
||||
float y = bars[bar];
|
||||
|
||||
// make sure there is a thin line at bottom
|
||||
if (y * u_resolution.y < 1.0)
|
||||
{
|
||||
y = 1.0 / u_resolution.y;
|
||||
}
|
||||
|
||||
//draw the bar up to current height
|
||||
if (y > fragCoord.y)
|
||||
{
|
||||
//make some space between bars basen on settings
|
||||
if (x > (bar + 1) * (bar_size) - bar_spacing)
|
||||
{
|
||||
fragColor = vec4(bg_color,1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gradient_count == 0)
|
||||
{
|
||||
fragColor = vec4(fg_color,1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//find which color in the configured gradient we are at
|
||||
int color = int((gradient_count - 1) * fragCoord.y);
|
||||
|
||||
//find where on y this and next color is supposed to be
|
||||
float y_min = color / (gradient_count - 1.0);
|
||||
float y_max = (color + 1.0) / (gradient_count - 1.0);
|
||||
|
||||
//make color
|
||||
fragColor = vec4(normalize_C(fragCoord.y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fragColor = vec4(bg_color,1.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#version 330
|
||||
|
||||
// this shader was stolen from shadertoy user ChunderFPV
|
||||
|
||||
#define SCALE 8.0
|
||||
#define PI radians(180.0)
|
||||
#define TAU (PI * 2.0)
|
||||
#define CS(a) vec2(cos(a), sin(a))
|
||||
#define PT(u, r) smoothstep(0.0, r, r - length(u))
|
||||
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform float bars[512];
|
||||
|
||||
uniform int bars_count; // number of bars (left + right) (configurable)
|
||||
uniform float shader_time; // shader execution time s
|
||||
uniform int bar_width; // bar width (configurable), not used here
|
||||
uniform int bar_spacing; // space bewteen bars (configurable)
|
||||
|
||||
uniform vec3 u_resolution; // window resolution
|
||||
|
||||
// colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
|
||||
uniform vec3 bg_color; // background color
|
||||
uniform vec3 fg_color; // foreground color
|
||||
|
||||
uniform int gradient_count;
|
||||
uniform vec3 gradient_colors[8]; // gradient colors
|
||||
|
||||
// gradient map ( color, equation, time, width, shadow, reciprocal )
|
||||
vec3 gm(vec3 c, float n, float t, float w, float d, bool i) {
|
||||
float g = min(abs(n), 1.0 / abs(n));
|
||||
float s = abs(sin(n * PI - t));
|
||||
if (i)
|
||||
s = min(s, abs(sin(PI / n + t)));
|
||||
return (1.0 - pow(abs(s), w)) * c * pow(g, d) * 6.0;
|
||||
}
|
||||
|
||||
// denominator spiral, use 1/n for numerator
|
||||
// ( screen xy, spiral exponent, decimal, line width, hardness, rotation )
|
||||
float ds(vec2 u, float e, float n, float w, float h, float ro) {
|
||||
float ur = length(u); // unit radius
|
||||
float sr = pow(ur, e); // spiral radius
|
||||
float a = round(sr) * n * TAU; // arc
|
||||
vec2 xy = CS(a + ro) * ur; // xy coords
|
||||
float l = PT(u - xy, w); // line
|
||||
float s = mod(sr + 0.5, 1.0); // gradient smooth
|
||||
s = min(s, 1.0 - s); // darken filter
|
||||
return l * s * h;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float t = shader_time / PI * 2.0;
|
||||
vec4 m = vec4(0, 0, 0, 0); // iMouse;
|
||||
m.xy = m.xy * 2.0 / u_resolution.xy - 1.0; // ±1x, ±1y
|
||||
if (m.z > 0.0)
|
||||
t += m.y * SCALE; // move time with mouse y
|
||||
float z = (m.z > 0.0) ? pow(1.0 - abs(m.y), sign(m.y)) : 1.0; // zoom (+)
|
||||
float e = (m.z > 0.0) ? pow(1.0 - abs(m.x), -sign(m.x))
|
||||
: 1.0; // screen exponent (+)
|
||||
float se = (m.z > 0.0) ? e * -sign(m.y) : 1.0; // spiral exponent
|
||||
vec3 bg = vec3(0); // black background
|
||||
|
||||
float aa = 3.0; // anti-aliasing
|
||||
|
||||
for (float j = 0.0; j < aa; j++)
|
||||
for (float k = 0.0; k < aa; k++) {
|
||||
vec3 c = vec3(0);
|
||||
vec2 o = vec2(j, k) / aa;
|
||||
vec2 uv = (fragCoord * u_resolution.xy - 0.5 * u_resolution.xy + o) /
|
||||
u_resolution.y * SCALE * z; // apply cartesian, scale and zoom
|
||||
if (m.z > 0.0)
|
||||
uv =
|
||||
exp(log(abs(uv)) * e) * sign(uv); // warp screen space with exponent
|
||||
|
||||
float px = length(fwidth(uv)); // pixel width
|
||||
float x = uv.x; // every pixel on x
|
||||
float y = uv.y; // every pixel on y
|
||||
float l = length(uv); // hypot of xy: sqrt(x*x+y*y)
|
||||
|
||||
float mc = (x * x + y * y - 1.0) / y; // metallic circle at xy
|
||||
float g = min(abs(mc), 1.0 / abs(mc)); // gradient
|
||||
vec3 gold = vec3(1.0, 0.6, 0.0) * g * l;
|
||||
vec3 blue = vec3(0.3, 0.5, 0.9) * (1.0 - g);
|
||||
vec3 rgb = max(gold, blue);
|
||||
|
||||
float w = 0.1; // line width
|
||||
float d = 0.4; // shadow depth
|
||||
c = max(c, gm(rgb, mc, -t, w * bars[0], d, false)); // metallic
|
||||
c = max(c, gm(rgb, abs(y / x) * sign(y), -t, w * bars[1], d,
|
||||
false)); // tangent
|
||||
c = max(c, gm(rgb, (x * x) / (y * y) * sign(y), -t, w * bars[2], d,
|
||||
false)); // sqrt cotangent
|
||||
c = max(c, gm(rgb, (x * x) + (y * y), t, w * bars[3], d,
|
||||
true)); // sqrt circles
|
||||
|
||||
c += rgb * ds(uv, se, t / TAU, px * 2.0 * bars[4], 2.0, 0.0); // spiral 1a
|
||||
c += rgb * ds(uv, se, t / TAU, px * 2.0 * bars[5], 2.0, PI); // spiral 1b
|
||||
c +=
|
||||
rgb * ds(uv, -se, t / TAU, px * 2.0 * bars[6], 2.0, 0.0); // spiral 2a
|
||||
c += rgb * ds(uv, -se, t / TAU, px * 2.0 * bars[7], 2.0, PI); // spiral 2b
|
||||
c = max(c, 0.0); // clear negative color
|
||||
|
||||
c += pow(max(1.0 - l, 0.0), 3.0 / z); // center glow
|
||||
|
||||
if (m.z > 0.0) // display grid on click
|
||||
{
|
||||
vec2 xyg = abs(fract(uv + 0.5) - 0.5) / px; // xy grid
|
||||
c.gb += 0.2 * (1.0 - min(min(xyg.x, xyg.y), 1.0));
|
||||
}
|
||||
bg += c;
|
||||
}
|
||||
bg /= aa * aa;
|
||||
bg *= sqrt(bg) * 1.5;
|
||||
|
||||
fragColor = vec4(bg, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#version 330
|
||||
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// bar values. defaults to left channels first (low to high), then right (high to low).
|
||||
uniform float bars[512];
|
||||
|
||||
uniform int bars_count; // number of bars (left + right) (configurable)
|
||||
|
||||
uniform vec3 u_resolution; // window resolution, not used here
|
||||
|
||||
//colors, configurable in cava config file
|
||||
uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here
|
||||
uniform vec3 fg_color; // foreground color, not used here
|
||||
|
||||
void main()
|
||||
{
|
||||
// find which bar to use based on where we are on the x axis
|
||||
int bar = int(bars_count * fragCoord.x);
|
||||
|
||||
float bar_y = 1.0 - abs((fragCoord.y - 0.5)) * 2.0;
|
||||
float y = (bars[bar]) * bar_y;
|
||||
|
||||
float bar_x = (fragCoord.x - float(bar) / float(bars_count)) * bars_count;
|
||||
float bar_r = 1.0 - abs((bar_x - 0.5)) * 2;
|
||||
|
||||
bar_r = bar_r * bar_r * 2;
|
||||
|
||||
// set color
|
||||
fragColor.r = fg_color.x * y * bar_r;
|
||||
fragColor.g = fg_color.y * y * bar_r;
|
||||
fragColor.b = fg_color.z * y * bar_r;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#version 330
|
||||
|
||||
|
||||
// Input vertex data, different for all executions of this shader.
|
||||
layout(location = 0) in vec3 vertexPosition_modelspace;
|
||||
|
||||
// Output data ; will be interpolated for each fragment.
|
||||
out vec2 fragCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(vertexPosition_modelspace,1);
|
||||
fragCoord = (vertexPosition_modelspace.xy+vec2(1,1))/2.0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#version 330
|
||||
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// bar values. defaults to left channels first (low to high), then right (high
|
||||
// to low).
|
||||
uniform float bars[512];
|
||||
|
||||
uniform int bars_count; // number of bars (left + right) (configurable)
|
||||
uniform int bar_width; // bar width (configurable), not used here
|
||||
uniform int bar_spacing; // space bewteen bars (configurable)
|
||||
|
||||
uniform vec3 u_resolution; // window resolution
|
||||
|
||||
// colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
|
||||
uniform vec3 bg_color; // background color
|
||||
uniform vec3 fg_color; // foreground color
|
||||
|
||||
uniform int gradient_count;
|
||||
uniform vec3 gradient_colors[8]; // gradient colors
|
||||
|
||||
uniform sampler2D inputTexture; // Texture from the first render pass
|
||||
|
||||
vec3 normalize_C(float y, vec3 col_1, vec3 col_2, float y_min, float y_max) {
|
||||
// create color based on fraction of this color and next color
|
||||
float yr = (y - y_min) / (y_max - y_min);
|
||||
return col_1 * (1.0 - yr) + col_2 * yr;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// find which bar to use based on where we are on the y axis
|
||||
int bar = int(bars_count * fragCoord.y);
|
||||
float y = bars[bar];
|
||||
float band_size = 1.0 / float(bars_count);
|
||||
float current_band_min = bar * band_size;
|
||||
float current_band_max = (bar + 1) * band_size;
|
||||
|
||||
int hist_length = 512;
|
||||
float win_size = 1.0 / hist_length;
|
||||
|
||||
if (fragCoord.x > 1.0 - win_size) {
|
||||
|
||||
if (fragCoord.y > current_band_min && fragCoord.y < current_band_max) {
|
||||
|
||||
fragColor = vec4(fg_color * y, 1.0);
|
||||
}
|
||||
} else {
|
||||
vec2 offsetCoord = fragCoord;
|
||||
offsetCoord.x += float(win_size);
|
||||
fragColor = texture(inputTexture, offsetCoord);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
#version 330
|
||||
|
||||
// Emulate the "line style" spectrum analyzer from Winamp 2.
|
||||
// Try this config for a demonstration:
|
||||
|
||||
/*
|
||||
[general]
|
||||
bar_width = 2
|
||||
bar_spacing = 0
|
||||
higher_cutoff_freq = 22000
|
||||
|
||||
[output]
|
||||
method = sdl_glsl
|
||||
channels = mono
|
||||
fragment_shader = winamp_line_style_spectrum.frag
|
||||
|
||||
[color]
|
||||
background = '#000000'
|
||||
gradient = 1
|
||||
gradient_color_1 = '#319C08'
|
||||
gradient_color_2 = '#29CE10'
|
||||
gradient_color_3 = '#BDDE29'
|
||||
gradient_color_4 = '#DEA518'
|
||||
gradient_color_5 = '#D66600'
|
||||
gradient_color_6 = '#CE2910'
|
||||
|
||||
[smoothing]
|
||||
noise_reduction = 10
|
||||
*/
|
||||
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// bar values. defaults to left channels first (low to high), then right (high to low).
|
||||
uniform float bars[512];
|
||||
|
||||
uniform int bars_count; // number of bars (left + right) (configurable)
|
||||
uniform int bar_width; // bar width (configurable), not used here
|
||||
uniform int bar_spacing; // space bewteen bars (configurable)
|
||||
|
||||
uniform vec3 u_resolution; // window resolution
|
||||
|
||||
//colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
|
||||
uniform vec3 bg_color; // background color
|
||||
uniform vec3 fg_color; // foreground color
|
||||
|
||||
uniform int gradient_count;
|
||||
uniform vec3 gradient_colors[8]; // gradient colors
|
||||
|
||||
vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max)
|
||||
{
|
||||
//create color based on fraction of this color and next color
|
||||
float yr = (y - y_min) / (y_max - y_min);
|
||||
return col_1 * (1.0 - yr) + col_2 * yr;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// find which bar to use based on where we are on the x axis
|
||||
float x = u_resolution.x * fragCoord.x;
|
||||
int bar = int(bars_count * fragCoord.x);
|
||||
|
||||
//calculate a bar size
|
||||
float bar_size = u_resolution.x / bars_count;
|
||||
|
||||
//the y coordinate is stretched by 4X to resemble Winamp
|
||||
float y = min(bars[bar] * 4.0, 1.0);
|
||||
|
||||
// make sure there is a thin line at bottom
|
||||
if (y * u_resolution.y < 1.0)
|
||||
{
|
||||
y = 1.0 / u_resolution.y;
|
||||
}
|
||||
|
||||
vec4 bar_color;
|
||||
|
||||
if (gradient_count == 0)
|
||||
{
|
||||
bar_color = vec4(fg_color,1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//find color in the configured gradient for the top of the bar
|
||||
int color = int((gradient_count - 1) * y);
|
||||
|
||||
//find where on y this and next color is supposed to be
|
||||
float y_min = float(color) / (gradient_count - 1.0);
|
||||
float y_max = float(color + 1) / (gradient_count - 1.0);
|
||||
|
||||
//make a solid color for the entire bar
|
||||
bar_color = vec4(normalize_C(y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0);
|
||||
}
|
||||
|
||||
|
||||
//draw the bar up to current height
|
||||
if (y > fragCoord.y)
|
||||
{
|
||||
//make some space between bars based on settings
|
||||
if (x > (bar + 1) * (bar_size) - bar_spacing)
|
||||
{
|
||||
fragColor = vec4(bg_color,1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragColor = bar_color;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fragColor = vec4(bg_color,1.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
[color]
|
||||
background = '#001e26'
|
||||
foreground = '#708183'
|
||||
|
||||
gradient = 1
|
||||
gradient_color_1 = '#268bd2'
|
||||
gradient_color_2 = '#6c71c4'
|
||||
gradient_color_3 = '#cb4b16'
|
||||
|
||||
horizontal_gradient = 1
|
||||
horizontal_gradient_color_1 = '#586e75'
|
||||
horizontal_gradient_color_2 = '#b58900'
|
||||
horizontal_gradient_color_3 = '#839496'
|
||||
|
||||
blend_direction = 'up'
|
||||
@@ -0,0 +1,10 @@
|
||||
[color]
|
||||
horizontal_gradient = 1
|
||||
horizontal_gradient_color_1 = '#c45161'
|
||||
horizontal_gradient_color_2 = '#e094a0'
|
||||
horizontal_gradient_color_3 = '#f2b6c0'
|
||||
horizontal_gradient_color_4 = '#f2dde1'
|
||||
horizontal_gradient_color_5 = '#cbc7d8'
|
||||
horizontal_gradient_color_6 = '#8db7d2'
|
||||
horizontal_gradient_color_7 = '#5e62a9'
|
||||
horizontal_gradient_color_8 = '#434279'
|
||||
@@ -0,0 +1,21 @@
|
||||
# Global user preferences (applies to every project)
|
||||
|
||||
## Environment
|
||||
- Arch Linux, Wayland, fish shell, kitty terminal. Prefer fish-compatible syntax in shell snippets (not bash-isms) when writing things the user will run interactively. Clipboard is `wl-copy`.
|
||||
- Package manager: pacman / yay. Common abbrs: `pacs`, `yays`.
|
||||
|
||||
## Local-first LLMs
|
||||
- The user self-hosts models on the LAN at `192.168.0.204`:
|
||||
- llama.cpp server — `http://192.168.0.204:11343/v1` (OpenAI-compatible).
|
||||
- Ollama — `192.168.0.204:11434`.
|
||||
- Recurring models: Qwen3-Coder-30B, gemma-4-26B, DeepSeek-Coder-V2-Lite, GLM-4.7-Flash. When configuring any AI/agent tool, default to these endpoints rather than a cloud API unless asked otherwise.
|
||||
|
||||
## Git
|
||||
- **Do not run `git commit` or `git push`, and never offer or ask to do the committing/pushing yourself** — the user reviews and commits entirely manually (these are also denied in settings.json). Stage/prepare changes and stop there. You may suggest a commit message for the user to use, but nothing more.
|
||||
- To hand off a suggested commit message, write it to the per-worktree file `$(git rev-parse --git-path CLAUDE_COMMIT_MSG)` — **not** `COMMIT_EDITMSG` (git overwrites that on `git commit`). A `prepare-commit-msg` hook prefills the editor from it (one-shot) on the next `git commit` / lazygit `C`. Just the raw message, no `#` comments.
|
||||
|
||||
## Formatting
|
||||
- Lua: format with `stylua` (2-space indent, 120 col, no call parentheses — see any `.stylua.toml`).
|
||||
|
||||
## Dotfiles
|
||||
- Configs live in the dots repo under `.config/` and are surfaced via per-directory symlinks into `~/.config/` (and `~/.claude/`). Editing a file under the repo's `.config/` is editing the live config — no deploy step.
|
||||
@@ -0,0 +1,91 @@
|
||||
# Claude Code config
|
||||
|
||||
Portable [Claude Code](https://claude.com/claude-code) customizations, synced via these
|
||||
dots. Claude Code still uses its default `~/.claude/` directory; we surface the tracked
|
||||
files below into it via per-file/dir symlinks, so edits made through Claude write straight
|
||||
back into this repo.
|
||||
|
||||
## What's tracked here
|
||||
|
||||
- `settings.json` — global settings: permissions (deny git commit/push + read of secret
|
||||
files), default `model`, `enabledPlugins`, vim mode, dark theme, `effortLevel`, fullscreen
|
||||
TUI, `statusLine`, `hooks`, `worktree` defaults, …
|
||||
- `statusline.py` — rich status line (dir, git, model, context %, cost, disk — system metrics live in the tmux bar).
|
||||
See [StatusBar.md](StatusBar.md) for what each segment and colour means.
|
||||
- `keybindings.json` — custom keybindings (vim-style scroll/navigation).
|
||||
- `CLAUDE.md` — global user preferences applied to every project.
|
||||
- `hooks/format.py` — PostToolUse hook: formats edited files by extension (stylua / ruff /
|
||||
prettier / gofmt / rustfmt / fish_indent / shfmt / taplo). Opinionated formatters (stylua, ruff,
|
||||
prettier, taplo) only run where the project opts in via a config file found walking up; gofmt and
|
||||
rustfmt gate on a project marker (`go.mod` / `Cargo.toml`); fish_indent and shfmt run on sight.
|
||||
No-ops if the formatter isn't installed, and always exits 0.
|
||||
- `skills/` — custom [Agent Skills](https://code.claude.com/docs/en/skills). See **Skills** below.
|
||||
- `link.sh` — idempotent bootstrap that creates the `~/.claude` symlinks below.
|
||||
|
||||
Paths inside `settings.json` reference `~/.claude/...` via `$HOME`/`PATH` (`/usr/bin/env
|
||||
python3 ~/.claude/...`), so they work regardless of the username, python location, or where the
|
||||
dots repo is cloned (`~/.dots`, …).
|
||||
|
||||
## What is **not** tracked (stays local, per device)
|
||||
|
||||
Everything else under `~/.claude/` is machine-specific or secret and must never be committed:
|
||||
credentials (`.credentials.json`), session history, `projects/` (transcripts + memory),
|
||||
caches, and the `plugins/` cache/binaries.
|
||||
|
||||
## Setup on a new device
|
||||
|
||||
```sh
|
||||
# 1. Deploy the dotfiles repo — install.sh stows ~/.config/claude AND runs link.sh for you
|
||||
cd ~/.dots && ./install.sh
|
||||
|
||||
# 2. Launch Claude and log in once (credentials are NOT synced)
|
||||
claude
|
||||
|
||||
# 3. Reinstall the plugins from settings.json -> enabledPlugins
|
||||
# (typescript-lsp, frontend-design — anthropics/claude-plugins-official) via /plugin.
|
||||
# Optional: install any formatters you want the hook to use (stylua, ruff, prettier, …).
|
||||
```
|
||||
|
||||
`install.sh` deploys `~/.config/claude` (via stow) and then runs `link.sh` automatically. You only
|
||||
need to run `link.sh` by hand (`bash ~/.config/claude/link.sh`) if a link later gets clobbered
|
||||
(e.g. Claude's `/config` replaces one with a plain file) — it's idempotent and self-healing.
|
||||
|
||||
A **new skill/hook** added to the repo shows up after a re-stow — `./install.sh` (or `dotsync`) links
|
||||
the new file into `~/.config/claude`, which `link.sh` then surfaces into `~/.claude`.
|
||||
|
||||
## Skills
|
||||
|
||||
Custom skills live in `skills/<name>/SKILL.md` (the directory name is the `/command`) and are
|
||||
linked in as `~/.claude/skills`. All are `disable-model-invocation: true` — explicit `/` only,
|
||||
so Claude never auto-triggers them. Run them inside the repo whose branch you're working on.
|
||||
|
||||
- **`/review-branch [base]`** — reviews the current branch's diff (vs its merge-base with the
|
||||
base branch) for 🐞 bugs / 🔒 security / ⚡ optimizations / 📖 readability, reports grouped
|
||||
findings with `file:line`, then applies the readability + safe fixes *after you approve*. Never
|
||||
commits.
|
||||
Borrows `/code-review`'s discipline: CLAUDE.md-aware, changed-lines-only, verified bugs with a
|
||||
false-positive filter (skips what linters/CI catch and pre-existing issues). Ends by pointing
|
||||
you at the relevant built-in follow-ups (`/security-review`, `/code-review`, `/verify`, …).
|
||||
- **`/pr-description [base]`** — auto-detects this repo's GitHub PR template
|
||||
(`.github/pull_request_template.md`, …), fills it from the branch diff + commits, prints a
|
||||
copy-paste markdown block, and copies it to the clipboard with `wl-copy`. Leaves verification
|
||||
checkboxes for you; never creates/pushes the PR.
|
||||
- **`/commit-msg [hint]`** — reads the **staged** diff, infers the repo's commit style from recent
|
||||
`git log` (e.g. this repo's `[Scope] summary`), drafts a matching message, prints it, and copies
|
||||
it to the clipboard with `wl-copy`. Never stages or commits — draft only.
|
||||
- **`/pr-loop [pr]`** — babysits the current branch's PR in a self-paced loop: fixes review
|
||||
comments that don't need your input — from **any** reviewer (Codex, Claude, humans) plus any
|
||||
`@claude` request — `git add`s them, drafts the commit message (`/commit-msg` style) and marks
|
||||
each thread with a reaction instead of an "Addressed — …" reply: **👍** fixed, **👀** parked for
|
||||
your decision, **👎** a bot false positive (bots only, always with a one-line why). Then pings you
|
||||
to commit & push and re-checks every ~10 min (via `ScheduleWakeup`). Resolves threads once their
|
||||
fix is pushed — dismissals right away, since there's nothing to land. Stops when no unresolved comments
|
||||
remain or the automated reviewers (Codex/Claude) hit their limit. Prep-only — never
|
||||
commits/pushes/merges; needs `gh` authed and the session left open. Each cycle it prints when it
|
||||
will re-check and that `Esc` (between cycles) stops it; on the last cycle it prints a clear
|
||||
**"Finished — no more active issues"** and does not reschedule.
|
||||
|
||||
## Adding more config later
|
||||
|
||||
Drop the file/dir under `.config/claude/` here, add its name to the `items` list in `link.sh`,
|
||||
and re-run `bash ~/.config/claude/link.sh`. For example `commands/` or `agents/`.
|
||||
@@ -0,0 +1,76 @@
|
||||
# Status line (`statusline.py`)
|
||||
|
||||
The custom Claude Code status line, ordered **work info (left) → system info (right)**,
|
||||
segments joined by a light-gray `│`. It's **responsive**: always a single line — if the
|
||||
rendered width would exceed the terminal (`$COLUMNS`, which Claude Code re-exports on
|
||||
resize), trailing (lowest-priority) segments are dropped from the right until it fits.
|
||||
|
||||
Wide — everything:
|
||||
|
||||
```
|
||||
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Opus 4.8 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h │ 💾 81%
|
||||
```
|
||||
|
||||
Narrow — trailing segments trimmed:
|
||||
|
||||
```
|
||||
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Opus 4.8 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h
|
||||
```
|
||||
|
||||
Every segment is defensive: if its data is missing or a command fails, the segment is
|
||||
simply omitted (the bar never crashes the UI). Secondary detail (the parts in light gray)
|
||||
is supplementary to the main colored value.
|
||||
|
||||
## Live segments
|
||||
|
||||
| | Segment | Shows | Notes |
|
||||
|---|---|---|---|
|
||||
| | **Vim mode** | `[I]`/`[N]`/`[V]` editor mode | only with `editorMode: vim`; pair with `hideVimModeIndicator: true` so the built-in one doesn't duplicate it |
|
||||
| 📁 | **Directory** | Current working dir, with `~` for home | cyan |
|
||||
| 🌿 | **Git** | `repo branch` + `*` if dirty + `↑N`/`↓N` ahead/behind upstream | repo = magenta; branch = green when clean, yellow + red `*` when dirty; `↑` cyan, `↓` yellow. Omitted outside a repo |
|
||||
| 🤖 | **Model** | Active model display name + `· effort` level (`low`/`medium`/`high`/`xhigh`) | name = blue, effort = light gray; effort omitted for models without the param |
|
||||
| 📝 | **Context** | `% of context window used` + `(Nk)` tokens | window = 1M for `[1m]` models, else 200k. Adds a red **⚠compact** at ≥80% |
|
||||
| 📊 | **5h usage** | `% of the 5-hour rolling limit used` + time until it resets | from `rate_limits.five_hour`; Pro/Max only, and absent until the first API response of a session |
|
||||
| 💰 | **Cost** | `$` session cost so far + `$/h` burn rate | burn rate shown once the session exceeds ~30s |
|
||||
| 💾 | **Disk** | `% used` of the filesystem at the cwd | from `statvfs` |
|
||||
|
||||
## Colour legend
|
||||
|
||||
Most numbers are **green / yellow / red** by threshold — green = healthy, red = needs
|
||||
attention. Light gray = secondary detail. Thresholds (`green < … < yellow < … ≤ red`):
|
||||
|
||||
| Segment | green | yellow | red |
|
||||
|---|---|---|---|
|
||||
| Context | `< 50%` | `50–80%` | `≥ 80%` (⚠compact) |
|
||||
| 5h usage | `< 50%` | `50–80%` | `≥ 80%` |
|
||||
| Disk | `< 75%` | `75–90%` | `≥ 90%` |
|
||||
|
||||
> Light gray is `\033[37m`; dimming (`\033[2m`) is disabled because it blended the gray
|
||||
> detail text into dark terminal backgrounds. To go brighter, set `"gray"` to `\033[97m`
|
||||
> (bright white) in the `C` table near the top of `statusline.py`.
|
||||
|
||||
## Optional segments (defined but not shown)
|
||||
|
||||
These functions exist in `statusline.py` but aren't in the output. Enable one by adding it
|
||||
to the `work` or `system` list in `main()`:
|
||||
|
||||
RAM/CPU/temp were **retired 2026-07-26**: the status line only refreshes on message
|
||||
events, so system metrics sat visibly stale between turns — the tmux status bar
|
||||
(`tmux/scripts/`) owns live system metrics now.
|
||||
|
||||
| | Function | Shows |
|
||||
|---|---|---|
|
||||
| 🧠 | `ram_segment` | `% used` + `used/totalG` from `/proc/meminfo` (green `<70%` / yellow / red `≥85%`) |
|
||||
| 🖥️ | `cpu_segment` | `% busy` (diffed `/proc/stat` snapshot) + loadavg + cores (green `<60%` / red `≥85%`) |
|
||||
| 🌡️ | `temp_segment` | hottest CPU thermal zone °C (green `<60` / red `≥80`) |
|
||||
| ✏️ | `velocity_segment` | `+added/-removed` lines this session + lines/min |
|
||||
| ♻️ | `cache_segment` | prompt-cache hit % (higher is better) |
|
||||
| ⚙️ | `api_segment` | share of wall-clock time spent in API/inference |
|
||||
| | `version_segment` | Claude Code version (`vX.Y.Z`) |
|
||||
| 🎨 | `style_segment` | active output-style name |
|
||||
|
||||
## Where it lives
|
||||
|
||||
`statusline.py` is tracked in this repo and symlinked to `~/.claude/statusline.py`;
|
||||
`settings.json` runs it via `statusLine` (`/usr/bin/env python3 ~/.claude/statusline.py`).
|
||||
Edits take effect on the next status refresh.
|
||||
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python3
|
||||
"""PostToolUse hook: format an edited file with the right formatter.
|
||||
|
||||
Reads the hook JSON from stdin, extracts the edited file path, and runs a
|
||||
language-appropriate formatter -- but, to avoid imposing a style on a project
|
||||
that never asked for it, opinionated formatters (stylua, ruff, prettier, taplo)
|
||||
only run when the project opts in via a config file discoverable by walking up
|
||||
from the edited file. Canonical single-style toolchains run on sight: gofmt and
|
||||
rustfmt on their go.mod / Cargo.toml marker; fish_indent and shfmt whenever the
|
||||
tool itself is installed (shell and fish have one de-facto style, no config).
|
||||
|
||||
Best-effort: always exits 0 so a format hiccup never blocks an edit. jq is not
|
||||
guaranteed on the host, hence python for the stdin JSON parse.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def find_up(start, names):
|
||||
"""Nearest ancestor dir (incl. the file's own) containing any of `names`."""
|
||||
d = os.path.dirname(os.path.abspath(start))
|
||||
while True:
|
||||
if any(os.path.exists(os.path.join(d, n)) for n in names):
|
||||
return d
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
return None
|
||||
d = parent
|
||||
|
||||
|
||||
def has_toml_section(start, filename, section):
|
||||
"""True if the nearest ancestor `filename` contains `section`."""
|
||||
d = find_up(start, [filename])
|
||||
if not d:
|
||||
return False
|
||||
try:
|
||||
with open(os.path.join(d, filename), errors="ignore") as fh:
|
||||
return section in fh.read()
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def stylua_cmd(path):
|
||||
exe = os.path.expanduser("~/.local/share/nvim/mason/bin/stylua")
|
||||
if not os.access(exe, os.X_OK):
|
||||
exe = shutil.which("stylua")
|
||||
if exe and find_up(path, [".stylua.toml", "stylua.toml"]):
|
||||
return [exe, path]
|
||||
return None
|
||||
|
||||
|
||||
def ruff_cmd(path):
|
||||
exe = shutil.which("ruff")
|
||||
if exe and (find_up(path, ["ruff.toml", ".ruff.toml"])
|
||||
or has_toml_section(path, "pyproject.toml", "[tool.ruff")):
|
||||
return [exe, "format", path]
|
||||
return None
|
||||
|
||||
|
||||
_PRETTIER_CFGS = [
|
||||
".prettierrc", ".prettierrc.json", ".prettierrc.yaml", ".prettierrc.yml",
|
||||
".prettierrc.json5", ".prettierrc.js", ".prettierrc.cjs", ".prettierrc.mjs",
|
||||
".prettierrc.toml", "prettier.config.js", "prettier.config.cjs",
|
||||
"prettier.config.mjs",
|
||||
]
|
||||
|
||||
|
||||
def prettier_cmd(path):
|
||||
exe = shutil.which("prettier")
|
||||
if exe and find_up(path, _PRETTIER_CFGS):
|
||||
return [exe, "--write", path]
|
||||
return None
|
||||
|
||||
|
||||
def gofmt_cmd(path):
|
||||
exe = shutil.which("gofmt")
|
||||
if exe and find_up(path, ["go.mod"]): # one canonical style
|
||||
return [exe, "-w", path]
|
||||
return None
|
||||
|
||||
|
||||
def rustfmt_cmd(path):
|
||||
exe = shutil.which("rustfmt")
|
||||
if exe and find_up(path, ["Cargo.toml", "rustfmt.toml", ".rustfmt.toml"]):
|
||||
return [exe, path]
|
||||
return None
|
||||
|
||||
|
||||
def fish_cmd(path):
|
||||
exe = shutil.which("fish_indent") # ships with fish, one canonical style
|
||||
return [exe, "-w", path] if exe else None
|
||||
|
||||
|
||||
def shfmt_cmd(path):
|
||||
exe = shutil.which("shfmt") # de-facto shell formatter, sane defaults
|
||||
return [exe, "-w", path] if exe else None
|
||||
|
||||
|
||||
def taplo_cmd(path):
|
||||
exe = shutil.which("taplo")
|
||||
# opt-in: TOML reflow/align is intrusive, so only where the project asked.
|
||||
if exe and find_up(path, ["taplo.toml", ".taplo.toml"]):
|
||||
return [exe, "format", path]
|
||||
return None
|
||||
|
||||
|
||||
HANDLERS = {
|
||||
".lua": stylua_cmd,
|
||||
".py": ruff_cmd,
|
||||
".js": prettier_cmd, ".jsx": prettier_cmd, ".mjs": prettier_cmd,
|
||||
".cjs": prettier_cmd, ".ts": prettier_cmd, ".tsx": prettier_cmd,
|
||||
".css": prettier_cmd, ".scss": prettier_cmd, ".less": prettier_cmd,
|
||||
".html": prettier_cmd, ".vue": prettier_cmd, ".json": prettier_cmd,
|
||||
".md": prettier_cmd, ".yaml": prettier_cmd, ".yml": prettier_cmd,
|
||||
".go": gofmt_cmd,
|
||||
".rs": rustfmt_cmd,
|
||||
".fish": fish_cmd,
|
||||
".sh": shfmt_cmd, ".bash": shfmt_cmd,
|
||||
".toml": taplo_cmd,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
data = json.load(sys.stdin)
|
||||
except Exception:
|
||||
return
|
||||
ti = data.get("tool_input") or {}
|
||||
tr = data.get("tool_response") or {}
|
||||
path = ti.get("file_path") or tr.get("filePath") or ""
|
||||
if not path or not os.path.isfile(path):
|
||||
return
|
||||
handler = HANDLERS.get(os.path.splitext(path)[1].lower())
|
||||
if not handler:
|
||||
return
|
||||
cmd = handler(path)
|
||||
if not cmd:
|
||||
return
|
||||
try:
|
||||
subprocess.run(cmd, timeout=15, capture_output=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
|
||||
"$docs": "https://code.claude.com/docs/en/keybindings",
|
||||
"bindings": [
|
||||
{
|
||||
"context": "Global",
|
||||
"bindings": {
|
||||
"alt+j": "scroll:lineDown",
|
||||
"alt+k": "scroll:lineUp",
|
||||
"ctrl+shift+j": "scroll:lineDown",
|
||||
"ctrl+shift+k": "scroll:lineUp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "MessageSelector",
|
||||
"bindings": {
|
||||
"g": "messageSelector:top",
|
||||
"shift+g": "messageSelector:bottom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Select",
|
||||
"bindings": {
|
||||
"g": "select:first",
|
||||
"shift+g": "select:last"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Footer",
|
||||
"bindings": {
|
||||
"j": "footer:down",
|
||||
"k": "footer:up"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
# Surface this repo's Claude Code config into ~/.claude via symlinks.
|
||||
#
|
||||
# `stow` deploys the repo to ~/.config/claude; Claude itself reads from ~/.claude,
|
||||
# so we link the individual files/dirs across. Idempotent and self-healing: re-run
|
||||
# any time. It also flags any file that has broken out of stow into a plain file —
|
||||
# which silently stops Claude's edits from reaching the repo.
|
||||
# (New skills/hooks added to the repo appear after a re-stow: `./install.sh` or `dotsync`.)
|
||||
#
|
||||
# bash ~/.config/claude/link.sh
|
||||
set -eu
|
||||
|
||||
SRC="$HOME/.config/claude"
|
||||
DST="$HOME/.claude"
|
||||
|
||||
if [ ! -e "$SRC" ]; then
|
||||
echo "error: $SRC not found — run 'cd ~/.dots && ./install.sh' first" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$DST"
|
||||
|
||||
# This repo's claude dir, resolved via link.sh's own symlink (location-independent).
|
||||
repo=$(dirname "$(readlink -f "$SRC/link.sh")")
|
||||
|
||||
# If link.sh itself has broken out of stow into a plain file, $repo resolves to $SRC and
|
||||
# the drift heal below would relink each drifted file onto ITSELF — destroying the only
|
||||
# copy of its content. Refuse to continue.
|
||||
if [ "$repo" = "$SRC" ]; then
|
||||
echo "error: link.sh itself is a plain file (broken out of stow) — re-stow first:" >&2
|
||||
echo " cd ~/.dots && ./install.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Tracked items to expose in ~/.claude. Add new ones (e.g. commands agents) here.
|
||||
items="settings.json statusline.py keybindings.json CLAUDE.md hooks skills"
|
||||
|
||||
# Expose each item in ~/.claude (where Claude actually reads).
|
||||
for item in $items; do
|
||||
[ -e "$SRC/$item" ] || continue
|
||||
if [ -d "$DST/$item" ] && [ ! -L "$DST/$item" ]; then
|
||||
echo "skip ~/.claude/$item (real directory in the way — move it aside first)" >&2
|
||||
continue
|
||||
fi
|
||||
# A plain FILE here means an atomic write replaced the link (Claude writes e.g.
|
||||
# ~/.claude/settings.json) — it may hold newer edits, so never clobber it silently:
|
||||
# heal only when provably lossless, warn otherwise (mirrors the SRC drift guard below).
|
||||
if [ -f "$DST/$item" ] && [ ! -L "$DST/$item" ]; then
|
||||
same=0
|
||||
case "$item" in
|
||||
*.json)
|
||||
python3 -c 'import json,sys; sys.exit(0 if json.load(open(sys.argv[1]))==json.load(open(sys.argv[2])) else 1)' \
|
||||
"$DST/$item" "$SRC/$item" 2>/dev/null && same=1 ;;
|
||||
*)
|
||||
cmp -s "$DST/$item" "$SRC/$item" && same=1 ;;
|
||||
esac
|
||||
if [ "$same" != 1 ]; then
|
||||
echo "DRIFT ~/.claude/$item is a real file that differs from the repo copy —" >&2
|
||||
echo " it may hold newer edits. Review, then re-link:" >&2
|
||||
echo " diff '$DST/$item' '$SRC/$item' # compare; keep whichever is right" >&2
|
||||
echo " ln -sfn '$SRC/$item' '$DST/$item' # re-link" >&2
|
||||
continue
|
||||
fi
|
||||
echo "healed ~/.claude/$item (plain copy identical to repo — re-linking)"
|
||||
fi
|
||||
ln -sfn "$SRC/$item" "$DST/$item"
|
||||
echo "linked ~/.claude/$item -> ~/.config/claude/$item"
|
||||
done
|
||||
|
||||
# Stow-layer drift guard: each SRC *file* should be a symlink into the repo, so edits
|
||||
# Claude writes (e.g. via /config) flow back and stay tracked. If an atomic write
|
||||
# replaced one with a plain file, it has silently broken out of stow. Auto-heal only
|
||||
# when provably lossless — the plain file is identical to the repo copy (JSON compared
|
||||
# ignoring key order, since /config often just reorders keys). Otherwise warn and stop:
|
||||
# the file may hold newer edits worth diffing in before re-linking.
|
||||
for item in $items; do
|
||||
[ -f "$SRC/$item" ] && [ ! -L "$SRC/$item" ] || continue # a real file where a link belongs
|
||||
same=0
|
||||
if [ -f "$repo/$item" ]; then
|
||||
case "$item" in
|
||||
*.json)
|
||||
python3 -c 'import json,sys; sys.exit(0 if json.load(open(sys.argv[1]))==json.load(open(sys.argv[2])) else 1)' \
|
||||
"$SRC/$item" "$repo/$item" 2>/dev/null && same=1 ;;
|
||||
*)
|
||||
cmp -s "$SRC/$item" "$repo/$item" && same=1 ;;
|
||||
esac
|
||||
fi
|
||||
if [ "$same" = 1 ]; then
|
||||
ln -sfrn "$repo/$item" "$SRC/$item" # -r: relative link, so stow keeps owning it
|
||||
echo "healed ~/.config/claude/$item (plain copy identical to repo — re-linked)"
|
||||
continue
|
||||
fi
|
||||
echo "DRIFT ~/.config/claude/$item is a real file that differs from the repo copy —" >&2
|
||||
echo " it may hold edits not yet tracked. Review, then re-link:" >&2
|
||||
echo " diff '$SRC/$item' '$repo/$item' # compare; keep whichever is right" >&2
|
||||
echo " ln -sfrn '$repo/$item' '$SRC/$item' # re-link (relative, stow-owned)" >&2
|
||||
done
|
||||
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"attribution": {
|
||||
"commit": "",
|
||||
"pr": ""
|
||||
},
|
||||
"permissions": {
|
||||
"deny": [
|
||||
"Bash(git push)",
|
||||
"Bash(git push:*)",
|
||||
"Bash(git commit)",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(git reset --hard)",
|
||||
"Bash(git reset --hard:*)",
|
||||
"Bash(git clean)",
|
||||
"Bash(git clean:*)",
|
||||
"Read(**/.env)",
|
||||
"Read(**/.env.*)",
|
||||
"Read(**/*.env)",
|
||||
"Read(**/*.pem)",
|
||||
"Read(**/*.key)",
|
||||
"Read(**/*.p12)",
|
||||
"Read(**/*.pfx)",
|
||||
"Read(**/*.keystore)",
|
||||
"Read(**/id_rsa*)",
|
||||
"Read(**/.ssh/**)",
|
||||
"Read(**/.aws/**)",
|
||||
"Read(**/.npmrc)",
|
||||
"Read(**/.netrc)",
|
||||
"Read(**/.git-credentials)",
|
||||
"Read(**/.claude/.credentials.json)",
|
||||
"Read(**/secrets.fish)",
|
||||
"Read(**/*.token)",
|
||||
"Read(**/.envrc)"
|
||||
],
|
||||
"defaultMode": "auto"
|
||||
},
|
||||
"model": "opus[1m]",
|
||||
"enableWorkflows": false,
|
||||
"skipWorkflowUsageWarning": true,
|
||||
"enabledPlugins": {
|
||||
"typescript-lsp@claude-plugins-official": true,
|
||||
"frontend-design@claude-plugins-official": true
|
||||
},
|
||||
"statusLine": {
|
||||
"type": "command",
|
||||
"command": "/usr/bin/env python3 ~/.claude/statusline.py",
|
||||
"padding": 0,
|
||||
"hideVimModeIndicator": true
|
||||
},
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write|MultiEdit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "/usr/bin/env python3 ~/.claude/hooks/format.py",
|
||||
"timeout": 20,
|
||||
"statusMessage": "format"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"worktree": {
|
||||
"baseRef": "fresh"
|
||||
},
|
||||
"effortLevel": "xhigh",
|
||||
"advisorModel": "fable",
|
||||
"tui": "fullscreen",
|
||||
"theme": "dark",
|
||||
"editorMode": "vim",
|
||||
"verbose": true,
|
||||
"autoCompactEnabled": true,
|
||||
"remoteControlAtStartup": false,
|
||||
"inputNeededNotifEnabled": false,
|
||||
"agentPushNotifEnabled": false,
|
||||
"skipAutoPermissionPrompt": true
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
description: Draft a commit message for the staged changes, matching this repo's commit style, then print it in the reply, save it to the repo's CLAUDE_COMMIT_MSG file, and copy it to the clipboard. Never stages or commits. Use once you've staged what you want to commit.
|
||||
argument-hint: [optional focus/scope hint]
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash(git diff:*), Bash(git log:*), Bash(git status:*), Bash(git rev-parse:*), Bash(wl-copy:*), Read, Glob, Write
|
||||
---
|
||||
|
||||
# Draft a commit message for the staged changes
|
||||
|
||||
Context for the current commit — what's staged, plus this repo's recent style:
|
||||
|
||||
!`echo "=== Staged (git diff --cached --stat) ==="; git --no-pager diff --cached --stat 2>/dev/null; echo; echo "=== Working tree (git status --short) ==="; git --no-pager status --short 2>/dev/null; echo; echo "=== Recent subjects — match this convention ==="; git --no-pager log -20 --pretty=format:'%s' 2>/dev/null`
|
||||
|
||||
## What to do
|
||||
|
||||
1. **See exactly what's being committed.** Read the full staged diff with
|
||||
`git --no-pager diff --cached`. If nothing is staged (the stat above is empty), tell me and
|
||||
**stop** — I stage changes myself; never run `git add`.
|
||||
2. **Learn the repo's commit style** from the recent subjects above — prefix convention (this repo
|
||||
uses `[Scope] summary`), imperative vs. past tense, subject length, whether bodies are used.
|
||||
Match what's already there; don't impose Conventional Commits / gitmoji if the repo doesn't use
|
||||
them.
|
||||
3. **Write the message from the *actual* staged diff** (not a guess):
|
||||
- A concise subject in the repo's style (~50 chars, imperative). Fold in my hint if given:
|
||||
**$ARGUMENTS**.
|
||||
- Add a short body (wrapped ~72 cols) only when the change needs the *why*; otherwise
|
||||
subject-only. Don't invent motivation that isn't evident from the diff.
|
||||
4. **Print the message in your reply first** — as a single fenced ` ```text ` block, copy-paste
|
||||
ready. This in-reply copy is the durable one: it lives in the transcript, so it survives even if
|
||||
the clipboard gets overwritten later (by me copying something else, or another Claude session
|
||||
running `wl-copy`). Always print it; don't rely on the clipboard alone.
|
||||
5. **Save it to a file in the repo** so I can recover it any time: resolve the path with
|
||||
`git rev-parse --git-path CLAUDE_COMMIT_MSG` (per-worktree correct), then use the Write tool to
|
||||
write the raw message there — **not** `COMMIT_EDITMSG`, which git overwrites on every
|
||||
`git commit` before the editor opens. My `prepare-commit-msg` hook prefills the commit editor
|
||||
from `CLAUDE_COMMIT_MSG` (one-shot) on the next `git commit` / lazygit `C`. The file lives
|
||||
inside the git dir so it never shows up in `git status`.
|
||||
6. **Also copy it to the clipboard** as a convenience: `wl-copy < <path from step 5>`. Then
|
||||
tell me all three places it is: **printed above**, **saved to `CLAUDE_COMMIT_MSG`** (hook
|
||||
prefills the next commit), and **on the clipboard** — so I never lose it to a stray copy.
|
||||
7. **Never** run `git add`, `git commit`, or `git push`, and never offer to — I stage and commit
|
||||
manually. Draft only.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
description: Draft a ready-to-paste PR description by filling this repo's GitHub PR template from the branch diff and commits, then copy it to the clipboard. Use after finishing a feature.
|
||||
argument-hint: [base-branch]
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash(git diff:*), Bash(git log:*), Bash(git merge-base:*), Bash(git symbolic-ref:*), Bash(git rev-parse:*), Bash(git show-ref:*), Bash(ls:*), Bash(cat:*), Bash(wl-copy:*), Bash(mktemp:*), Bash(rm:*), Read, Glob
|
||||
---
|
||||
|
||||
# Draft this branch's PR description
|
||||
|
||||
This repo's PR template (first match), plus the branch's changes:
|
||||
|
||||
!`for f in .github/pull_request_template.md .github/PULL_REQUEST_TEMPLATE.md docs/pull_request_template.md docs/PULL_REQUEST_TEMPLATE.md PULL_REQUEST_TEMPLATE.md pull_request_template.md; do if [ -f "$f" ]; then echo "=== PR template: $f ==="; cat "$f"; found=1; break; fi; done; if [ -z "$found" ]; then if [ -d .github/PULL_REQUEST_TEMPLATE ]; then echo "=== template dir .github/PULL_REQUEST_TEMPLATE/ (pick one) ==="; ls .github/PULL_REQUEST_TEMPLATE/; else echo "(no PR template found — use the fallback structure)"; fi; fi`
|
||||
|
||||
!`b=$(git symbolic-ref --short -q refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@'); [ -z "$b" ] && { git show-ref -q --verify refs/heads/main && b=main || b=master; }; m=$(git merge-base "$b" HEAD 2>/dev/null); echo "Branch: $(git rev-parse --abbrev-ref HEAD 2>/dev/null) Base: $b Range: ${m:-?}..HEAD"; echo; echo "Commits:"; git --no-pager log --oneline "${m}..HEAD" 2>/dev/null; echo; echo "Files changed:"; git --no-pager diff --stat "${m}...HEAD" 2>/dev/null`
|
||||
|
||||
## What to do
|
||||
|
||||
1. **Resolve the base branch** (use the invocation argument if given — **$ARGUMENTS** — else the
|
||||
detected base) and read the full diff + commit messages for `merge-base..HEAD`.
|
||||
2. **Fill the PR template shown above** from the *actual* changes:
|
||||
- Write the Summary / motivation and any "Implementation Notes" from the diff and commits.
|
||||
- Fill the **Type of Change** field or boxes with the kinds that genuinely match (feature /
|
||||
fix / refactor / perf / tests / docs / chore).
|
||||
- Tick `Self-reviewed` and `LLM-assisted` if those boxes exist.
|
||||
- **Leave verification boxes unchecked** — e.g. "tests passed", "`validate:full` passes",
|
||||
"pre-commit hooks passed". I confirm those myself; never tick them for me.
|
||||
- Fill **Related Issues** from issue numbers in the branch name or commit trailers; delete any
|
||||
placeholder lines you can't fill (never leave a dangling `Closes #`), and drop the whole
|
||||
section if there are no issues to reference.
|
||||
- If a multi-template dir was listed (no single file), pick the most fitting one and say which.
|
||||
- **If no template exists**, use this fallback: `## Summary` / `## Changes` / `## Testing` /
|
||||
`## Notes`.
|
||||
3. **Output** the filled description as a single fenced ```markdown code block, copy-paste ready.
|
||||
4. **Copy it to the clipboard**: write the same markdown to a temp file (`mktemp`) and run
|
||||
`wl-copy < "$tmpfile"`, then remove the temp file. Tell me it's on the clipboard.
|
||||
5. **Do not** create, push, or edit the PR (`gh pr ...`) — I add the text to the PR myself.
|
||||
@@ -0,0 +1,275 @@
|
||||
---
|
||||
description: Babysit the current branch's PR — address review comments that don't need my input, re-check every ~10 min, and stop when there are no open comments left or the automated reviewers (Codex, Claude) hit their limit. Prep-only — stages fixes and drafts the commit message; never commits, pushes, or merges.
|
||||
argument-hint: [pr number or url — optional; defaults to the current branch's PR]
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash(gh:*), Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git rev-parse:*), Bash(git fetch:*), Bash(git add:*), Bash(wl-copy:*), Read, Edit, Write, Grep, Glob, ScheduleWakeup
|
||||
---
|
||||
|
||||
# Watch this PR and resolve review comments (prep-only)
|
||||
|
||||
A self-paced loop over one PR's review feedback: fix the comments that don't need my judgement,
|
||||
stage them, draft a commit message, then wait ~10 min and re-check — until there are no unresolved
|
||||
comments left or the automated reviewers (Codex/Claude) hit a usage limit.
|
||||
|
||||
**The contract — read this first:**
|
||||
- **I never commit, push, or merge.** Each cycle you *prepare*: edit + `git add` + draft a commit
|
||||
message + reply on the threads you handled. Then you **ping me to commit & push**, and the loop
|
||||
resumes after I do. This honours the global no-commit/no-push rule; nothing in `settings.json`
|
||||
changes.
|
||||
- **React, don't reply — then resolve.** A handled thread gets a 👍 **reaction** on the reviewer's
|
||||
comment while unpushed — never an "Addressed — …" reply, those are just noise. Once I've pushed
|
||||
and its fix is live, you **resolve the thread on GitHub** (or minimize the bot comment as
|
||||
RESOLVED) rather than leaving it open — see step 6. Never resolve unpushed work or a needs-input
|
||||
thread. The **only** comments you ever post are the one-line decision questions for needs-input
|
||||
items (step 7) and the one-line reason on a dismissal.
|
||||
- **The marker vocabulary — exactly these three, never others.** Every item you triage gets exactly
|
||||
one reaction, so I can read the PR's state at a glance without opening threads:
|
||||
- 👍 `+1` — **addressed**: fix staged; the thread gets resolved once I push.
|
||||
- 👀 `eyes` — **parked**: needs a decision from me, paired with the one-line question (step 7).
|
||||
- 👎 `-1` — **dismissed**: a *bot* finding that's wrong, paired with a one-line why, then
|
||||
resolved/minimized straight away (step 8).
|
||||
|
||||
**Never 👎 a human's comment.** If I'm the one who's wrong, write the reasoning as a reply and
|
||||
park it as 👀 — I decide, not you. And don't invent other reactions (🎉/❤️/🚀/😄/😕): an
|
||||
unexplained emoji is worse than no emoji.
|
||||
- The 10-minute cadence uses `ScheduleWakeup`, so the loop only advances **while this Claude
|
||||
session stays open**. **To stop it: press `Esc` while I'm idle between cycles** (that clears the
|
||||
queued wake-up); closing the session also stops it. A plain message does **not** cancel a pending
|
||||
wake-up — use `Esc`.
|
||||
- **Every token counts.** Each wake-up re-reads the whole conversation with a cold prompt cache
|
||||
(the 10-min cadence outlives the 5-min cache TTL), so cost compounds with every cycle and every
|
||||
extra line in context. Therefore: fetch **filtered** data only (use the `--jq` filters below —
|
||||
never let raw unfiltered JSON into the conversation), summarize deltas rather than restating
|
||||
unchanged state, and keep idle cycles to **one cheap API call and ≤2 lines of output**.
|
||||
|
||||
Current state (auth + the current branch's PR):
|
||||
|
||||
!`echo "=== gh auth ==="; gh auth status 2>&1 | head -3; echo; echo "=== PR (current branch) ==="; gh pr view --json number,url,state,headRefName,baseRefName,headRefOid 2>/dev/null || echo "(no open PR for current branch — or gh not authed)"; echo; echo "=== repo ==="; gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null`
|
||||
|
||||
## Each cycle (one invocation / wake-up)
|
||||
|
||||
1. **Preflight.** If `gh auth status` failed above → **stop** and tell me to run `! gh auth login`,
|
||||
then re-run `/pr-loop`. Do nothing else. Capture `owner`/`repo` from `nameWithOwner`.
|
||||
|
||||
2. **Load state & resolve the PR.** Read `<git-dir>/pr-loop-state.json` (find `<git-dir>` with
|
||||
`git rev-parse --absolute-git-dir`). It's inside `.git/`, so it never shows in `git status` and
|
||||
survives wake-ups. Shape:
|
||||
```json
|
||||
{ "number": 0, "lastHeadOid": "", "lastSeenUpdatedAt": "", "handledThreadIds": [],
|
||||
"handledCommentIds": [], "needsInputThreadIds": [], "needsInputCommentIds": [],
|
||||
"dismissedIds": [], "awaitingPush": false, "idleCount": 0, "cycleCount": 0 }
|
||||
```
|
||||
Resolve the target PR **in this order**: my argument if given (**$ARGUMENTS**) → the `number`
|
||||
in the state file (wake-ups re-invoke `/pr-loop` *without* arguments — the state file is the
|
||||
durable copy) → the current branch's PR from the context block. If none → **stop** and say so.
|
||||
If the state file is missing or for a different `number`, start fresh. Increment `cycleCount`.
|
||||
|
||||
**Then print one status line before any network call** — so I always see the loop is alive:
|
||||
> 🔄 pr-loop cycle <N> — PR #<num>: checking…
|
||||
|
||||
3. **Cheap activity check — one API call, before any heavy fetch.**
|
||||
`gh pr view NUM --json headRefOid,updatedAt`
|
||||
- If `updatedAt == lastSeenUpdatedAt` **and** `headRefOid == lastHeadOid` → nothing happened at
|
||||
all (no comment, review, or push). This is an **idle cycle**: `idleCount += 1`; if a safety
|
||||
cap (step 5) is now exceeded, STOP per step 5. Otherwise save state and jump straight to
|
||||
step 10's reschedule. Total output ≤2 lines — if `awaitingPush`, one line is a brief
|
||||
commit-&-push reminder (remind at most twice across idle cycles, then just the status line).
|
||||
- Otherwise: remember the fetched `headRefOid` for step 6 and continue. (Don't update
|
||||
`lastSeenUpdatedAt` yet — step 10 refreshes it *after* you've posted replies, so your own
|
||||
replies don't defeat the next cycle's cheap check.)
|
||||
|
||||
4. **Fetch review state — filtered at the source, both calls in parallel** (one message, two
|
||||
tool calls). Never fetch unfiltered `reviews,comments`.
|
||||
|
||||
Unresolved review threads (resolved/unresolved is GraphQL-only):
|
||||
```bash
|
||||
gh api graphql --paginate -F owner=OWNER -F repo=REPO -F number=NUM -f query='
|
||||
query($owner:String!,$repo:String!,$number:Int!,$cursor:String){
|
||||
repository(owner:$owner,name:$repo){ pullRequest(number:$number){
|
||||
reviewThreads(first:100,after:$cursor){ pageInfo{hasNextPage endCursor}
|
||||
nodes{ id isResolved isOutdated
|
||||
comments(first:100){ nodes{ id databaseId author{login} path line body } } } } } } }' \
|
||||
--jq '.data.repository.pullRequest.reviewThreads.nodes[]
|
||||
| select(.isResolved | not)
|
||||
| {id, isOutdated,
|
||||
comments: [.comments.nodes[] | {id, databaseId, author: .author.login, path, line, body}]}'
|
||||
```
|
||||
Mind the two id kinds: the thread's own `id` (`PRRT_…`) is what you resolve; a
|
||||
`comments[].id` (`PRRC_…`) is what you react to.
|
||||
|
||||
Automated-reviewer activity + `@claude` requests from the PR conversation — latest review per
|
||||
bot (for the limit check in step 5) and only the relevant comments, not the whole history:
|
||||
```bash
|
||||
gh pr view NUM --json reviews,comments --jq '{
|
||||
latestBotReviews: ([.reviews[] | select(.author.login | test("codex|claude"; "i"))]
|
||||
| group_by(.author.login) | map(max_by(.submittedAt))
|
||||
| map({author: .author.login, state, submittedAt, body})),
|
||||
relevantComments: ([.comments[] | select((.isMinimized | not)
|
||||
and ((.body | test("@claude")) or (.author.login | test("codex|claude"; "i"))))
|
||||
| {id, author: .author.login, body}] | .[-10:])
|
||||
}'
|
||||
```
|
||||
Act on feedback from **any** reviewer — especially the automated ones, **Codex and Claude**
|
||||
(`author.login` matching `codex`/`claude`, or a Bot account). Treat any comment — inline review
|
||||
**or** PR conversation — whose body **mentions `@claude`** as an explicit request to act on,
|
||||
same as a review comment.
|
||||
|
||||
Some bots post **findings as a plain PR-conversation comment** rather than inline review threads
|
||||
(e.g. Claude when its tooling can't post inline). Triage those findings like thread findings;
|
||||
since they have no thread, you "resolve" them by **minimizing** the comment once fixed (step 8).
|
||||
`relevantComments[].id` is the comment's GraphQL node id (`IC_…`) used for that, and the
|
||||
`isMinimized` filter above already drops ones you've resolved. A bot's pure **summary / status /
|
||||
usage-limit** comment carries no finding — triage/minimize only comments with concrete asks.
|
||||
|
||||
5. **Check stop conditions — before doing any work:**
|
||||
- **Nothing left to address** → no unresolved review threads, no un-minimized bot **findings**
|
||||
comments, and no open `@claude` requests. Anything in `dismissedIds` doesn't count as
|
||||
outstanding (if a resolve/minimize failed, the 👎 + reason still stands). The PR is clean:
|
||||
report done, save state, and **do not** schedule another wake-up. STOP.
|
||||
- **The automated reviewers are spent** → an automated reviewer's most recent review/comment
|
||||
body matches a limit signal (case-insensitive: `rate/usage/quota/credit … limit`,
|
||||
`limit reached`, `exceeded … quota`, `out of … credits`). Automated reviewers = authors whose
|
||||
`login` matches `codex` or `claude` (or a `[bot]` that leaves review comments; confirm with
|
||||
`gh api users/<login> --jq .type` → `Bot`). STOP and report which reviewer hit the limit
|
||||
**only** when no unresolved threads (incl. `@claude` requests) remain that you can still act
|
||||
on. If one reviewer is limited but other threads still need work, handle those first, then
|
||||
re-check.
|
||||
- **Safety caps** (these apply on idle cycles too) → if `cycleCount > 20`, or `idleCount > 4`,
|
||||
or `gh api rate_limit --jq .resources.core.remaining` is `< 100` → STOP and hand back to me
|
||||
with a summary.
|
||||
|
||||
**When any stop fires:** save state, do **not** call `ScheduleWakeup`, and end with a clear
|
||||
final line so I know the loop is over and won't run again — e.g.:
|
||||
> ✅ **Finished — no more active issues.** I won't re-check again.
|
||||
|
||||
Adapt it to the reason: `✅ Finished — <reviewer> hit its usage limit; nothing left to address,
|
||||
I won't re-check again.` or `⏹ Stopped — hit safety cap (<which>); re-run \`/pr-loop\` to resume.`
|
||||
|
||||
6. **Did I push since last cycle?** Compare the `headRefOid` from step 3 to `lastHeadOid` (no
|
||||
extra API call).
|
||||
- If **unchanged and `awaitingPush` is true** → I haven't pushed yet. Don't re-fix anything for
|
||||
threads already handled: `idleCount += 1`, then continue with step 7 **only for genuinely new
|
||||
threads/comments** (something new must exist, or step 3 would have short-circuited).
|
||||
- If **changed** → I pushed. Set `awaitingPush=false`, `idleCount=0`, update `lastHeadOid`. Then,
|
||||
**before handling anything new, resolve on GitHub every already-handled item whose fix is now
|
||||
live** — don't leave them lingering as open, 👍-only threads. For each id in `handledThreadIds`
|
||||
that is still unresolved and not re-flagged, run `resolveReviewThread`; for each id in
|
||||
`handledCommentIds` not re-flagged, `minimizeComment` as RESOLVED (mutations in step 8).
|
||||
Resolved threads drop out of the step-4 fetch, so each fix is resolved exactly once. Then
|
||||
continue to any genuinely new threads.
|
||||
|
||||
7. **Triage** each unresolved review thread, every bot **findings** comment on the PR conversation,
|
||||
and every `@claude` request **not already handled**:
|
||||
- **Auto-handle (no input needed):** typos, lint/format, naming, missing null/error checks,
|
||||
applying the reviewer's concrete suggested diff, docs/comments, and localized bugs with one
|
||||
correct fix — **including fixes that touch a shared type/contract or span multiple layers,
|
||||
when the repo's existing conventions determine the shape.** Blast radius (multi-file,
|
||||
contract-touching, "I'd have to pick among a few representations") is **not** a reason to
|
||||
defer: pick the minimal idiomatic shape that matches existing patterns, implement it, and let
|
||||
me veto. A reviewer finding that names the concrete fix is almost always auto-handleable.
|
||||
- **Leave for me (needs input) — 👀:** defer **only** for genuine ambiguity — two or more
|
||||
*materially different* correct behaviours, a real security/performance trade-off, or missing
|
||||
product/domain knowledge that existing code can't settle. Never guess these. Post the
|
||||
`path:line` + a **one-line decision I can answer in a word**, and record the id in
|
||||
`needsInputThreadIds` (or `needsInputCommentIds` for a plain conversation comment) so step 3
|
||||
re-surfaces it every idle cycle instead of letting it fall silent.
|
||||
- **Not an issue (dismiss) — 👎:** a **bot** finding that is simply wrong — it misread the code,
|
||||
the behaviour is intentional and the surrounding code proves it, or the concern is already
|
||||
handled elsewhere. Don't "fix" it to make it go away, and don't park it as needs-input either:
|
||||
that leaves a false positive propping the loop open until a safety cap fires. Reply with the
|
||||
one-line reason (facts, not opinion: the line/behaviour that disproves it), 👎 it, then resolve
|
||||
the thread / minimize the comment **immediately** — no push required, since there's no fix to
|
||||
land. Record the id in `dismissedIds` so a re-fetch can't re-litigate it.
|
||||
**Only bots get dismissed.** A *human* comment you think is wrong is a needs-input item: state
|
||||
your reasoning in a reply, mark it 👀, and let me settle it. If you'd be dismissing more than
|
||||
one or two findings in a cycle, you're probably the one who's wrong — park them for me instead.
|
||||
|
||||
Apply the same split to Codex's and Claude's review suggestions and to every `@claude` request:
|
||||
a concrete ask is auto-handled; a genuine judgement call is left for me. Skip anything whose id
|
||||
is already in `handledThreadIds` / `handledCommentIds` / `dismissedIds`. When I answer a needs-input item (or you
|
||||
push a fix for it), drop its id from the needs-input arrays and handle/resolve it normally.
|
||||
|
||||
8. **Prepare the auto-handled set (no commit, no push):**
|
||||
- Apply the edits (the PostToolUse format hook auto-formats). `git add` the changed files.
|
||||
- **Mark every triaged item with its reaction — never an "Addressed — …" reply.** The reaction
|
||||
goes on the reviewer's comment (for a thread, its *first* comment — the finding itself):
|
||||
👍 what you fixed this cycle, 👀 what you parked for me, 👎 a dismissed bot finding.
|
||||
|
||||
One mutation covers both surfaces. Pass the **comment** node id — `comments[].id` (`PRRC_…`)
|
||||
from the thread query, or `relevantComments[].id` (`IC_…`) for a conversation comment; *not*
|
||||
the thread's own `PRRT_…` id. `content` is `THUMBS_UP` / `EYES` / `THUMBS_DOWN`:
|
||||
```bash
|
||||
gh api graphql -f query='mutation($id:ID!,$c:ReactionContent!){
|
||||
addReaction(input:{subjectId:$id,content:$c}){ reaction{ content } } }' \
|
||||
-F id=COMMENT_NODE_ID -F c=THUMBS_UP
|
||||
```
|
||||
Re-adding the same reaction is a harmless no-op, so a repeat cycle can't double-post. When an
|
||||
item **changes class** — I answer a 👀, or a reviewer re-flags something you'd 👍'd — clear the
|
||||
stale marker first, same call shape, so nothing ever carries two contradictory markers:
|
||||
```bash
|
||||
gh api graphql -f query='mutation($id:ID!,$c:ReactionContent!){
|
||||
removeReaction(input:{subjectId:$id,content:$c}){ reaction{ content } } }' \
|
||||
-F id=COMMENT_NODE_ID -F c=EYES
|
||||
```
|
||||
- Add handled review-thread ids to `handledThreadIds` and handled conversation/`@claude`
|
||||
comment ids to `handledCommentIds`; set `awaitingPush=true`.
|
||||
- **Resolve** a thread — `gh api graphql -f query='mutation($id:ID!){
|
||||
resolveReviewThread(input:{threadId:$id}){ thread{ id isResolved } } }' -F id=THREAD_ID` —
|
||||
**only** once its fix is live (a cycle where `headRefOid` advanced, per step 6) and the
|
||||
reviewer hasn't re-flagged it. Never resolve unpushed work or a "needs input" thread. This
|
||||
resolves the review *conversation*, not any linked GitHub Issue.
|
||||
**The one exception is a 👎 dismissal:** there's no fix to land, so resolve/minimize it in the
|
||||
same cycle you post the reason — otherwise the false positive keeps the loop alive forever.
|
||||
- **Resolve a plain PR-conversation findings comment** (a bot finding with no inline thread —
|
||||
e.g. Claude's) by **minimizing it as resolved** — the issue-comment equivalent, under the same
|
||||
rules (only once its fix is live and not re-flagged):
|
||||
```bash
|
||||
gh api graphql -f query='mutation($id:ID!){ minimizeComment(input:{subjectId:$id,
|
||||
classifier:RESOLVED}){ minimizedComment{ isMinimized } } }' -F id=COMMENT_NODE_ID
|
||||
```
|
||||
`COMMENT_NODE_ID` is the `relevantComments[].id` (`IC_…`). Never minimize unpushed work, a
|
||||
"needs input" comment, or a summary/status/usage-limit comment.
|
||||
|
||||
9. **Draft the commit message — exactly like `/commit-msg`:** from the staged diff and the repo's
|
||||
recent `git log` style (this repo uses `[Scope] summary`), write a message that matches. Then:
|
||||
- **(a) Print it** in your reply as a fenced ` ```text ` block — the durable copy.
|
||||
- **(b) Write it** with the Write tool to the path from `git rev-parse --git-path CLAUDE_COMMIT_MSG`
|
||||
(**not** `COMMIT_EDITMSG` — git overwrites that on `git commit`; the `prepare-commit-msg` hook
|
||||
prefills the editor from `CLAUDE_COMMIT_MSG`).
|
||||
- **(c) Copy it:** `wl-copy < <that path>`.
|
||||
- Tell me all three locations. **Never** run `git commit`.
|
||||
(Skip this step when nothing new was staged this cycle.)
|
||||
|
||||
10. **Ping + schedule.** Give me a tight summary — deltas only, don't restate unchanged threads:
|
||||
- 👍 fixed & staged this cycle: threads (with `path:line`);
|
||||
- 👀 left for you: threads + one-line reason each;
|
||||
- 👎 dismissed as not-an-issue: thread + the one-line why (call these out explicitly — a
|
||||
dismissal is me trusting your judgement, so I should see every one);
|
||||
- resolved on GitHub this cycle (if any);
|
||||
- the commit message (printed above), then "commit & push when ready".
|
||||
|
||||
Refresh `lastSeenUpdatedAt` with one `gh pr view NUM --json updatedAt` call **after** any
|
||||
needs-input questions are posted (reactions don't bump `updatedAt`, comments do — so your own
|
||||
activity doesn't defeat the next cheap check), then save state
|
||||
to `<git-dir>/pr-loop-state.json`. Then schedule:
|
||||
- **normal cycle:** `ScheduleWakeup(delaySeconds=600, prompt="/pr-loop", reason="recheck PR
|
||||
#<num> review comments")`;
|
||||
- **idle cycle** (step 3 short-circuited): back off — `delaySeconds=1200`, I'm clearly away;
|
||||
re-running `/pr-loop` checks immediately.
|
||||
|
||||
End the turn with a sign-off that states when you'll run again and how to stop, e.g.:
|
||||
> ⏳ **Next check in ~10 min** (~20 when idle). To stop, press `Esc` while I'm idle between
|
||||
> cycles (or close the session).
|
||||
|
||||
(When a stop condition in step 5 fired, skip both the wake-up and this sign-off — use the
|
||||
**Finished** line from step 5 instead.)
|
||||
|
||||
## Guardrails
|
||||
|
||||
- **Never** `git commit`, `git push`, `gh pr merge`, `gh pr create`, `gh pr close`, or `gh pr edit`
|
||||
— I do all of those. You stage, react, resolve, and draft; nothing more. The only comment you may
|
||||
post is a needs-input decision question.
|
||||
- Act only on the target PR. Don't touch unrelated files or other PRs.
|
||||
- **Keep context lean:** no raw JSON dumps in replies, no re-listing threads that haven't changed,
|
||||
idle cycles ≤2 lines. Every line you emit is re-read (uncached) on every later cycle.
|
||||
- If anything is unclear or risky, leave it for me rather than guessing.
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
description: Review all changes on the current branch (diff vs its base) for bugs, security issues, optimizations, and readability/scannability, then apply the readability + safe improvements after you approve. Use right before opening a PR.
|
||||
argument-hint: [base-branch]
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash(git diff:*), Bash(git log:*), Bash(git status:*), Bash(git merge-base:*), Bash(git symbolic-ref:*), Bash(git rev-parse:*), Bash(git show-ref:*), Bash(git branch:*), Read, Grep, Glob
|
||||
---
|
||||
|
||||
# Review this branch
|
||||
|
||||
Context auto-collected for the current branch vs. its base:
|
||||
|
||||
!`b=$(git symbolic-ref --short -q refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@'); [ -z "$b" ] && { git show-ref -q --verify refs/heads/main && b=main || b=master; }; m=$(git merge-base "$b" HEAD 2>/dev/null); echo "Current branch: $(git rev-parse --abbrev-ref HEAD 2>/dev/null)"; echo "Base branch: $b"; echo "Diff range: ${m:-?}..HEAD"; echo; echo "Commits:"; git --no-pager log --oneline "${m}..HEAD" 2>/dev/null; echo; echo "Files changed:"; git --no-pager diff --stat "${m}...HEAD" 2>/dev/null`
|
||||
|
||||
## What to do
|
||||
|
||||
1. **Resolve the base branch.** If a base branch was passed when invoking (it appears here:
|
||||
**$ARGUMENTS** — empty if none), use that. Otherwise use the base detected above. The changes
|
||||
to review are the diff `git merge-base <base> HEAD`..`HEAD`.
|
||||
2. **Gather context.** Read the full diff for that range (`git diff <merge-base>...HEAD`) and
|
||||
review **only the lines this branch changed** — not pre-existing code. Read surrounding code
|
||||
with the Read tool when you need it to judge a finding. Also read the repo's `CLAUDE.md` (root,
|
||||
and any in the directories the branch touched) and treat its guidance as a review lens.
|
||||
3. **Find issues** across four lenses:
|
||||
- 🐞 **Correctness / bugs** — logic errors, unhandled edge cases, swallowed/ignored errors,
|
||||
race conditions, wrong/loose types, off-by-ones, and anything that violates the repo's
|
||||
`CLAUDE.md`.
|
||||
- 🔒 **Security** — injection (SQL / command / path traversal), missing input validation or
|
||||
output encoding, authn/authz gaps, secrets or credentials committed / logged / echoed,
|
||||
unsafe deserialization, SSRF, weak crypto or randomness, unsafe defaults, and sensitive data
|
||||
leaked in logs or error messages.
|
||||
- ⚡ **Optimizations** — redundant work, needless allocations/copies, N+1 patterns, a simpler
|
||||
or standard-library equivalent.
|
||||
- 📖 **Readability & scannability** — naming, structure, dead code, stale/misleading comments,
|
||||
formatting, over-long functions, unclear control flow.
|
||||
4. **Verify the bugs and security findings before reporting.** Double-check each 🐞 and 🔒
|
||||
finding against the real code and keep only the ones you're confident are real and exploitable
|
||||
/ will bite in practice. **Do not flag:**
|
||||
- issues on lines the branch didn't change (pre-existing);
|
||||
- theoretical vulnerabilities with no reachable exploit path in the changed code, or anything a
|
||||
SAST / dependency scanner would own;
|
||||
- anything a linter / type-checker / compiler / CI catches (imports, type errors, formatting) —
|
||||
assume those run separately;
|
||||
- pedantic nitpicks a senior engineer wouldn't raise, or "needs more tests/docs" unless the
|
||||
repo's `CLAUDE.md` requires it;
|
||||
- changes that are clearly intentional and part of the feature.
|
||||
|
||||
(This filter is for 🐞 bugs and 🔒 security. ⚡ optimizations and 📖 readability are the
|
||||
deliberate polish pass — minor suggestions there are welcome, since the goal is PR-readiness.)
|
||||
5. **Report**, grouped by the four lenses, most-severe-first, each finding one or two lines with
|
||||
a `path:line` reference so it's scannable. If a category is clean, say so in one line. No walls
|
||||
of text.
|
||||
6. **Then stop and ask** whether to apply the fixes. On approval, apply **only** the readability
|
||||
improvements and behavior-preserving optimizations. Anything that changes behavior, public API,
|
||||
or semantics: list it separately and let me decide — do **not** apply it silently. Treat 🔒
|
||||
security fixes the same way: propose them, but never apply them silently. After editing, re-run
|
||||
the repo's formatter/linter if it has one.
|
||||
7. **Point me at the relevant built-in follow-ups.** After reporting, list the Claude Code
|
||||
commands worth running next as separate, deeper passes — tailored to what this review
|
||||
surfaced, not a blanket dump. Only include the ones that actually fit:
|
||||
- `/security-review` — a deeper, whole-branch security pass; suggest whenever the 🔒 lens
|
||||
flagged something or the diff touches auth, crypto, input handling, secrets, or network I/O.
|
||||
- `/code-review` (add `--fix` to apply, `--comment` for inline PR comments) — a second review
|
||||
of the working-tree diff at a chosen effort level.
|
||||
- `/simplify` — apply reuse / simplification / efficiency cleanups beyond the safe ones applied
|
||||
here.
|
||||
- `/verify` — run the app to confirm the change behaves, if this branch changed behavior.
|
||||
- `/pr-description` — draft the PR text from this branch once the review is clean.
|
||||
- `/review` — review the PR on GitHub after it's open.
|
||||
8. **Never** run `git commit` or `git push` — I do that manually.
|
||||
@@ -0,0 +1,517 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Claude Code status line.
|
||||
|
||||
One line: vim mode | dir (repo-relative, hidden at the root) |
|
||||
git(repo/branch +dirty +ahead/behind) | model (+effort) |
|
||||
context% (+compact warn) | 5h usage (+reset eta) | cost (+burn rate) | disk. If the
|
||||
rendered line would overflow the terminal, trailing (lowest-priority) segments are
|
||||
dropped until it fits.
|
||||
(Dormant, re-addable in main(): ram, cpu%, temp -- retired 2026-07-26 because the
|
||||
status line only refreshes on message events, so system metrics sat visibly stale;
|
||||
tmux's status bar owns those now -- plus velocity, cache hit %, api ratio, version,
|
||||
style.)
|
||||
|
||||
Reads the status JSON from stdin (Claude Code statusLine command). Every segment
|
||||
is wrapped defensively so the status line can never crash the UI -- on any error
|
||||
a segment is simply omitted.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import unicodedata
|
||||
|
||||
# --- ANSI helpers -----------------------------------------------------------
|
||||
RESET = "\033[0m"
|
||||
DIM = "" # disabled: "\033[2m" blended the gray detail text into dark backgrounds
|
||||
BOLD = "\033[1m"
|
||||
C = {
|
||||
"cyan": "\033[36m",
|
||||
"green": "\033[32m",
|
||||
"yellow": "\033[33m",
|
||||
"red": "\033[31m",
|
||||
"magenta": "\033[35m",
|
||||
"blue": "\033[34m",
|
||||
"gray": "\033[37m", # light gray (was "\033[90m" bright-black, too dark to read)
|
||||
}
|
||||
|
||||
|
||||
def color(text, name="", dim=False, bold=False):
|
||||
pre = ""
|
||||
if dim:
|
||||
pre += DIM
|
||||
if bold:
|
||||
pre += BOLD
|
||||
pre += C.get(name, "")
|
||||
return f"{pre}{text}{RESET}" if pre else str(text)
|
||||
|
||||
|
||||
def bucket(value, lo, hi, invert=False):
|
||||
"""green/yellow/red by threshold. invert=True -> high is good."""
|
||||
if invert:
|
||||
return "green" if value >= hi else ("yellow" if value >= lo else "red")
|
||||
return "green" if value < lo else ("yellow" if value < hi else "red")
|
||||
|
||||
|
||||
DIV = color(" │ ", "gray", dim=True)
|
||||
|
||||
|
||||
def join_line(segs):
|
||||
return DIV.join(s for s in segs if s)
|
||||
|
||||
|
||||
_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m")
|
||||
|
||||
|
||||
def vlen(text):
|
||||
"""Visible width of a rendered string: ANSI stripped, emoji counted as 2."""
|
||||
text = _ANSI_RE.sub("", text)
|
||||
w = 0
|
||||
for ch in text:
|
||||
if ch in ("\u200d", "\ufe0f", "\ufe0e") or unicodedata.combining(ch):
|
||||
continue # ZWJ / variation selectors / combining marks: zero width
|
||||
o = ord(ch)
|
||||
if o >= 0x1F000 or 0x2600 <= o <= 0x27BF or unicodedata.east_asian_width(ch) in ("W", "F"):
|
||||
w += 2
|
||||
else:
|
||||
w += 1
|
||||
return w
|
||||
|
||||
|
||||
def term_cols():
|
||||
"""Terminal width. Claude Code exports COLUMNS; 0 if unknown -> stay one line."""
|
||||
try:
|
||||
return shutil.get_terminal_size(fallback=(0, 0)).columns
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
|
||||
# --- shared transcript usage ------------------------------------------------
|
||||
def last_usage(data):
|
||||
"""Most recent `message.usage` block from the transcript, or {}."""
|
||||
try:
|
||||
path = data.get("transcript_path")
|
||||
if not path or not os.path.exists(path):
|
||||
return {}
|
||||
usage = {}
|
||||
with open(path, "r", errors="ignore") as fh:
|
||||
for line in fh:
|
||||
line = line.strip()
|
||||
if not line or '"usage"' not in line:
|
||||
continue
|
||||
try:
|
||||
obj = json.loads(line)
|
||||
except Exception:
|
||||
continue
|
||||
msg = obj.get("message")
|
||||
if isinstance(msg, dict) and isinstance(msg.get("usage"), dict):
|
||||
usage = msg["usage"]
|
||||
return usage
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
|
||||
# --- row 1: work ------------------------------------------------------------
|
||||
def vim_segment(data):
|
||||
"""Vim editor mode as a compact [I]/[N]/[V] (only present with editorMode: vim).
|
||||
|
||||
Pair with `"hideVimModeIndicator": true` in the statusLine settings block so
|
||||
Claude's own built-in indicator doesn't duplicate this one.
|
||||
"""
|
||||
mode = (data.get("vim") or {}).get("mode")
|
||||
if not mode:
|
||||
return ""
|
||||
m = mode.upper()
|
||||
if m.startswith("INSERT"):
|
||||
return color("[I]", "green", bold=True)
|
||||
if m.startswith("VISUAL"):
|
||||
return color("[V]", "magenta", bold=True)
|
||||
if m.startswith("NORMAL"):
|
||||
return color("[N]", "blue", bold=True)
|
||||
return color(f"[{m[:1]}]", "gray")
|
||||
|
||||
|
||||
def abbrev(path):
|
||||
"""fish-style prompt_pwd: shrink every component but the last to one char,
|
||||
keeping a leading dot (`.config` -> `.c`)."""
|
||||
parts = path.split(os.sep)
|
||||
out = []
|
||||
for i, p in enumerate(parts):
|
||||
if i == len(parts) - 1 or p in ("", "~"):
|
||||
out.append(p)
|
||||
elif p.startswith("."):
|
||||
out.append(p[:2])
|
||||
else:
|
||||
out.append(p[:1])
|
||||
return os.sep.join(out)
|
||||
|
||||
|
||||
def dir_segment(cwd, top=None):
|
||||
"""Path *inside* the repo -- git_segment already names the repo itself, so
|
||||
repeating the full ~-path here was pure duplication. Empty at the repo root;
|
||||
a fish-shortened ~-path when we're not in a repo at all."""
|
||||
try:
|
||||
rel = os.path.relpath(cwd, top) if top else None
|
||||
if rel and not rel.startswith(os.pardir): # `..` -> cwd is outside `top` (symlinked in); use the ~-path
|
||||
if rel == os.curdir:
|
||||
return ""
|
||||
shown = rel if len(rel) <= 28 else abbrev(rel)
|
||||
else:
|
||||
home = os.path.expanduser("~")
|
||||
shown = cwd
|
||||
if cwd == home:
|
||||
shown = "~"
|
||||
elif cwd.startswith(home + os.sep):
|
||||
shown = "~" + cwd[len(home):]
|
||||
shown = abbrev(shown)
|
||||
return "📁 " + color(shown, "cyan")
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def _git(cwd, *args):
|
||||
return subprocess.run(
|
||||
["git", "-C", cwd, *args], capture_output=True, text=True, timeout=1
|
||||
)
|
||||
|
||||
|
||||
def git_top(cwd):
|
||||
"""Absolute path of the enclosing work tree, or None."""
|
||||
try:
|
||||
r = _git(cwd, "rev-parse", "--show-toplevel")
|
||||
return r.stdout.strip() or None if r.returncode == 0 else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def git_segment(cwd, top):
|
||||
try:
|
||||
if not top:
|
||||
return ""
|
||||
repo = os.path.basename(top) or "repo"
|
||||
branch = _git(cwd, "rev-parse", "--abbrev-ref", "HEAD").stdout.strip() or "?"
|
||||
dirty = bool(_git(cwd, "status", "--porcelain").stdout.strip())
|
||||
|
||||
# ahead/behind vs upstream (omitted when no upstream is configured)
|
||||
ab = ""
|
||||
rl = _git(cwd, "rev-list", "--left-right", "--count", "@{upstream}...HEAD")
|
||||
if rl.returncode == 0 and rl.stdout.strip():
|
||||
try:
|
||||
behind, ahead = (int(x) for x in rl.stdout.split())
|
||||
bits = []
|
||||
if ahead:
|
||||
bits.append(color(f"↑{ahead}", "cyan"))
|
||||
if behind:
|
||||
bits.append(color(f"↓{behind}", "yellow"))
|
||||
if bits:
|
||||
ab = " " + "".join(bits)
|
||||
except Exception:
|
||||
ab = ""
|
||||
|
||||
mark = color("*", "red") if dirty else ""
|
||||
label = color(repo, "magenta", bold=True)
|
||||
br = color(branch, "yellow" if dirty else "green")
|
||||
return f"🌿 {label} {br}{mark}{ab}"
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def model_segment(data):
|
||||
name = (data.get("model") or {}).get("display_name")
|
||||
if not name:
|
||||
return ""
|
||||
name = name.replace(" context)", ")") # "Opus 4.8 (1M context)" -> "Opus 4.8 (1M)"
|
||||
out = "🤖 " + color(name, "blue")
|
||||
level = (data.get("effort") or {}).get("level")
|
||||
if level:
|
||||
out += color(f" · {level}", "gray")
|
||||
return out
|
||||
|
||||
|
||||
def context_segment(data, usage):
|
||||
try:
|
||||
if not usage:
|
||||
return ""
|
||||
used = (
|
||||
usage.get("input_tokens", 0)
|
||||
+ usage.get("cache_creation_input_tokens", 0)
|
||||
+ usage.get("cache_read_input_tokens", 0)
|
||||
)
|
||||
model_id = (data.get("model") or {}).get("id", "")
|
||||
window = 1_000_000 if "1m" in model_id.lower() else 200_000
|
||||
pct = used / window * 100 if window else 0
|
||||
col = bucket(pct, 50, 80)
|
||||
out = "📝 " + color(f"{pct:.0f}%", col) + color(f" ({used / 1000:.0f}k)", "gray", dim=True)
|
||||
if pct >= 80:
|
||||
out += color(" ⚠compact", "red", bold=True)
|
||||
return out
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def usage_segment(data):
|
||||
"""5-hour rolling usage window: used % (+ time until it resets)."""
|
||||
try:
|
||||
five = (data.get("rate_limits") or {}).get("five_hour") or {}
|
||||
pct = five.get("used_percentage")
|
||||
if pct is None:
|
||||
return ""
|
||||
out = "📊 " + color(f"{pct:.0f}%", bucket(pct, 50, 80))
|
||||
resets = five.get("resets_at")
|
||||
if resets:
|
||||
secs = int(resets) - int(time.time())
|
||||
if secs > 0:
|
||||
h, m = divmod(secs // 60, 60)
|
||||
out += color(f" {h}h{m:02d}m" if h else f" {m}m", "gray")
|
||||
return out
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def cost_segment(data):
|
||||
try:
|
||||
cost = data.get("cost") or {}
|
||||
usd = cost.get("total_cost_usd")
|
||||
if usd is None:
|
||||
return ""
|
||||
out = "💰 " + color(f"${usd:.2f}", "yellow")
|
||||
dur_ms = cost.get("total_duration_ms") or 0
|
||||
if dur_ms > 30_000: # need a meaningful window before extrapolating
|
||||
per_hr = usd / (dur_ms / 3_600_000)
|
||||
out += color(f" ${per_hr:.2f}/h", "gray", dim=True)
|
||||
return out
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def velocity_segment(data):
|
||||
try:
|
||||
cost = data.get("cost") or {}
|
||||
added = cost.get("total_lines_added", 0)
|
||||
removed = cost.get("total_lines_removed", 0)
|
||||
if not (added or removed):
|
||||
return ""
|
||||
out = "✏️ " + color(f"+{added}", "green") + color("/", "gray", dim=True) + color(f"-{removed}", "red")
|
||||
dur_ms = cost.get("total_duration_ms") or 0
|
||||
if dur_ms > 30_000:
|
||||
per_min = added / (dur_ms / 60_000)
|
||||
out += color(f" {per_min:.0f}/m", "gray", dim=True)
|
||||
return out
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def cache_segment(usage):
|
||||
try:
|
||||
if not usage:
|
||||
return ""
|
||||
read = usage.get("cache_read_input_tokens", 0)
|
||||
total = (
|
||||
usage.get("input_tokens", 0)
|
||||
+ usage.get("cache_creation_input_tokens", 0)
|
||||
+ read
|
||||
)
|
||||
if total <= 0:
|
||||
return ""
|
||||
pct = read / total * 100
|
||||
return "♻️ " + color(f"{pct:.0f}%", bucket(pct, 50, 80, invert=True))
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def api_segment(data):
|
||||
"""Share of wall-clock time spent in API/inference (rough 'busy' ratio)."""
|
||||
try:
|
||||
cost = data.get("cost") or {}
|
||||
wall = cost.get("total_duration_ms") or 0
|
||||
api = cost.get("total_api_duration_ms") or 0
|
||||
if wall <= 0 or api <= 0:
|
||||
return ""
|
||||
pct = min(api / wall * 100, 100)
|
||||
return "⚙️ " + color(f"{pct:.0f}%", "blue")
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
# --- row 2: system ----------------------------------------------------------
|
||||
def ram_segment():
|
||||
try:
|
||||
info = {}
|
||||
with open("/proc/meminfo") as fh:
|
||||
for line in fh:
|
||||
k, _, v = line.partition(":")
|
||||
info[k.strip()] = int(v.split()[0]) # kB
|
||||
total = info.get("MemTotal", 0)
|
||||
avail = info.get("MemAvailable", info.get("MemFree", 0))
|
||||
if total <= 0:
|
||||
return ""
|
||||
used = total - avail
|
||||
pct = used / total * 100
|
||||
g = 1024 * 1024
|
||||
return (
|
||||
"🧠 " + color(f"{pct:.0f}%", bucket(pct, 70, 85))
|
||||
+ color(f" {used / g:.1f}/{total / g:.0f}G", "gray", dim=True)
|
||||
)
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def disk_segment(cwd):
|
||||
try:
|
||||
st = os.statvfs(cwd)
|
||||
total = st.f_blocks
|
||||
if total <= 0:
|
||||
return ""
|
||||
used = total - st.f_bfree
|
||||
pct = used / total * 100
|
||||
return "💾 " + color(f"{pct:.0f}%", bucket(pct, 75, 90))
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def _cpu_pct():
|
||||
"""Live CPU% diffed against a cached /proc/stat snapshot (no sleeping)."""
|
||||
try:
|
||||
with open("/proc/stat") as fh:
|
||||
parts = fh.readline().split()
|
||||
if not parts or parts[0] != "cpu":
|
||||
return None
|
||||
vals = [int(x) for x in parts[1:]]
|
||||
idle = vals[3] + (vals[4] if len(vals) > 4 else 0) # idle + iowait
|
||||
total = sum(vals)
|
||||
|
||||
state = os.path.expanduser("~/.claude/cache/statusline.cpu")
|
||||
prev = None
|
||||
try:
|
||||
with open(state) as fh:
|
||||
pt, pi = fh.read().split()
|
||||
prev = (int(pt), int(pi))
|
||||
except Exception:
|
||||
prev = None
|
||||
try:
|
||||
os.makedirs(os.path.dirname(state), exist_ok=True)
|
||||
with open(state, "w") as fh:
|
||||
fh.write(f"{total} {idle}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not prev:
|
||||
return None
|
||||
dt = total - prev[0]
|
||||
di = idle - prev[1]
|
||||
if dt <= 0 or di < 0:
|
||||
return None
|
||||
return max(0.0, min(100.0, (1 - di / dt) * 100))
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def cpu_segment():
|
||||
try:
|
||||
load1 = os.getloadavg()[0]
|
||||
cores = os.cpu_count() or 1
|
||||
pct = _cpu_pct()
|
||||
if pct is not None:
|
||||
head = color(f"{pct:.0f}%", bucket(pct, 60, 85))
|
||||
tail = color(f" {load1:.1f} {cores}c", "gray", dim=True)
|
||||
else:
|
||||
head = color(f"{load1:.2f}", bucket(load1 / cores, 0.7, 1.0))
|
||||
tail = color(f" {cores}c", "gray", dim=True)
|
||||
return "🖥️ " + head + tail
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def temp_segment():
|
||||
"""Hottest CPU-ish thermal zone in °C, falling back to the max zone."""
|
||||
try:
|
||||
base = "/sys/class/thermal"
|
||||
if not os.path.isdir(base):
|
||||
return ""
|
||||
prefer = ("x86_pkg_temp", "coretemp", "cpu", "k10temp", "tctl")
|
||||
chosen = None
|
||||
fallback = None
|
||||
for name in os.listdir(base):
|
||||
if not name.startswith("thermal_zone"):
|
||||
continue
|
||||
d = os.path.join(base, name)
|
||||
try:
|
||||
with open(os.path.join(d, "temp")) as fh:
|
||||
milli = int(fh.read().strip())
|
||||
except Exception:
|
||||
continue
|
||||
ztype = ""
|
||||
try:
|
||||
with open(os.path.join(d, "type")) as fh:
|
||||
ztype = fh.read().strip().lower()
|
||||
except Exception:
|
||||
pass
|
||||
if fallback is None or milli > fallback:
|
||||
fallback = milli
|
||||
if any(p in ztype for p in prefer) and (chosen is None or milli > chosen):
|
||||
chosen = milli
|
||||
milli = chosen if chosen is not None else fallback
|
||||
if milli is None:
|
||||
return ""
|
||||
c = milli / 1000.0
|
||||
return "🌡️ " + color(f"{c:.0f}°C", bucket(c, 60, 80))
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def version_segment(data):
|
||||
v = data.get("version")
|
||||
return color(f"v{v}", "gray", dim=True) if v else ""
|
||||
|
||||
|
||||
def style_segment(data):
|
||||
name = (data.get("output_style") or {}).get("name")
|
||||
return color(f"🎨{name}", "gray", dim=True) if name else ""
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
data = json.load(sys.stdin)
|
||||
except Exception:
|
||||
data = {}
|
||||
|
||||
cwd = (
|
||||
(data.get("workspace") or {}).get("current_dir")
|
||||
or data.get("cwd")
|
||||
or os.getcwd()
|
||||
)
|
||||
usage = last_usage(data)
|
||||
top = git_top(cwd)
|
||||
|
||||
# One row: work (left) then system (right), joined. If it would overflow the
|
||||
# terminal, trailing (lowest-priority) segments are dropped so it stays one line.
|
||||
# Dormant helpers kept above for easy re-add: ram_segment, cpu_segment,
|
||||
# temp_segment (retired -- they only refresh on message events, so they sat
|
||||
# stale; the tmux status bar owns system metrics now), velocity_segment,
|
||||
# cache_segment, api_segment, version_segment, style_segment.
|
||||
work = [s for s in (
|
||||
vim_segment(data),
|
||||
dir_segment(cwd, top),
|
||||
git_segment(cwd, top),
|
||||
model_segment(data),
|
||||
context_segment(data, usage),
|
||||
usage_segment(data),
|
||||
cost_segment(data),
|
||||
) if s]
|
||||
system = [s for s in (
|
||||
disk_segment(cwd),
|
||||
) if s]
|
||||
|
||||
segs = work + system
|
||||
cols = term_cols()
|
||||
if cols: # trim from the right until it fits one line (cols=0 -> width unknown, keep all)
|
||||
while len(segs) > 1 and vlen(join_line(segs)) > cols:
|
||||
segs.pop()
|
||||
sys.stdout.write(join_line(segs))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,108 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"source": "$(find \"${XDG_CONFIG_HOME:-$HOME/.config}/fastfetch/pngs/\" -name \"*.png\" | shuf -n 1)",
|
||||
"height": 18
|
||||
},
|
||||
"display": {
|
||||
"separator": " : "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "\u001b[36m "
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "┌──────────────────────────────────────────┐"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": " OS",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": " Kernel",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": " Packages",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "display",
|
||||
"key": " Display",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "wm",
|
||||
"key": " WM",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": " Terminal",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "└──────────────────────────────────────────┘"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type": "title",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "┌──────────────────────────────────────────┐"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"format": "{1}",
|
||||
"key": " CPU",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"format": "{2}",
|
||||
"key": " GPU",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"format": "{3}",
|
||||
"key": " GPU Driver",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": " Memory",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"key": " OS Age ",
|
||||
"keyColor": "31",
|
||||
"text": "birth_install=$(stat -c %W /); current=$(date +%s); time_progression=$((current - birth_install)); days_difference=$((time_progression / 86400)); echo $days_difference days"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": " Uptime ",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "└──────────────────────────────────────────┘"
|
||||
},
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 2,
|
||||
"symbol": "circle"
|
||||
},
|
||||
"break"
|
||||
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,5 @@
|
||||
# Single positional arg: a branch name. It runs `git checkout -b`, so the new
|
||||
# branch is typically a fresh name -- but offer existing branch names as a base
|
||||
# to type from. Only suggest inside a git repo.
|
||||
complete -c c2-worktree -x -n 'git rev-parse --is-inside-work-tree 2>/dev/null' \
|
||||
-a '(git for-each-ref --format="%(refname:short)" refs/heads refs/remotes 2>/dev/null | string replace -r "^origin/" "")'
|
||||
@@ -0,0 +1,3 @@
|
||||
# `h <cmd> ...` shows a command's --help via bat, so complete it like a
|
||||
# command line: first token = a command, rest = that command's own args.
|
||||
complete -c h -x -a '(__fish_complete_subcommand)'
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
function __fish_pipx_complete
|
||||
set -x _ARGCOMPLETE 1
|
||||
set -x _ARGCOMPLETE_DFS \t
|
||||
set -x _ARGCOMPLETE_IFS \n
|
||||
set -x _ARGCOMPLETE_SUPPRESS_SPACE 1
|
||||
set -x _ARGCOMPLETE_SHELL fish
|
||||
set -x COMP_LINE (commandline -p)
|
||||
set -x COMP_POINT (string length (commandline -cp))
|
||||
set -x COMP_TYPE
|
||||
if set -q _ARC_DEBUG
|
||||
pipx 8>&1 9>&2 1>&9 2>&1
|
||||
else
|
||||
pipx 8>&1 9>&2 1>/dev/null 2>&1
|
||||
end
|
||||
end
|
||||
complete --command pipx -f -a '(__fish_pipx_complete)'
|
||||
@@ -0,0 +1,7 @@
|
||||
if test -z "$SSH_ENV"
|
||||
set -xg SSH_ENV $HOME/.ssh/environment
|
||||
end
|
||||
|
||||
if not __ssh_agent_is_started
|
||||
__ssh_agent_start
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
set --global fish_key_bindings fish_vi_key_bindings
|
||||
|
||||
set --erase --universal fish_key_bindings
|
||||
@@ -0,0 +1,38 @@
|
||||
set --global fish_color_autosuggestion 4D5566
|
||||
set --global fish_color_cancel -r
|
||||
set --global fish_color_command 39BAE6
|
||||
set --global fish_color_comment 626A73
|
||||
set --global fish_color_cwd 59C2FF
|
||||
set --global fish_color_cwd_root red
|
||||
set --global fish_color_end F29668
|
||||
set --global fish_color_error FF3333
|
||||
set --global fish_color_escape 95E6CB
|
||||
set --global fish_color_history_current --bold
|
||||
set --global fish_color_host normal
|
||||
set --global fish_color_host_remote yellow
|
||||
set --global fish_color_keyword 39BAE6
|
||||
set --global fish_color_match F07178
|
||||
set --global fish_color_normal B3B1AD
|
||||
set --global fish_color_operator E6B450
|
||||
set --global fish_color_option B3B1AD
|
||||
set --global fish_color_param B3B1AD
|
||||
set --global fish_color_quote C2D94C
|
||||
set --global fish_color_redirection FFEE99
|
||||
set --global fish_color_search_match --background=E6B450
|
||||
set --global fish_color_selection --background=E6B450
|
||||
set --global fish_color_status red
|
||||
set --global fish_color_user brgreen
|
||||
set --global fish_color_valid_path --underline
|
||||
set --global fish_pager_color_background
|
||||
set --global fish_pager_color_completion normal
|
||||
set --global fish_pager_color_description B3A06D yellow
|
||||
set --global fish_pager_color_prefix normal --bold --underline
|
||||
set --global fish_pager_color_progress brwhite --background=cyan
|
||||
set --global fish_pager_color_secondary_background
|
||||
set --global fish_pager_color_secondary_completion
|
||||
set --global fish_pager_color_secondary_description
|
||||
set --global fish_pager_color_secondary_prefix
|
||||
set --global fish_pager_color_selected_background --background=E6B450
|
||||
set --global fish_pager_color_selected_completion
|
||||
set --global fish_pager_color_selected_description
|
||||
set --global fish_pager_color_selected_prefix
|
||||
@@ -0,0 +1,7 @@
|
||||
# fnm — single init for all hosts (config.fish must NOT source fnm again:
|
||||
# every `fnm env | source` mints a fresh multishell dir onto PATH).
|
||||
# fnm may be pacman-installed (on PATH) or self-installed under ~/.local/share/fnm.
|
||||
test -d "$HOME/.local/share/fnm"; and fish_add_path -g "$HOME/.local/share/fnm"
|
||||
if command -q fnm
|
||||
fnm env --use-on-cd --version-file-strategy local --shell fish | source
|
||||
end
|
||||
@@ -0,0 +1,115 @@
|
||||
## Shared fish config (all hosts). Host-specific bits live in host.fish (sourced at the end).
|
||||
## Secrets (e.g. DUSKADIY_API_KEY) go in conf.d/secrets.fish, which is gitignored.
|
||||
|
||||
set -gx EDITOR nvim
|
||||
set -gx PAGER less
|
||||
set -gx QT_FONT_DPI 96
|
||||
set -gx PI_SKIP_VERSION_CHECK 1
|
||||
set -gx OPENCODE_CONFIG "$HOME/.config/opencode/openai-gpt.jsonc"
|
||||
set -gx MANPAGER "nvim +Man!"
|
||||
# fzf's built-in walker is the one search tool that ignores .ignore files, so point it at
|
||||
# fd, which honours them. fd still hides dotfiles by default everywhere else — this only
|
||||
# changes what fzf sees inside trees that opt in (e.g. ~/.dots/.ignore).
|
||||
set -gx FZF_DEFAULT_COMMAND 'fd --type f --strip-cwd-prefix'
|
||||
set -gx NEWT_COLORS 'root=black,black;window=black,black;border=white,black;listbox=white,black;label=blue,black;checkbox=red,black;title=green,black;button=white,red;actsellistbox=white,red;actlistbox=white,gray;compactbutton=white,gray;actcheckbox=white,blue;entry=lightgray,black;textbox=blue,black' # themes nmtui
|
||||
# set -gx BAT_THEME "Catppuccin Mocha"
|
||||
|
||||
# Cursor / greeting
|
||||
set -g fish_greeting
|
||||
set -g fish_cursor_insert line
|
||||
set -g fish_cursor_default block
|
||||
set -g fish_cursor_visual underscore
|
||||
|
||||
# Misc
|
||||
alias exti=exit
|
||||
alias dmz="cat ~/.config/fish/dmz.txt"
|
||||
alias nmatrix="neo-matrix -DS 3"
|
||||
alias grep="grep --color=auto"
|
||||
alias fzf="fzf --preview 'bat --color=always {}'"
|
||||
alias fzff="fzf --multi --preview 'bat --style=numbers --color=always {}' | xargs -n 1 nvim"
|
||||
abbr scrcpyz 'scrcpy -wSK -m 1920 --window-borderless --always-on-top --power-off-on-close --no-audio'
|
||||
|
||||
# Git
|
||||
alias gti="git"
|
||||
alias gs="git status -s"
|
||||
alias gca="git add -p . && git commit"
|
||||
alias gd="git diff --word-diff"
|
||||
alias gl="git log --graph --show-signature"
|
||||
alias glog="git log --all --decorate --oneline --color --graph"
|
||||
alias gla="git log --all --decorate --oneline"
|
||||
alias gls="serie"
|
||||
alias gm="git merge"
|
||||
|
||||
# List directory
|
||||
alias ls='eza --icons --group-directories-first'
|
||||
alias l="ls -l"
|
||||
alias la="ls -a"
|
||||
alias lla="ls -la"
|
||||
alias lt="ls --tree"
|
||||
|
||||
# Dotfiles + notes
|
||||
alias cdots="cd ~/.dots/"
|
||||
alias cpnotes="cd ~/sync/PersonalNotes/"
|
||||
alias cnotes="cd ~/sync/CojaDuska/Notes/"
|
||||
abbr notes "cnotes && nvim"
|
||||
abbr wnotes "cd ~/sync/Wingman/notes && nvim"
|
||||
abbr wtodo "cd ~/sync/Wingman/notes/wm-client/ && nvim todo.md"
|
||||
abbr dots "cdots && nvim"
|
||||
abbr dotsync "cdots && ./bin/dotsync"
|
||||
abbr pnotes "cpnotes && nvim"
|
||||
abbr todo "cpnotes && nvim ToDoNext.md"
|
||||
abbr aliases "bat ~/.config/fish/config.fish"
|
||||
|
||||
# Handy
|
||||
abbr cat "bat -p"
|
||||
abbr untar "tar -xf"
|
||||
abbr unarchive "atool -x"
|
||||
abbr copy wl-copy
|
||||
abbr img "kitten icat"
|
||||
abbr fm yazi
|
||||
abbr lg lazygit
|
||||
abbr gcommit "git diff HEAD | aichat -r commit"
|
||||
abbr aichatdel "rm ~/.config/aichat/sessions/*.yaml"
|
||||
abbr mkdir "mkdir -p"
|
||||
abbr faillock "sudo faillock --reset"
|
||||
abbr xremaps "sudo xremap ~/.config/xremap/config.yml"
|
||||
abbr pacs "sudo pacman -Syu --noconfirm"
|
||||
abbr yays "yay --noconfirm --sudoloop"
|
||||
abbr nmaps "sudo nmap -sn 192.168.0.0/24"
|
||||
abbr scrcpyc 'scrcpy -wSK -m 1920 --window-borderless --always-on-top --power-off-on-close'
|
||||
abbr scrcpys 'scrcpy -wS --power-off-on-close'
|
||||
abbr tts "tt -notheme -bold -showwpm -json"
|
||||
abbr tuioss "tuios --show-clock --show-keys --show-cpu --show-ram --confirm-quit"
|
||||
abbr keybinds "cd ~/.dots/ && nvim gui/.config/hypr/keybindings.conf"
|
||||
abbr vpnhome "sudo wg-quick up wg0"
|
||||
abbr vpnkralizec "sudo wg-quick up kralizec-wg0"
|
||||
abbr vpnsumadija "sudo wg-quick up sumadija-wg0"
|
||||
abbr ipadd "sudo ip route add 192.168.0.234 dev wg0"
|
||||
abbr aria2cs "aria2c -x 16 -k 1M"
|
||||
|
||||
# Change-dir shortcuts
|
||||
abbr .. "cd .."
|
||||
abbr ... "cd ../.."
|
||||
abbr .3 "cd ../../.."
|
||||
abbr .4 "cd ../../../.."
|
||||
abbr .5 "cd ../../../../.."
|
||||
|
||||
# Tool init (fnm is initialized once in conf.d/fnm.fish — don't source it again here)
|
||||
zoxide init --cmd cd fish | source
|
||||
fish_add_path $HOME/.cargo/bin $HOME/.local/bin
|
||||
|
||||
# thefuck, lazy-loaded on first use (its --alias eval costs ~170ms of shell startup)
|
||||
function fuck
|
||||
functions -e fuck
|
||||
thefuck --alias | source
|
||||
fuck $argv
|
||||
end
|
||||
|
||||
# pnpm
|
||||
set -gx PNPM_HOME "$HOME/.local/share/pnpm"
|
||||
if not string match -q -- $PNPM_HOME $PATH
|
||||
set -gx PATH "$PNPM_HOME" $PATH
|
||||
end
|
||||
|
||||
# Per-host extras
|
||||
test -f ~/.config/fish/host.fish; and source ~/.config/fish/host.fish
|
||||
@@ -0,0 +1,30 @@
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;47;57;44m.[0m[38;2;108;178;82md[0m[38;2;122;228;83mO[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;124;232;84mO[0m[38;2;110;185;83md[0m[38;2;57;71;52m'[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;24;26;23m [0m[38;2;110;182;82md[0m[38;2;128;247;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;128;249;84m0[0m[38;2;112;190;83md[0m[38;2;32;37;31m.[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;113;202;80md[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;121;224;83mk[0m[38;2;5;5;4m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;83;83;83m [0m[38;2;109;211;71mx[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;122;238;79mO[0m[38;2;92;92;92m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;140;140;140m [0m[38;2;115;224;75mk[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;2;3;1m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;114;114;114m [0m[38;2;165;165;165m [0m[38;2;57;110;37m;[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;71;138;46m:[0m[38;2;180;180;180m [0m[38;2;124;242;81mO[0m[38;2;117;212;83mk[0m[38;2;94;131;81mc[0m[38;2;3;3;3m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;86;86;86m [0m[38;2;103;103;103m [0m[38;2;112;112;112m [0m[38;2;112;112;112m [0m[38;2;104;104;104m [0m[38;2;87;87;87m [0m[38;2;80;80;80m [0m[38;2;110;110;110m [0m[38;2;163;163;163m [0m[38;2;112;218;73mk[0m[38;2;118;215;83mk[0m[38;2;96;136;81mc[0m[38;2;10;10;10m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;105;105;105m [0m[38;2;161;161;161m [0m[38;2;110;215;72mk[0m[38;2;120;221;83mk[0m[38;2;97;140;81mc[0m[38;2;11;11;10m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;103;103;103m [0m[38;2;156;156;156m [0m[38;2;100;194;65md[0m[38;2;121;225;83mk[0m[38;2;99;147;81ml[0m[38;2;17;18;17m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;101;101;101m [0m[38;2;153;153;153m [0m[38;2;88;170;58mo[0m[38;2;122;227;83mk[0m[38;2;100;151;82ml[0m[38;2;25;26;24m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;97;97;97m [0m[38;2;151;151;151m [0m[38;2;84;162;55ml[0m[38;2;124;233;83mO[0m[38;2;101;155;82ml[0m[38;2;27;29;26m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;94;94;94m [0m[38;2;146;146;146m [0m[38;2;76;146;50mc[0m[38;2;125;236;84mO[0m[38;2;103;162;82mo[0m[38;2;32;35;31m.[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;33;36;31m.[0m[38;2;101;151;82ml[0m[38;2;114;198;82mx[0m[38;2;121;224;83mk[0m[38;2;125;238;84mO[0m[38;2;125;238;84mO[0m[38;2;121;225;83mk[0m[38;2;114;200;83mx[0m[38;2;101;152;81ml[0m[38;2;34;38;33m.[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;30;33;29m.[0m[38;2;101;152;81ml[0m[38;2;114;198;82mx[0m[38;2;121;224;83mk[0m[38;2;125;238;84mO[0m[38;2;125;239;84mO[0m[38;2;123;228;83mk[0m[38;2;115;201;83mx[0m[38;2;103;158;82ml[0m[38;2;39;44;37m.[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;93;93;93m [0m[38;2;143;143;143m [0m[38;2;64;122;42m;[0m[38;2;125;238;84mO[0m[38;2;107;175;82mo[0m[38;2;114;196;82mx[0m[38;2;122;224;83mk[0m[38;2;125;236;84mO[0m[38;2;125;239;84mO[0m[38;2;122;227;83mk[0m[38;2;115;201;82mx[0m[38;2;102;156;82ml[0m[38;2;42;47;40m.[0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;61;83;53m'[0m[38;2;125;239;84mO[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;126;239;84mO[0m[38;2;65;90;55m,[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;60;80;53m'[0m[38;2;124;235;84mO[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;126;240;83mO[0m[38;2;72;101;60m,[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;57;80;48m'[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;126;243;84mO[0m[38;2;72;103;60m,[0m
|
||||
[0m[38;2;123;234;82mO[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;126;240;84mO[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;125;239;84mO[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;127;246;84m0[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;108;177;82md[0m[38;2;124;233;84mO[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;127;245;84m0[0m
|
||||
[0m[38;2;77;146;51mc[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;80;152;53mc[0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;73;139;49m:[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;87;167;57ml[0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;141;141;141m [0m[38;2;66;124;45m:[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;89;171;59ml[0m
|
||||
[0m[38;2;109;109;109m [0m[38;2;37;70;25m.[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;40;75;27m.[0m[38;2;111;111;111m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;107;107;107m [0m[38;2;36;67;24m.[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;43;82;29m'[0m[38;2;113;113;113m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;60;85;50m'[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;50;96;34m'[0m[38;2;116;116;116m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;85;85;85m [0m[38;2;123;123;123m [0m[38;2;154;154;154m [0m[38;2;172;172;172m [0m[38;2;181;181;181m [0m[38;2;181;181;181m [0m[38;2;174;174;174m [0m[38;2;156;156;156m [0m[38;2;124;124;124m [0m[38;2;85;85;85m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;85;85;85m [0m[38;2;124;124;124m [0m[38;2;155;155;155m [0m[38;2;5;9;4m [0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;16;29;11m [0m[38;2;156;156;156m [0m[38;2;126;126;126m [0m[38;2;87;87;87m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;63;79;57m'[0m[38;2;111;189;83md[0m[38;2;128;248;84m0[0m[38;2;30;56;20m.[0m[38;2;139;139;139m [0m[38;2;154;154;154m [0m[38;2;172;172;172m [0m[38;2;180;180;180m [0m[38;2;182;182;182m [0m[38;2;174;174;174m [0m[38;2;156;156;156m [0m[38;2;126;126;126m [0m[38;2;88;88;88m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;3;4;3m [0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;12;15;11m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;70;89;63m,[0m[38;2;112;192;83md[0m[38;2;129;250;84m0[0m[38;2;20;38;14m.[0m[38;2;131;131;131m [0m[38;2;85;85;85m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;3;4;3m [0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;12;15;11m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;73;94;65m,[0m[38;2;115;200;83mx[0m[38;2;129;251;84m0[0m[38;2;18;34;13m [0m[38;2;126;126;126m [0m[38;2;83;83;83m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;3;4;3m [0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;12;15;11m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;83;112;72m:[0m[38;2;116;203;83mx[0m[38;2;129;251;84m0[0m[38;2;7;13;5m [0m[38;2;123;123;123m [0m[38;2;83;83;83m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;3;4;3m [0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;12;15;11m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;92;126;79mc[0m[38;2;117;207;83mx[0m[38;2;125;244;81mO[0m[38;2;174;174;174m [0m[38;2;121;121;121m [0m[38;2;81;81;81m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;3;4;3m [0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;12;15;11m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;81;81;81m [0m[38;2;93;130;79mc[0m[38;2;119;215;83mk[0m[38;2;124;243;81mO[0m[38;2;171;171;171m [0m[38;2;116;116;116m [0m[38;2;81;81;81m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;54;60;51m.[0m[38;2;95;132;81mc[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;99;144;81ml[0m[38;2;59;67;56m'[0m[38;2;6;6;6m [0m[38;2;97;140;81mc[0m[38;2;120;218;83mk[0m[38;2;113;221;74mk[0m[38;2;166;166;166m [0m[38;2;113;113;113m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;92;131;78mc[0m[38;2;119;213;83mk[0m[38;2;129;251;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;250;84m0[0m[38;2;124;236;84mO[0m[38;2;129;252;84m0[0m[38;2;6;10;4m [0m[38;2;111;111;111m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;93;151;71mc[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;108;183;78mo[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;82;82;82m [0m[38;2;121;236;79mO[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;3;4;3m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;27;47;19m.[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;40;72;28m.[0m[38;2;81;81;81m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;85;85;85m [0m[38;2;143;143;143m [0m[38;2;53;101;35m,[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;129;252;84m0[0m[38;2;65;126;43m:[0m[38;2;149;149;149m [0m[38;2;88;88;88m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
[0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;92;92;92m [0m[38;2;142;142;142m [0m[38;2;179;179;179m [0m[38;2;66;129;43m:[0m[38;2;73;142;47mc[0m[38;2;179;179;179m [0m[38;2;147;147;147m [0m[38;2;96;96;96m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m[38;2;80;80;80m [0m
|
||||
@@ -0,0 +1 @@
|
||||
danhper/fish-ssh-agent
|
||||
@@ -0,0 +1,23 @@
|
||||
function __ssh_agent_is_started -d "check if ssh agent is already started"
|
||||
if test -n "$SSH_CONNECTION"
|
||||
# This is an SSH session
|
||||
ssh-add -l > /dev/null 2>&1
|
||||
if test $status -eq 0 -o $status -eq 1
|
||||
# An SSH agent was forwarded
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
if begin; test -f "$SSH_ENV"; and test -z "$SSH_AGENT_PID"; end
|
||||
source $SSH_ENV > /dev/null
|
||||
end
|
||||
|
||||
if test -z "$SSH_AGENT_PID"
|
||||
return 1
|
||||
end
|
||||
|
||||
ssh-add -l > /dev/null 2>&1
|
||||
if test $status -eq 2
|
||||
return 1
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
function __ssh_agent_start -d "start a new ssh agent"
|
||||
ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV
|
||||
chmod 600 $SSH_ENV
|
||||
source $SSH_ENV > /dev/null
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
function ask --description 'answer from cht.sh'
|
||||
curl -s https://cht.sh/$(string join '+' $argv[1..])
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
function bashs --description 'raw bash command'
|
||||
bash -c "$argv"
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
function c2-worktree
|
||||
if test (count $argv) -ne 1
|
||||
echo "Usage: c2-worktree <branch-name>"
|
||||
echo "Example: c2-worktree package/package-update"
|
||||
return 1
|
||||
end
|
||||
|
||||
set branch $argv[1]
|
||||
|
||||
set root (git rev-parse --show-toplevel)
|
||||
or return 1
|
||||
set dir $root/.worktrees/(basename $branch)
|
||||
|
||||
mkdir -p $root/.worktrees
|
||||
or return 1
|
||||
|
||||
git checkout -b $branch
|
||||
or return 1
|
||||
|
||||
git checkout master
|
||||
or return 1
|
||||
|
||||
git worktree add $dir $branch
|
||||
or return 1
|
||||
|
||||
cd $dir
|
||||
or return 1
|
||||
|
||||
pnpm i
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
function clis --description 'fzf select cli'
|
||||
eval (cat $HOME/.config/misc/clis.txt | command fzf --multi)
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
function copy-commandline
|
||||
set -l cmd (commandline)
|
||||
if test -n "$cmd"
|
||||
if type -q pbcopy
|
||||
echo -n "$cmd" | pbcopy
|
||||
else if type -q xclip
|
||||
echo -n "$cmd" | xclip -selection clipboard
|
||||
else if type -q wl-copy
|
||||
echo -n "$cmd" | wl-copy
|
||||
end
|
||||
|
||||
# Provide brief visual feedback in the prompt
|
||||
set -l original_cmd (commandline)
|
||||
commandline -r "Copied!"
|
||||
sleep 0.4
|
||||
commandline -r "$original_cmd"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
function extract --description 'Extract any archive'
|
||||
switch $argv[1]
|
||||
case '*.tar' '*.tar.*' '*.tgz' '*.tbz2' '*.txz' # tar autodetects compression
|
||||
tar xf $argv[1]
|
||||
case '*.zip'
|
||||
unzip $argv[1]
|
||||
case '*.rar'
|
||||
unrar x $argv[1]
|
||||
case '*.7z'
|
||||
7z x $argv[1]
|
||||
case '*.gz'
|
||||
gunzip -k $argv[1]
|
||||
case '*.xz'
|
||||
unxz -k $argv[1]
|
||||
case '*.zst'
|
||||
unzstd $argv[1]
|
||||
case '*.bz2'
|
||||
bunzip2 -k $argv[1]
|
||||
case '*'
|
||||
echo "Unknown extension: $argv[1]"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
function fish_greeting
|
||||
#curl "wttr.in/Belgrade?format=%l:+%c+%t+|+%h+|+%w+|+(%%M+%m)\n"
|
||||
test -r ~/.config/fish/greet.txt; and cat ~/.config/fish/greet.txt ## populated by cronjob
|
||||
date +"📅 %d. %b 🕗 %H:%M - %A"
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
function fish_prompt
|
||||
if test -n "$SSH_TTY"
|
||||
echo -n (set_color brred)"$USER"(set_color white)'@'(set_color yellow)(prompt_hostname)' '
|
||||
end
|
||||
|
||||
echo -n (set_color blue)(prompt_pwd)' '
|
||||
|
||||
set_color -o
|
||||
if fish_is_root_user
|
||||
echo -n (set_color red)'# '
|
||||
end
|
||||
echo -n (set_color red)'❯'(set_color yellow)'❯'(set_color green)'❯ '
|
||||
set_color normal
|
||||
end
|
||||
@@ -0,0 +1,161 @@
|
||||
function fish_right_prompt
|
||||
set -l cmd_status $status
|
||||
if test $cmd_status -ne 0
|
||||
echo -n (set_color red)" $cmd_status"
|
||||
end
|
||||
|
||||
if not command -sq git
|
||||
set_color normal
|
||||
return
|
||||
end
|
||||
|
||||
# Get the git directory for later use.
|
||||
# Return if not inside a Git repository work tree.
|
||||
if not set -l git_dir (command git rev-parse --git-dir 2>/dev/null)
|
||||
set_color normal
|
||||
return
|
||||
end
|
||||
|
||||
# Get the current action ("merge", "rebase", etc.)
|
||||
# and if there's one get the current commit hash too.
|
||||
set -l commit ''
|
||||
if set -l action (fish_print_git_action "$git_dir")
|
||||
set commit (command git rev-parse HEAD 2> /dev/null | string sub -l 7)
|
||||
end
|
||||
|
||||
# Get either the branch name or a branch descriptor.
|
||||
set -l branch_detached 0
|
||||
if not set -l branch (command git symbolic-ref --short HEAD 2>/dev/null)
|
||||
set branch_detached 1
|
||||
set branch (command git describe --contains --all HEAD 2>/dev/null)
|
||||
end
|
||||
|
||||
# Get the commit difference counts between local and remote.
|
||||
command git rev-list --count --left-right 'HEAD...@{upstream}' 2>/dev/null \
|
||||
| read -d \t -l status_ahead status_behind
|
||||
if test $status -ne 0
|
||||
set status_ahead 0
|
||||
set status_behind 0
|
||||
end
|
||||
|
||||
# Get the stash status.
|
||||
# (git stash list) is very slow. => Avoid using it.
|
||||
set -l status_stashed 0
|
||||
if test -f "$git_dir/refs/stash"
|
||||
set status_stashed 1
|
||||
else if test -r "$git_dir/commondir"
|
||||
read -l commondir <"$git_dir/commondir"
|
||||
if test -f "$commondir/refs/stash"
|
||||
set status_stashed 1
|
||||
end
|
||||
end
|
||||
|
||||
# git-status' porcelain v1 format starts with 2 letters on each line:
|
||||
# The first letter (X) denotes the index state.
|
||||
# The second letter (Y) denotes the working directory state.
|
||||
#
|
||||
# The following table presents the possible combinations:
|
||||
# * The underscore character denotes whitespace.
|
||||
# * The cell values stand for the following file states:
|
||||
# a: added
|
||||
# d: deleted
|
||||
# m: modified
|
||||
# r: renamed
|
||||
# u: unmerged
|
||||
# t: untracked
|
||||
# * Cells with more than one letter signify that both states
|
||||
# are simultaneously the case. This is possible since the git index
|
||||
# and working directory operate independently of each other.
|
||||
# * Cells which are empty are unhandled by this code.
|
||||
# * T (= type change) is undocumented.
|
||||
# See Git v1.7.8.2 release notes for more information.
|
||||
#
|
||||
# \ Y→
|
||||
# X \
|
||||
# ↓ | A | C | D | M | R | T | U | X | B | ? | _
|
||||
# ----+----+----+----+----+----+----+----+----+----+----+----
|
||||
# A | u | | ad | am | r | am | u | | | | a
|
||||
# C | | | ad | am | r | am | u | | | | a
|
||||
# D | | | u | am | r | am | u | | | | a
|
||||
# M | | | ad | am | r | am | u | | | | a
|
||||
# R | r | r | rd | rm | r | rm | ur | r | r | r | r
|
||||
# T | | | ad | am | r | am | u | | | | a
|
||||
# U | u | u | u | um | ur | um | u | u | u | u | u
|
||||
# X | | | | m | r | m | u | | | |
|
||||
# B | | | | m | r | m | u | | | |
|
||||
# ? | | | | m | r | m | u | | | t |
|
||||
# _ | | | d | m | r | m | u | | | |
|
||||
set -l porcelain_status (command git status --porcelain 2>/dev/null | string sub -l2)
|
||||
|
||||
set -l status_added 0
|
||||
if string match -qr '[ACDMT][ MT]|[ACMT]D' $porcelain_status
|
||||
set status_added 1
|
||||
end
|
||||
set -l status_deleted 0
|
||||
if string match -qr '[ ACMRT]D' $porcelain_status
|
||||
set status_deleted 1
|
||||
end
|
||||
set -l status_modified 0
|
||||
if string match -qr '[MT]$' $porcelain_status
|
||||
set status_modified 1
|
||||
end
|
||||
set -l status_renamed 0
|
||||
if string match -qe R $porcelain_status
|
||||
set status_renamed 1
|
||||
end
|
||||
set -l status_unmerged 0
|
||||
if string match -qr 'AA|DD|U' $porcelain_status
|
||||
set status_unmerged 1
|
||||
end
|
||||
set -l status_untracked 0
|
||||
if string match -qe '\?\?' $porcelain_status
|
||||
set status_untracked 1
|
||||
end
|
||||
|
||||
set_color -o
|
||||
|
||||
if test -n "$branch"
|
||||
if test $branch_detached -ne 0
|
||||
set_color brmagenta
|
||||
else
|
||||
set_color green
|
||||
end
|
||||
echo -n " $branch"
|
||||
end
|
||||
if test -n "$commit"
|
||||
echo -n ' '(set_color yellow)"$commit"
|
||||
end
|
||||
if test -n "$action"
|
||||
set_color normal
|
||||
echo -n (set_color white)':'(set_color -o brred)"$action"
|
||||
end
|
||||
if test $status_ahead -ne 0
|
||||
echo -n ' '(set_color brmagenta)''
|
||||
end
|
||||
if test $status_behind -ne 0
|
||||
echo -n ' '(set_color brmagenta)''
|
||||
end
|
||||
if test $status_stashed -ne 0
|
||||
echo -n ' '(set_color cyan)''
|
||||
end
|
||||
if test $status_added -ne 0
|
||||
echo -n ' '(set_color green)''
|
||||
end
|
||||
if test $status_deleted -ne 0
|
||||
echo -n ' '(set_color red)''
|
||||
end
|
||||
if test $status_modified -ne 0
|
||||
echo -n ' '(set_color blue)''
|
||||
end
|
||||
if test $status_renamed -ne 0
|
||||
echo -n ' '(set_color magenta)''
|
||||
end
|
||||
if test $status_unmerged -ne 0
|
||||
echo -n ' '(set_color yellow)'═'
|
||||
end
|
||||
if test $status_untracked -ne 0
|
||||
echo -n ' '(set_color white)'◼'
|
||||
end
|
||||
|
||||
set_color normal
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
function fish_user_key_bindings
|
||||
# free Ctrl+S from terminal flow control (XOFF) so it can be bound below
|
||||
stty -ixon
|
||||
fish_default_key_bindings -M insert
|
||||
fish_vi_key_bindings --no-erase insert
|
||||
bind -M default ctrl-a beginning-of-line
|
||||
bind -M default ctrl-e end-of-line
|
||||
bind -M insert ctrl-space accept-autosuggestion
|
||||
bind -M insert ctrl-g 'git diff' repaint
|
||||
bind -M insert ctrl-o execute yazi
|
||||
bind -M insert ctrl-l clear-screen ls repaint
|
||||
bind -M default ctrl-s copy-commandline
|
||||
bind -M insert ctrl-s copy-commandline
|
||||
bind -M search ctrl-s copy-commandline
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
function fzfh --description 'Search history with fzf'
|
||||
history | fzf --query="$argv" --tac | read cmd
|
||||
if test -n "$cmd"
|
||||
echo $cmd
|
||||
commandline -r $cmd
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
function gcap --description 'Git add, commit with message, and push'
|
||||
git add .
|
||||
and git commit -m "$argv"
|
||||
and git push
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
function h --description "Colorized --help via bat"
|
||||
$argv --help 2>&1 | bat --plain --language=help
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
function lk --description 'linux knowledge'
|
||||
set -l DB "$HOME/projects/dmz/soft/lk/db.rec"
|
||||
set -l passes 0
|
||||
set -l count 0
|
||||
set -l query ""
|
||||
|
||||
while test $passes -lt 2; and test $count -eq 0
|
||||
set query (recsel "$DB" -p aim,tag | recsel -iq "$query" -CP aim,tag | sort -u | fzf --preview="recsel \"$DB\" -e \"aim~{}\" | bat")
|
||||
if test -n "$query"
|
||||
set count (recsel "$DB" -q "$query" -c)
|
||||
end
|
||||
set passes (math $passes + 1)
|
||||
end
|
||||
|
||||
if test $count -eq 1
|
||||
recsel "$DB" -q "$query" | recfmt -f "$HOME/projects/dmz/soft/lk/lists.fmt" | less
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
function opencodes --description 'contained opencode'
|
||||
bwrap \
|
||||
--unshare-all \
|
||||
--new-session \
|
||||
--clearenv \
|
||||
--die-with-parent \
|
||||
--share-net \
|
||||
--dev /dev \
|
||||
--proc /proc \
|
||||
--ro-bind /usr /usr \
|
||||
--ro-bind /lib /lib \
|
||||
--ro-bind /lib64 /lib64 \
|
||||
--ro-bind /bin /bin \
|
||||
--ro-bind /etc /etc \
|
||||
--ro-bind ~/.config/opencode ~/.config/opencode \
|
||||
--tmpfs /tmp/node-compile-cache \
|
||||
--bind ~/.local/state/opencode ~/.local/state/opencode \
|
||||
--bind ~/.local/share/opencode ~/.local/share/opencode \
|
||||
--bind "$(pwd)" "$(pwd)" \
|
||||
opencode
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
function ssh
|
||||
if type -q kitten
|
||||
kitten ssh $argv
|
||||
else
|
||||
command ssh $argv
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
function sshf --description 'fzf-pick an ssh host from ~/.ssh/config'
|
||||
# command fzf: bypass the fzf alias (its bat preview makes no sense for host names);
|
||||
# skip `Host *` wildcard blocks and take every alias on multi-name Host lines
|
||||
set -l host (awk '/^Host /{for (i = 2; i <= NF; i++) if ($i != "*") print $i}' ~/.ssh/config | command fzf)
|
||||
test -n "$host"; and ssh $host
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
function tuis --description 'fzf select tui'
|
||||
eval (cat $HOME/.config/misc/tuis.txt | command fzf --multi)
|
||||
end
|
||||
@@ -0,0 +1,483 @@
|
||||
# Config relating to the Lazygit UI
|
||||
gui:
|
||||
# The number of lines you scroll by when scrolling the main window
|
||||
scrollHeight: 2
|
||||
# If true, allow scrolling past the bottom of the content in the main window
|
||||
scrollPastBottom: true
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#scroll-off-margin
|
||||
scrollOffMargin: 2
|
||||
# One of: 'margin' (default) | 'jump'
|
||||
scrollOffBehavior: margin
|
||||
# If true, capture mouse events.
|
||||
# When mouse events are captured, it's a little harder to select text: e.g. requiring you to hold the option key when on macOS.
|
||||
mouseEvents: true
|
||||
# If true, do not show a warning when discarding changes in the staging view.
|
||||
skipDiscardChangeWarning: false
|
||||
# If true, do not show warning when applying/popping the stash
|
||||
skipStashWarning: false
|
||||
# If true, do not show a warning when attempting to commit without any staged files; instead stage all unstaged files.
|
||||
skipNoStagedFilesWarning: false
|
||||
# If true, do not show a warning when rewording a commit via an external editor
|
||||
skipRewordInEditorWarning: false
|
||||
# Fraction of the total screen width to use for the left side section. You may want to pick a small number (e.g. 0.2) if you're using a narrow screen, so that you can see more of the main section.
|
||||
# Number from 0 to 1.0.
|
||||
sidePanelWidth: 0.3333
|
||||
# If true, increase the height of the focused side window; creating an accordion effect.
|
||||
expandFocusedSidePanel: true
|
||||
# The weight of the expanded side panel, relative to the other panels. 2 means
|
||||
# twice as tall as the other panels. Only relevant if `expandFocusedSidePanel` is true.
|
||||
expandedSidePanelWeight: 3
|
||||
# Sometimes the main window is split in two (e.g. when the selected file has both staged and unstaged changes). This setting controls how the two sections are split.
|
||||
# Options are:
|
||||
# - 'horizontal': split the window horizontally
|
||||
# - 'vertical': split the window vertically
|
||||
# - 'flexible': (default) split the window horizontally if the window is wide enough, otherwise split vertically
|
||||
mainPanelSplitMode: flexible
|
||||
# How the window is split when in half screen mode (i.e. after hitting '+' once).
|
||||
# Possible values:
|
||||
# - 'left': split the window horizontally (side panel on the left, main view on the right)
|
||||
# - 'top': split the window vertically (side panel on top, main view below)
|
||||
enlargedSideViewLocation: left
|
||||
# If true, wrap lines in the staging view to the width of the view. This
|
||||
# makes it much easier to work with diffs that have long lines, e.g.
|
||||
# paragraphs of markdown text.
|
||||
wrapLinesInStagingView: true
|
||||
# One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
|
||||
language: auto
|
||||
# Format used when displaying time e.g. commit time.
|
||||
# Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format
|
||||
timeFormat: 02 Jan 06
|
||||
# Format used when displaying time if the time is less than 24 hours ago.
|
||||
# Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format
|
||||
shortTimeFormat: 3:04PM
|
||||
# Config relating to colors and styles.
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#color-attributes
|
||||
theme:
|
||||
# Border color of focused window
|
||||
activeBorderColor:
|
||||
- green
|
||||
- bold
|
||||
# Border color of non-focused windows
|
||||
inactiveBorderColor:
|
||||
- default
|
||||
# Border color of focused window when searching in that window
|
||||
searchingActiveBorderColor:
|
||||
- cyan
|
||||
- bold
|
||||
# Color of keybindings help text in the bottom line
|
||||
optionsTextColor:
|
||||
- blue
|
||||
# Background color of selected line.
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line
|
||||
selectedRangeBgColor:
|
||||
- "#444444"
|
||||
selectedLineBgColor:
|
||||
- "#444444"
|
||||
# Background color of selected line when view doesn't have focus.
|
||||
inactiveViewSelectedLineBgColor:
|
||||
- bold
|
||||
# Foreground color of copied commit
|
||||
cherryPickedCommitFgColor:
|
||||
- blue
|
||||
# Background color of copied commit
|
||||
cherryPickedCommitBgColor:
|
||||
- cyan
|
||||
# Foreground color of marked base commit (for rebase)
|
||||
markedBaseCommitFgColor:
|
||||
- blue
|
||||
# Background color of marked base commit (for rebase)
|
||||
markedBaseCommitBgColor:
|
||||
- yellow
|
||||
# Color for file with unstaged changes
|
||||
unstagedChangesColor:
|
||||
- red
|
||||
# Default text color
|
||||
defaultFgColor:
|
||||
- default
|
||||
# Config relating to the commit length indicator
|
||||
commitLength:
|
||||
# If true, show an indicator of commit message length
|
||||
show: true
|
||||
# If true, show the '5 of 20' footer at the bottom of list views
|
||||
showListFooter: true
|
||||
# If true, display the files in the file views as a tree. If false, display the files as a flat list.
|
||||
# This can be toggled from within Lazygit with the '~' key, but that will not change the default.
|
||||
showFileTree: true
|
||||
# If true, show the number of lines changed per file in the Files view
|
||||
showNumstatInFilesView: false
|
||||
# If true, show a random tip in the command log when Lazygit starts
|
||||
showRandomTip: true
|
||||
# If true, show the command log
|
||||
showCommandLog: true
|
||||
# If true, show the bottom line that contains keybinding info and useful buttons. If false, this line will be hidden except to display a loader for an in-progress action.
|
||||
showBottomLine: true
|
||||
# If true, show jump-to-window keybindings in window titles.
|
||||
showPanelJumps: true
|
||||
# Deprecated: use nerdFontsVersion instead
|
||||
showIcons: false
|
||||
# Nerd fonts version to use.
|
||||
# One of: '2' | '3' | empty string (default)
|
||||
# If empty, do not show icons.
|
||||
nerdFontsVersion: ""
|
||||
# If true (default), file icons are shown in the file views. Only relevant if NerdFontsVersion is not empty.
|
||||
showFileIcons: true
|
||||
# Length of author name in (non-expanded) commits view. 2 means show initials only.
|
||||
commitAuthorShortLength: 2
|
||||
# Length of author name in expanded commits view. 2 means show initials only.
|
||||
commitAuthorLongLength: 17
|
||||
# Length of commit hash in commits view. 0 shows '*' if NF icons aren't on.
|
||||
commitHashLength: 8
|
||||
# If true, show commit hashes alongside branch names in the branches view.
|
||||
showBranchCommitHash: false
|
||||
# Whether to show the divergence from the base branch in the branches view.
|
||||
# One of: 'none' | 'onlyArrow' | 'arrowAndNumber'
|
||||
showDivergenceFromBaseBranch: none
|
||||
# Height of the command log view
|
||||
commandLogSize: 8
|
||||
# Whether to split the main window when viewing file changes.
|
||||
# One of: 'auto' | 'always'
|
||||
# If 'auto', only split the main window when a file has both staged and unstaged changes
|
||||
splitDiff: auto
|
||||
# Default size for focused window. Window size can be changed from within Lazygit with '+' and '_' (but this won't change the default).
|
||||
# One of: 'normal' (default) | 'half' | 'full'
|
||||
screenMode: normal
|
||||
# Window border style.
|
||||
# One of 'rounded' (default) | 'single' | 'double' | 'hidden'
|
||||
border: rounded
|
||||
# If true, show a seriously epic explosion animation when nuking the working tree.
|
||||
animateExplosion: true
|
||||
# Whether to stack UI components on top of each other.
|
||||
# One of 'auto' (default) | 'always' | 'never'
|
||||
portraitMode: auto
|
||||
# How things are filtered when typing '/'.
|
||||
# One of 'substring' (default) | 'fuzzy'
|
||||
filterMode: substring
|
||||
# Config relating to the spinner.
|
||||
spinner:
|
||||
# The frames of the spinner animation.
|
||||
frames:
|
||||
- '|'
|
||||
- /
|
||||
- '-'
|
||||
- \
|
||||
# The "speed" of the spinner in milliseconds.
|
||||
rate: 50
|
||||
# Status panel view.
|
||||
# One of 'dashboard' (default) | 'allBranchesLog'
|
||||
statusPanelView: dashboard
|
||||
# If true, jump to the Files panel after popping a stash
|
||||
switchToFilesAfterStashPop: true
|
||||
# If true, jump to the Files panel after applying a stash
|
||||
switchToFilesAfterStashApply: true
|
||||
# If true, when using the panel jump keys (default 1 through 5) and target panel is already active, go to next tab instead
|
||||
switchTabsWithPanelJumpKeys: false
|
||||
# Config relating to git
|
||||
git:
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md
|
||||
diffRenderers:
|
||||
- # Value of the --color arg in the git diff command. Some pagers want this to be set to 'always' and some want it set to 'never'
|
||||
colorArg: always
|
||||
# If true, Lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager).
|
||||
useConfig: false
|
||||
type: rawGit
|
||||
# Config relating to committing
|
||||
commit:
|
||||
# If true, pass '--signoff' flag when committing
|
||||
signOff: false
|
||||
# Automatic WYSIWYG wrapping of the commit message as you type
|
||||
autoWrapCommitMessage: true
|
||||
# If autoWrapCommitMessage is true, the width to wrap to
|
||||
autoWrapWidth: 72
|
||||
# Config relating to merging
|
||||
merging:
|
||||
# If true, run merges in a subprocess so that if a commit message is required, Lazygit will not hang
|
||||
# Only applicable to unix users.
|
||||
manualCommit: false
|
||||
# Extra args passed to `git merge`, e.g. --no-ff
|
||||
args: ""
|
||||
# The commit message to use for a squash merge commit. Can contain "{{selectedRef}}" and "{{currentBranch}}" placeholders.
|
||||
squashMergeMessage: Squash merge {{selectedRef}} into {{currentBranch}}
|
||||
# list of branches that are considered 'main' branches, used when displaying commits
|
||||
mainBranches:
|
||||
- master
|
||||
- main
|
||||
# Prefix to use when skipping hooks. E.g. if set to 'WIP', then pre-commit hooks will be skipped when the commit message starts with 'WIP'
|
||||
skipHookPrefix: WIP
|
||||
# If true, periodically fetch from remote
|
||||
autoFetch: true
|
||||
# If true, periodically refresh files and submodules
|
||||
autoRefresh: true
|
||||
# If true, pass the --all arg to git fetch
|
||||
fetchAll: true
|
||||
# If true, lazygit will automatically stage files that used to have merge
|
||||
# conflicts but no longer do; and it will also ask you if you want to
|
||||
# continue a merge or rebase if you've resolved all conflicts. If false, it
|
||||
# won't do either of these things.
|
||||
autoStageResolvedConflicts: true
|
||||
# Command used when displaying the current branch git log in the main window
|
||||
branchLogCmd: git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --
|
||||
# If true, do not spawn a separate process when using GPG
|
||||
overrideGpg: false
|
||||
# If true, do not allow force pushes
|
||||
disableForcePushing: false
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix
|
||||
commitPrefix:
|
||||
- # pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use "^\\w+\\/(\\w+-\\w+).*"
|
||||
pattern: ""
|
||||
# Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] "
|
||||
replace: ""
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-branch-name-prefix
|
||||
branchPrefix: ""
|
||||
# If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀
|
||||
# (This should really be under 'gui', not 'git')
|
||||
parseEmoji: false
|
||||
# Config for showing the log in the commits view
|
||||
log:
|
||||
# One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default'
|
||||
# 'topo-order' makes it easier to read the git log graph, but commits may not
|
||||
# appear chronologically. See https://git-scm.com/docs/
|
||||
#
|
||||
# Deprecated: Configure this with `Log menu -> Commit sort order` (<c-l> in the commits window by default).
|
||||
order: topo-order
|
||||
# This determines whether the git graph is rendered in the commits panel
|
||||
# One of 'always' | 'never' | 'when-maximised'
|
||||
#
|
||||
# Deprecated: Configure this with `Log menu -> Show git graph` (<c-l> in the commits window by default).
|
||||
showGraph: always
|
||||
# displays the whole git graph by default in the commits view (equivalent to passing the `--all` argument to `git log`)
|
||||
showWholeGraph: false
|
||||
# When copying commit hashes to the clipboard, truncate them to this
|
||||
# length. Set to 40 to disable truncation.
|
||||
truncateCopiedCommitHashesTo: 12
|
||||
allBranchesLogCmds:
|
||||
- git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium
|
||||
# Periodic update checks
|
||||
update:
|
||||
# One of: 'prompt' (default) | 'background' | 'never'
|
||||
method: prompt
|
||||
# Period in days between update checks
|
||||
days: 14
|
||||
# Background refreshes
|
||||
refresher:
|
||||
# File/submodule refresh interval in seconds.
|
||||
# Auto-refresh can be disabled via option 'git.autoRefresh'.
|
||||
refreshInterval: 10
|
||||
# Re-fetch interval in seconds.
|
||||
# Auto-fetch can be disabled via option 'git.autoFetch'.
|
||||
fetchInterval: 60
|
||||
# If true, show a confirmation popup before quitting Lazygit
|
||||
confirmOnQuit: false
|
||||
# If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close
|
||||
quitOnTopLevelReturn: false
|
||||
# Config relating to things outside of Lazygit like how files are opened, copying to clipboard, etc
|
||||
os:
|
||||
# Command for editing a file. Should contain "{{filename}}".
|
||||
edit: ""
|
||||
# Command for editing a file at a given line number. Should contain
|
||||
# "{{filename}}", and may optionally contain "{{line}}".
|
||||
editAtLine: ""
|
||||
# Same as EditAtLine, except that the command needs to wait until the
|
||||
# window is closed.
|
||||
editAtLineAndWait: ""
|
||||
# For opening a directory in an editor
|
||||
openDirInEditor: ""
|
||||
# A built-in preset that sets all of the above settings. Supported presets
|
||||
# are defined in the getPreset function in editor_presets.go.
|
||||
editPreset: ""
|
||||
# Command for opening a file, as if the file is double-clicked. Should
|
||||
# contain "{{filename}}", but doesn't support "{{line}}".
|
||||
open: ""
|
||||
# Command for opening a link. Should contain "{{link}}".
|
||||
openLink: ""
|
||||
# EditCommand is the command for editing a file.
|
||||
# Deprecated: use Edit instead. Note that semantics are different:
|
||||
# EditCommand is just the command itself, whereas Edit contains a
|
||||
# "{{filename}}" variable.
|
||||
editCommand: ""
|
||||
# EditCommandTemplate is the command template for editing a file
|
||||
# Deprecated: use EditAtLine instead.
|
||||
editCommandTemplate: ""
|
||||
# OpenCommand is the command for opening a file
|
||||
# Deprecated: use Open instead.
|
||||
openCommand: ""
|
||||
# OpenLinkCommand is the command for opening a link
|
||||
# Deprecated: use OpenLink instead.
|
||||
openLinkCommand: ""
|
||||
# CopyToClipboardCmd is the command for copying to clipboard.
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard
|
||||
copyToClipboardCmd: ""
|
||||
# ReadFromClipboardCmd is the command for reading the clipboard.
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard
|
||||
readFromClipboardCmd: ""
|
||||
# If true, don't display introductory popups upon opening Lazygit.
|
||||
disableStartupPopups: false
|
||||
# What to do when opening Lazygit outside of a git repo.
|
||||
# - 'prompt': (default) ask whether to initialize a new repo or open in the most recent repo
|
||||
# - 'create': initialize a new repo
|
||||
# - 'skip': open most recent repo
|
||||
# - 'quit': exit Lazygit
|
||||
notARepository: prompt
|
||||
# If true, display a confirmation when subprocess terminates. This allows you to view the output of the subprocess before returning to Lazygit.
|
||||
promptToReturnFromSubprocess: true
|
||||
# Keybindings
|
||||
keybinding:
|
||||
universal:
|
||||
quit: q
|
||||
quit-alt1: <c-c>
|
||||
return: <esc>
|
||||
quitWithoutChangingDirectory: Q
|
||||
togglePanel: <tab>
|
||||
prevItem: <up>
|
||||
nextItem: <down>
|
||||
prevItem-alt: k
|
||||
nextItem-alt: j
|
||||
prevPage: ','
|
||||
nextPage: .
|
||||
scrollLeft: H
|
||||
scrollRight: L
|
||||
gotoTop: <
|
||||
gotoBottom: '>'
|
||||
toggleRangeSelect: v
|
||||
rangeSelectDown: <s-down>
|
||||
rangeSelectUp: <s-up>
|
||||
prevBlock: <left>
|
||||
nextBlock: <right>
|
||||
prevBlock-alt: h
|
||||
nextBlock-alt: l
|
||||
nextBlock-alt2: <tab>
|
||||
prevBlock-alt2: <backtab>
|
||||
jumpToBlock:
|
||||
- "1"
|
||||
- "2"
|
||||
- "3"
|
||||
- "4"
|
||||
- "5"
|
||||
nextMatch: "n"
|
||||
prevMatch: "N"
|
||||
startSearch: /
|
||||
optionMenu: '?'
|
||||
optionMenu-alt1: <disabled>
|
||||
select: <space>
|
||||
goInto: <enter>
|
||||
confirm: <enter>
|
||||
confirmInEditor: <a-enter>
|
||||
remove: d
|
||||
new: "n"
|
||||
edit: e
|
||||
openFile: o
|
||||
scrollUpMain: <pgup>
|
||||
scrollDownMain: <pgdown>
|
||||
scrollUpMain-alt1: K
|
||||
scrollDownMain-alt1: J
|
||||
scrollUpMain-alt2: <c-u>
|
||||
scrollDownMain-alt2: <c-d>
|
||||
executeShellCommand: ':'
|
||||
createRebaseOptionsMenu: m
|
||||
# 'Files' appended for legacy reasons
|
||||
pushFiles: P
|
||||
# 'Files' appended for legacy reasons
|
||||
pullFiles: p
|
||||
refresh: R
|
||||
createPatchOptionsMenu: <c-p>
|
||||
nextTab: ']'
|
||||
prevTab: '['
|
||||
nextScreenMode: +
|
||||
prevScreenMode: _
|
||||
undo: z
|
||||
redo: <c-z>
|
||||
filteringMenu: <c-s>
|
||||
diffingMenu: W
|
||||
diffingMenu-alt: <c-e>
|
||||
copyToClipboard: <c-o>
|
||||
openRecentRepos: <c-r>
|
||||
submitEditorText: <enter>
|
||||
extrasMenu: '@'
|
||||
toggleWhitespaceInDiffView: <c-w>
|
||||
increaseContextInDiffView: '}'
|
||||
decreaseContextInDiffView: '{'
|
||||
increaseRenameSimilarityThreshold: )
|
||||
decreaseRenameSimilarityThreshold: (
|
||||
openDiffTool: <c-t>
|
||||
newWorktree: w
|
||||
status:
|
||||
checkForUpdate: u
|
||||
recentRepos: <enter>
|
||||
allBranchesLogGraph: a
|
||||
files:
|
||||
commitChanges: c
|
||||
commitChangesWithoutHook: w
|
||||
amendLastCommit: A
|
||||
commitChangesWithEditor: C
|
||||
findBaseCommitForFixup: <c-f>
|
||||
confirmDiscard: x
|
||||
ignoreFile: i
|
||||
refreshFiles: r
|
||||
stashAllChanges: s
|
||||
viewStashOptions: S
|
||||
toggleStagedAll: a
|
||||
viewResetOptions: D
|
||||
fetch: f
|
||||
toggleTreeView: '`'
|
||||
openMergeOptions: M
|
||||
openStatusFilter: <c-b>
|
||||
copyFileInfoToClipboard: "y"
|
||||
branches:
|
||||
createPullRequest: o
|
||||
viewPullRequestOptions: O
|
||||
copyPullRequestURL: <c-y>
|
||||
checkoutBranchByName: c
|
||||
forceCheckoutBranch: F
|
||||
rebaseBranch: r
|
||||
renameBranch: R
|
||||
mergeIntoCurrentBranch: M
|
||||
viewGitFlowOptions: i
|
||||
fastForward: f
|
||||
createTag: T
|
||||
pushTag: P
|
||||
setUpstream: u
|
||||
fetchRemote: f
|
||||
sortOrder: s
|
||||
commits:
|
||||
squashDown: s
|
||||
renameCommit: r
|
||||
renameCommitWithEditor: R
|
||||
viewResetOptions: g
|
||||
markCommitAsFixup: f
|
||||
createFixupCommit: F
|
||||
squashAboveCommits: S
|
||||
moveDownCommit: <c-j>
|
||||
moveUpCommit: <c-k>
|
||||
amendToCommit: A
|
||||
resetCommitAuthor: a
|
||||
pickCommit: p
|
||||
revertCommit: t
|
||||
cherryPickCopy: C
|
||||
pasteCommits: V
|
||||
markCommitAsBaseForRebase: B
|
||||
tagCommit: T
|
||||
checkoutCommit: <space>
|
||||
# resetCherryPick: <c-R>
|
||||
copyCommitAttributeToClipboard: "y"
|
||||
openLogMenu: <c-l>
|
||||
openInBrowser: o
|
||||
viewBisectOptions: b
|
||||
startInteractiveRebase: i
|
||||
amendAttribute:
|
||||
resetAuthor: a
|
||||
setAuthor: A
|
||||
addCoAuthor: c
|
||||
stash:
|
||||
popStash: g
|
||||
renameStash: r
|
||||
commitFiles:
|
||||
checkoutCommitFile: c
|
||||
main:
|
||||
toggleSelectHunk: a
|
||||
pickBothHunks: b
|
||||
editSelectHunk: E
|
||||
submodules:
|
||||
init: i
|
||||
update: u
|
||||
bulkMenu: b
|
||||
commitMessage:
|
||||
commitMenu: <c-o>
|
||||
@@ -0,0 +1,3 @@
|
||||
om
|
||||
openWebUI
|
||||
itTools
|
||||
@@ -0,0 +1,36 @@
|
||||
jq
|
||||
fq
|
||||
rg
|
||||
fd
|
||||
fzf
|
||||
lsd
|
||||
bat
|
||||
zoxide
|
||||
resvg
|
||||
mosh
|
||||
tennis
|
||||
dysk
|
||||
dust
|
||||
scrcpy
|
||||
adb
|
||||
gpg
|
||||
fnm
|
||||
recfmt
|
||||
recsel
|
||||
pass
|
||||
xxd
|
||||
voxcii
|
||||
tldr
|
||||
rsync
|
||||
cowsay
|
||||
fortune
|
||||
lolcat
|
||||
glow
|
||||
pake
|
||||
bwrap
|
||||
dog
|
||||
nmap
|
||||
traceroute
|
||||
fuck
|
||||
atool
|
||||
aria2c
|
||||
@@ -0,0 +1,72 @@
|
||||
browsh
|
||||
wiki-tui
|
||||
wikiman
|
||||
yazi
|
||||
tdf
|
||||
dysk
|
||||
dust
|
||||
ncdu
|
||||
duf
|
||||
systemctl-tui
|
||||
btop
|
||||
bandwhich
|
||||
mtr
|
||||
gping
|
||||
bmon
|
||||
profanity
|
||||
nmtui
|
||||
impala
|
||||
bluetui
|
||||
sshm
|
||||
aichat
|
||||
tt
|
||||
gittype
|
||||
toofan
|
||||
pastel
|
||||
hexyl
|
||||
tmux
|
||||
zellij
|
||||
nvim
|
||||
vim
|
||||
tetrigo
|
||||
pyradio
|
||||
px7-radio
|
||||
kew
|
||||
cmatrix
|
||||
neo-matrix
|
||||
cava
|
||||
pipes-rs
|
||||
asciiquarium
|
||||
cbonsai
|
||||
tclock
|
||||
hunk
|
||||
gittop
|
||||
lazygit
|
||||
lazyjournal
|
||||
lazydocker
|
||||
lazyrsync
|
||||
ctop
|
||||
colima
|
||||
dive
|
||||
asciinema
|
||||
posting
|
||||
serie
|
||||
clx
|
||||
whosthere
|
||||
voxcii
|
||||
bookokrat
|
||||
tennis
|
||||
llmfit
|
||||
termdraw
|
||||
torlink
|
||||
riptide
|
||||
quien
|
||||
eilmeldung
|
||||
calcure
|
||||
weathr
|
||||
hyprmon
|
||||
hulak
|
||||
netwatch
|
||||
gpk
|
||||
circumflex
|
||||
darya
|
||||
@@ -0,0 +1,6 @@
|
||||
column_width = 120
|
||||
line_endings = "Unix"
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
quote_style = "AutoPreferDouble"
|
||||
call_parentheses = "None"
|
||||
@@ -0,0 +1,98 @@
|
||||
# Neovim Configuration Setup
|
||||
|
||||
This Neovim configuration is built on top of [NvChad](https://nvchad.com/), a popular Neovim framework designed for speed and aesthetics. It uses [lazy.nvim](https://github.com/folke/lazy.nvim) as the plugin manager.
|
||||
|
||||
## Core Components
|
||||
|
||||
- **Framework**: [NvChad](https://nvchad.com/) (v2.5)
|
||||
- **Plugin Manager**: `lazy.nvim`
|
||||
- **Theme Engine**: `base46` (integrated with NvChad)
|
||||
- **Keybindings**: Custom mappings are defined in `lua/mappings.lua`.
|
||||
- **Options**: Base options are inherited from NvChad, with customizations in `lua/options.lua`.
|
||||
|
||||
## Installed Plugins & Features
|
||||
|
||||
The configuration includes several key plugins and features:
|
||||
|
||||
### Development Tools
|
||||
- **LSP (Language Server Protocol)**: Configured via `nvim-lspconfig`. Note that you must install the actual language servers using [Mason.nvim](https://github.com/williamboman/mason.nvim).
|
||||
- **Formatting**: Uses `conform.nvim` for code formatting (configured in `lua/configs/conform.lua`).
|
||||
- **Treesitter**: Provides advanced syntax highlighting and code folding (configured in `lua/plugins/init.lua`).
|
||||
- **Telescope**: Powerful fuzzy finder for files, text, and LSP symbols.
|
||||
|
||||
### UI & Productivity
|
||||
- **Snacks.nvim**: A collection of useful utilities including:
|
||||
- `explorer`: File explorer.
|
||||
- `indent`: Indent guides (replaces `indent-blankline.nvim` to avoid duplication).
|
||||
- `picker`: Fast picker for various tasks.
|
||||
- `notifier`: Improved notification system.
|
||||
- `words`: Word count and related features.
|
||||
- **Render Markdown**: Enhances the appearance of Markdown files in the buffer (`lua/configs/render-markdown.lua`).
|
||||
|
||||
## Maintenance & Package Management
|
||||
|
||||
### Managing Plugins (lazy.nvim)
|
||||
To update your installed Neovim plugins:
|
||||
1. Open Neovim.
|
||||
2. Run `:Lazy` to open the plugin manager UI.
|
||||
3. Press `U` to check for updates and `u` to update everything.
|
||||
|
||||
### Managing LSPs & Tools (Mason.nvim)
|
||||
While plugins are managed by `lazy.nvim`, the actual language servers, debuggers, and formatters are managed by **Mason**.
|
||||
1. Open Neovim.
|
||||
2. Run `:Mason` to open the Mason UI.
|
||||
3. Use the UI to install or update your desired LSPs (e.g., `ts_ls`, `html`, `cssls`), linters, or formatters.
|
||||
|
||||
### Managing Syntax Highlighting (Treesitter)
|
||||
To ensure all language parsers are installed for proper syntax highlighting:
|
||||
1. Open Neovim.
|
||||
2. Run `:TSUpdate` (or `:TSInstall <language>` for a specific one).
|
||||
|
||||
## Custom Keybindings
|
||||
|
||||
Some notable custom mappings (defined in `lua/mappings.lua`):
|
||||
|
||||
| Mapping | Action | Description |
|
||||
|---------|--------|-------------|
|
||||
| `gd` | `vim.lsp.buf.definition` | Go to definition |
|
||||
| `gD` | `Telescope lsp_definitions` | Go to definitions (Telescope) |
|
||||
| `grr` | `Telescope lsp_references` | Go to references (Telescope) |
|
||||
| `<leader>da` | `vim.lsp.buf.code_action()` | Code actions |
|
||||
| `<leader>dh` | `vim.diagnostic.open_float()` | Show diagnostics in float |
|
||||
| `<leader>dj` | `vim.diagnostic.jump` | Go to next diagnostic |
|
||||
| `<leader>dk` | `vim.diagnostic.jump` | Go to previous diagnostic |
|
||||
| `<leader>fr` | `Telescope resume` | Resume last Telescope search |
|
||||
| `<leader>fs` | `Telescope grep_string` | Find selected string |
|
||||
| `<leader>fk` | `Telescope keymaps` | Find keymaps |
|
||||
| `<leader>fd` | `Telescope diagnostics` | Search diagnostics |
|
||||
|
||||
**Improved Deletion/Change:**
|
||||
- `x` (in Normal/Visual mode): Deletes a character without yanking it to the register.
|
||||
- `c` (in Normal/Visual mode): Changes text without yanking it to the register.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```text
|
||||
.
|
||||
├── init.lua # Entry point: bootstraps lazy.nvim and loads config
|
||||
├── lazy-lock.json # Lockfile for lazy.nvim
|
||||
└── lua/
|
||||
├── chadrc.lua # NvChad configuration
|
||||
├── configs/ # Plugin-specific configurations
|
||||
│ ├── conform.lua
|
||||
│ ├── lazy.lua
|
||||
│ ├── lspconfig.lua
|
||||
│ └── render-markdown.lua
|
||||
├── mappings.lua # Custom keybindings
|
||||
├── options.lua # Custom Neovim options
|
||||
└── plugins/
|
||||
└── init.lua # Plugin definitions and setup
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
1. Ensure you have [Neovim](https://neovim.io/) (latest stable or nightly) installed.
|
||||
2. Clone this repository to your Neovim configuration directory (usually `~/.config/nvim`).
|
||||
3. Open Neovim. `lazy.nvim` will automatically bootstrap and install all required plugins.
|
||||
4. **Important**: After the initial plugin installation, run `:MasonInstall <server_name>` (or use the `:Mason` UI) to install the language servers required for your workflow.
|
||||
5. Restart Neovim after the initial installation completes.
|
||||
@@ -0,0 +1,38 @@
|
||||
vim.g.base46_cache = vim.fn.stdpath "data" .. "/base46/"
|
||||
vim.g.mapleader = " "
|
||||
vim.opt.relativenumber = true
|
||||
|
||||
-- bootstrap lazy and all plugins
|
||||
local lazypath = vim.fn.stdpath "data" .. "/lazy/lazy.nvim"
|
||||
|
||||
if not vim.uv.fs_stat(lazypath) then
|
||||
local repo = "https://github.com/folke/lazy.nvim.git"
|
||||
vim.fn.system { "git", "clone", "--filter=blob:none", repo, "--branch=stable", lazypath }
|
||||
end
|
||||
|
||||
vim.opt.rtp:prepend(lazypath)
|
||||
|
||||
local lazy_config = require "configs.lazy"
|
||||
|
||||
-- load plugins
|
||||
require("lazy").setup({
|
||||
{
|
||||
"NvChad/NvChad",
|
||||
lazy = false,
|
||||
branch = "v2.5",
|
||||
import = "nvchad.plugins",
|
||||
},
|
||||
|
||||
{ import = "plugins" },
|
||||
}, lazy_config)
|
||||
|
||||
-- load theme
|
||||
dofile(vim.g.base46_cache .. "defaults")
|
||||
dofile(vim.g.base46_cache .. "statusline")
|
||||
|
||||
require "options"
|
||||
require "nvchad.autocmds"
|
||||
|
||||
vim.schedule(function()
|
||||
require "mappings"
|
||||
end)
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"LuaSnip": { "branch": "master", "commit": "0abc8f390b278c3b4aabc4c004ac8a088b65cf24" },
|
||||
"NvChad": { "branch": "v2.5", "commit": "add44b952d631981614bbb8cfc6f7002f296dfe6" },
|
||||
"base46": { "branch": "v3.0", "commit": "267954c8663607823f03a3259bb8deb15688212f" },
|
||||
"cmp-async-path": { "branch": "main", "commit": "98185a91d49ff5dd249aebf2f7456e18063fa2a0" },
|
||||
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
|
||||
"cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" },
|
||||
"cmp-nvim-lua": { "branch": "main", "commit": "e3a22cb071eb9d6508a156306b102c45cd2d573d" },
|
||||
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
|
||||
"conform.nvim": { "branch": "master", "commit": "016802de402556da54c36bd7359b441266b01cdd" },
|
||||
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
|
||||
"gitsigns.nvim": { "branch": "main", "commit": "d29ecf6626cf6ffb109fb04a8ecd92c46f4a1ce9" },
|
||||
"indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" },
|
||||
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
||||
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
|
||||
"menu": { "branch": "main", "commit": "7a0a4a2896b715c066cfbe320bdc048091874cc6" },
|
||||
"minty": { "branch": "main", "commit": "aafc9e8e0afe6bf57580858a2849578d8d8db9e0" },
|
||||
"nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" },
|
||||
"nvim-cmp": { "branch": "main", "commit": "2ffe79f1f021def8dd1fcd81deb16f1bb0d989f3" },
|
||||
"nvim-lspconfig": { "branch": "master", "commit": "4267d26e60323a45e18f8e7a63a964cc8f53ca4e" },
|
||||
"nvim-tree.lua": { "branch": "master", "commit": "b2aadda94b107480c48e548d6db51c6840b7b33c" },
|
||||
"nvim-treesitter": { "branch": "main", "commit": "c9f9ed6c1892f629ea399f4ee7905f2686fa13f2" },
|
||||
"nvim-web-devicons": { "branch": "master", "commit": "2ae6958df7ced50baac5035cec0c15799eedfbf7" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
|
||||
"render-markdown.nvim": { "branch": "main", "commit": "f422cb5c6855f150e2ddcfaf44e7157b98b34f6a" },
|
||||
"snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" },
|
||||
"telescope.nvim": { "branch": "master", "commit": "427b576c16792edad01a92b89721d923c19ad60f" },
|
||||
"ui": { "branch": "v3.0", "commit": "fe781d1c12860d6a25d45e588fe4fdd27eb34a1a" },
|
||||
"volt": { "branch": "main", "commit": "620de1321f275ec9d80028c68d1b88b409c0c8b1" },
|
||||
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
-- This file needs to have same structure as nvconfig.lua
|
||||
-- https://github.com/NvChad/ui/blob/v3.0/lua/nvconfig.lua
|
||||
-- Please read that file to know all available options :(
|
||||
|
||||
---@type ChadrcConfig
|
||||
|
||||
local M = {
|
||||
lsp = { signature = true },
|
||||
|
||||
base46 = {
|
||||
theme = "onedark",
|
||||
transparency = true,
|
||||
hl_override = {
|
||||
NvimTreeGitDirty = {
|
||||
fg = "#DBA55D",
|
||||
},
|
||||
},
|
||||
-- Comment = { italic = true },
|
||||
-- ["@comment"] = { italic = true },
|
||||
},
|
||||
|
||||
nvdash = {
|
||||
load_on_startup = true,
|
||||
-- buttons = {
|
||||
-- { txt = " Find File", keys = "Spc f f", cmd = "Telescope find_files custom" },
|
||||
-- { txt = " Recent Files", keys = "Spc f o", cmd = "Telescope oldfiles" },
|
||||
-- -- more... check nvconfig.lua file for full list of buttons
|
||||
-- },
|
||||
},
|
||||
|
||||
ui = {
|
||||
-- lazyload it when there are 1+ buffers
|
||||
tabufline = {
|
||||
enabled = true,
|
||||
lazyload = true,
|
||||
order = { "treeOffset", "buffers", "tabs", "btns" },
|
||||
modules = nil,
|
||||
bufwidth = 21,
|
||||
},
|
||||
},
|
||||
|
||||
term = {
|
||||
base46_colors = true,
|
||||
winopts = { number = false },
|
||||
sizes = { sp = 0.5, vsp = 0.2, ["bo sp"] = 0.3, ["bo vsp"] = 0.2 },
|
||||
float = {
|
||||
relative = "editor",
|
||||
row = 0.05,
|
||||
col = 0.05,
|
||||
width = 0.9,
|
||||
height = 0.8,
|
||||
border = "single",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,17 @@
|
||||
local options = {
|
||||
formatters_by_ft = {
|
||||
lua = { "stylua" },
|
||||
css = { "prettier" },
|
||||
html = { "prettier" },
|
||||
typescript = { "prettier" },
|
||||
javascript = { "prettier" },
|
||||
},
|
||||
|
||||
format_on_save = {
|
||||
-- These options will be passed to conform.format()
|
||||
timeout_ms = 500,
|
||||
lsp_format = "fallback",
|
||||
},
|
||||
}
|
||||
|
||||
return options
|
||||
@@ -0,0 +1,47 @@
|
||||
return {
|
||||
defaults = { lazy = true },
|
||||
install = { colorscheme = { "nvchad" } },
|
||||
|
||||
ui = {
|
||||
icons = {
|
||||
ft = "",
|
||||
lazy = " ",
|
||||
loaded = "",
|
||||
not_loaded = "",
|
||||
},
|
||||
},
|
||||
|
||||
performance = {
|
||||
rtp = {
|
||||
disabled_plugins = {
|
||||
"2html_plugin",
|
||||
"tohtml",
|
||||
"getscript",
|
||||
"getscriptPlugin",
|
||||
"gzip",
|
||||
"logipat",
|
||||
"netrw",
|
||||
"netrwPlugin",
|
||||
"netrwSettings",
|
||||
"netrwFileHandlers",
|
||||
"matchit",
|
||||
"tar",
|
||||
"tarPlugin",
|
||||
"rrhelper",
|
||||
"spellfile_plugin",
|
||||
"vimball",
|
||||
"vimballPlugin",
|
||||
"zip",
|
||||
"zipPlugin",
|
||||
"tutor",
|
||||
"rplugin",
|
||||
"syntax",
|
||||
"synmenu",
|
||||
"optwin",
|
||||
"compiler",
|
||||
"bugreport",
|
||||
"ftplugin",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
require("nvchad.configs.lspconfig").defaults()
|
||||
|
||||
local servers = { "html", "cssls", "ts_ls", "eslint" }
|
||||
vim.lsp.enable(servers)
|
||||
|
||||
-- local lspconfig = require "lspconfig"
|
||||
-- local nvlsp = require "nvchad.configs.lspconfig"
|
||||
--
|
||||
-- -- lsps with default config
|
||||
-- for _, lsp in ipairs(servers) do
|
||||
-- lspconfig[lsp].setup {
|
||||
-- on_attach = nvlsp.on_attach,
|
||||
-- on_init = nvlsp.on_init,
|
||||
-- capabilities = nvlsp.capabilities,
|
||||
-- }
|
||||
-- end
|
||||
--
|
||||
-- -- configuring single server, example: typescript
|
||||
-- lspconfig.ts_ls.setup {
|
||||
-- filetypes = { 'typescript', 'javascript', 'javascriptreact', 'typescriptreact', 'vue', 'markdown' },
|
||||
-- }
|
||||
--
|
||||
-- -- configuring single server, example: typescript
|
||||
-- -- lspconfig.ts_ls.setup {
|
||||
-- -- on_attach = nvlsp.on_attach,
|
||||
-- -- on_init = nvlsp.on_init,
|
||||
-- -- capabilities = nvlsp.capabilities,
|
||||
-- -- }
|
||||
@@ -0,0 +1,851 @@
|
||||
return {
|
||||
-- Whether markdown should be rendered by default.
|
||||
enabled = true,
|
||||
-- Vim modes that will show a rendered view of the markdown file, :h mode(), for all enabled
|
||||
-- components. Individual components can be enabled for other modes. Remaining modes will be
|
||||
-- unaffected by this plugin.
|
||||
render_modes = { "i", "n", "c", "t" },
|
||||
-- Maximum file size (in MB) that this plugin will attempt to render.
|
||||
-- Any file larger than this will effectively be ignored.
|
||||
max_file_size = 10.0,
|
||||
-- Milliseconds that must pass before updating marks, updates occur.
|
||||
-- within the context of the visible window, not the entire buffer.
|
||||
debounce = 100,
|
||||
-- Pre configured settings that will attempt to mimic various target user experiences.
|
||||
-- Any user provided settings will take precedence.
|
||||
-- | obsidian | mimic Obsidian UI |
|
||||
-- | lazy | will attempt to stay up to date with LazyVim configuration |
|
||||
-- | none | does nothing |
|
||||
preset = "none",
|
||||
-- The level of logs to write to file: vim.fn.stdpath('state') .. '/render-markdown.log'.
|
||||
-- Only intended to be used for plugin development / debugging.
|
||||
log_level = "error",
|
||||
-- Print runtime of main update method.
|
||||
-- Only intended to be used for plugin development / debugging.
|
||||
log_runtime = false,
|
||||
-- Filetypes this plugin will run on.
|
||||
file_types = { "markdown", "gitcommit" },
|
||||
-- Takes buffer as input, if it returns true this plugin will not attach to the buffer
|
||||
ignore = function()
|
||||
return false
|
||||
end,
|
||||
-- Additional events that will trigger this plugin's render loop.
|
||||
change_events = {},
|
||||
injections = {
|
||||
-- Out of the box language injections for known filetypes that allow markdown to be interpreted
|
||||
-- in specified locations, see :h treesitter-language-injections.
|
||||
-- Set enabled to false in order to disable.
|
||||
|
||||
gitcommit = {
|
||||
enabled = true,
|
||||
query = [[
|
||||
((message) @injection.content
|
||||
(#set! injection.combined)
|
||||
(#set! injection.include-children)
|
||||
(#set! injection.language "markdown"))
|
||||
]],
|
||||
},
|
||||
},
|
||||
patterns = {
|
||||
-- Highlight patterns to disable for filetypes, i.e. lines concealed around code blocks
|
||||
|
||||
markdown = {
|
||||
disable = true,
|
||||
directives = {
|
||||
{ id = 17, name = "conceal_lines" },
|
||||
{ id = 18, name = "conceal_lines" },
|
||||
},
|
||||
},
|
||||
},
|
||||
anti_conceal = {
|
||||
-- This enables hiding any added text on the line the cursor is on.
|
||||
enabled = true,
|
||||
-- Modes to disable anti conceal feature.
|
||||
disabled_modes = false,
|
||||
-- Number of lines above cursor to show.
|
||||
above = 0,
|
||||
-- Number of lines below cursor to show.
|
||||
below = 0,
|
||||
-- Which elements to always show, ignoring anti conceal behavior. Values can either be
|
||||
-- booleans to fix the behavior or string lists representing modes where anti conceal
|
||||
-- behavior will be ignored. Valid values are:
|
||||
-- bullet
|
||||
-- callout
|
||||
-- check_icon, check_scope
|
||||
-- code_background, code_border, code_language
|
||||
-- dash
|
||||
-- head_background, head_border, head_icon
|
||||
-- indent
|
||||
-- link
|
||||
-- quote
|
||||
-- sign
|
||||
-- table_border
|
||||
-- virtual_lines
|
||||
ignore = {
|
||||
code_background = true,
|
||||
indent = true,
|
||||
sign = true,
|
||||
virtual_lines = true,
|
||||
},
|
||||
},
|
||||
padding = {
|
||||
-- Highlight to use when adding whitespace, should match background.
|
||||
highlight = "Normal",
|
||||
},
|
||||
latex = {
|
||||
-- Turn on / off latex rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render latex.
|
||||
render_modes = false,
|
||||
-- Executable used to convert latex formula to rendered unicode.
|
||||
converter = "latex2text",
|
||||
-- Highlight for latex blocks.
|
||||
highlight = "RenderMarkdownMath",
|
||||
-- Determines where latex formula is rendered relative to block.
|
||||
-- | above | above latex block |
|
||||
-- | below | below latex block |
|
||||
position = "above",
|
||||
-- Number of empty lines above latex blocks.
|
||||
top_pad = 0,
|
||||
-- Number of empty lines below latex blocks.
|
||||
bottom_pad = 0,
|
||||
},
|
||||
on = {
|
||||
-- Called when plugin initially attaches to a buffer.
|
||||
attach = function() end,
|
||||
-- Called before adding marks to the buffer for the first time.
|
||||
initial = function() end,
|
||||
-- Called after plugin renders a buffer.
|
||||
render = function() end,
|
||||
-- Called after plugin clears a buffer.
|
||||
clear = function() end,
|
||||
},
|
||||
completions = {
|
||||
-- Settings for blink.cmp completions source
|
||||
blink = { enabled = false },
|
||||
-- Settings for coq_nvim completions source
|
||||
coq = { enabled = false },
|
||||
-- Settings for in-process language server completions
|
||||
lsp = { enabled = false },
|
||||
filter = {
|
||||
callout = function()
|
||||
-- example to exclude obsidian callouts
|
||||
-- return value.category ~= 'obsidian'
|
||||
return true
|
||||
end,
|
||||
checkbox = function()
|
||||
return true
|
||||
end,
|
||||
},
|
||||
},
|
||||
heading = {
|
||||
-- Useful context to have when evaluating values.
|
||||
-- | level | the number of '#' in the heading marker |
|
||||
-- | sections | for each level how deeply nested the heading is |
|
||||
|
||||
-- Turn on / off heading icon & background rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render headings.
|
||||
render_modes = false,
|
||||
-- Turn on / off atx heading rendering.
|
||||
atx = true,
|
||||
-- Turn on / off setext heading rendering.
|
||||
setext = true,
|
||||
-- Turn on / off any sign column related rendering.
|
||||
sign = true,
|
||||
-- Replaces '#+' of 'atx_h._marker'.
|
||||
-- Output is evaluated depending on the type.
|
||||
-- | function | `value(context)` |
|
||||
-- | string[] | `cycle(value, context.level)` |
|
||||
icons = { " ", " ", " ", " ", " ", " " },
|
||||
-- Determines how icons fill the available space.
|
||||
-- | right | '#'s are concealed and icon is appended to right side |
|
||||
-- | inline | '#'s are concealed and icon is inlined on left side |
|
||||
-- | overlay | icon is left padded with spaces and inserted on left hiding any additional '#' |
|
||||
position = "overlay",
|
||||
-- Added to the sign column if enabled.
|
||||
-- Output is evaluated by `cycle(value, context.level)`.
|
||||
signs = { " " },
|
||||
-- Width of the heading background.
|
||||
-- | block | width of the heading text |
|
||||
-- | full | full width of the window |
|
||||
-- Can also be a list of the above values evaluated by `clamp(value, context.level)`.
|
||||
width = "full",
|
||||
-- Amount of margin to add to the left of headings.
|
||||
-- Margin available space is computed after accounting for padding.
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
-- Can also be a list of numbers evaluated by `clamp(value, context.level)`.
|
||||
left_margin = 0,
|
||||
-- Amount of padding to add to the left of headings.
|
||||
-- Output is evaluated using the same logic as 'left_margin'.
|
||||
left_pad = 0,
|
||||
-- Amount of padding to add to the right of headings when width is 'block'.
|
||||
-- Output is evaluated using the same logic as 'left_margin'.
|
||||
right_pad = 0,
|
||||
-- Minimum width to use for headings when width is 'block'.
|
||||
-- Can also be a list of integers evaluated by `clamp(value, context.level)`.
|
||||
min_width = 0,
|
||||
-- Determines if a border is added above and below headings.
|
||||
-- Can also be a list of booleans evaluated by `clamp(value, context.level)`.
|
||||
border = false,
|
||||
-- Always use virtual lines for heading borders instead of attempting to use empty lines.
|
||||
border_virtual = false,
|
||||
-- Highlight the start of the border using the foreground highlight.
|
||||
border_prefix = false,
|
||||
-- Used above heading for border.
|
||||
above = "▄",
|
||||
-- Used below heading for border.
|
||||
below = "▀",
|
||||
-- Highlight for the heading icon and extends through the entire line.
|
||||
-- Output is evaluated by `clamp(value, context.level)`.
|
||||
backgrounds = {
|
||||
"RenderMarkdownH1Bg",
|
||||
"RenderMarkdownH2Bg",
|
||||
"RenderMarkdownH3Bg",
|
||||
"RenderMarkdownH4Bg",
|
||||
"RenderMarkdownH5Bg",
|
||||
"RenderMarkdownH6Bg",
|
||||
},
|
||||
-- Highlight for the heading and sign icons.
|
||||
-- Output is evaluated using the same logic as 'backgrounds'.
|
||||
foregrounds = {
|
||||
"RenderMarkdownH1",
|
||||
"RenderMarkdownH2",
|
||||
"RenderMarkdownH3",
|
||||
"RenderMarkdownH4",
|
||||
"RenderMarkdownH5",
|
||||
"RenderMarkdownH6",
|
||||
},
|
||||
-- Define custom heading patterns which allow you to override various properties based on
|
||||
-- the contents of a heading.
|
||||
-- The key is for healthcheck and to allow users to change its values, value type below.
|
||||
-- | pattern | matched against the heading text @see :h lua-patterns |
|
||||
-- | icon | optional override for the icon |
|
||||
-- | background | optional override for the background |
|
||||
-- | foreground | optional override for the foreground |
|
||||
custom = {},
|
||||
},
|
||||
paragraph = {
|
||||
-- Useful context to have when evaluating values.
|
||||
-- | text | text value of the node |
|
||||
|
||||
-- Turn on / off paragraph rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render paragraphs.
|
||||
render_modes = false,
|
||||
-- Amount of margin to add to the left of paragraphs.
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
-- Output is evaluated depending on the type.
|
||||
-- | function | `value(context)` |
|
||||
-- | number | `value` |
|
||||
left_margin = 0,
|
||||
-- Amount of padding to add to the first line of each paragraph.
|
||||
-- Output is evaluated using the same logic as 'left_margin'.
|
||||
indent = 0,
|
||||
-- Minimum width to use for paragraphs.
|
||||
min_width = 0,
|
||||
},
|
||||
code = {
|
||||
-- Turn on / off code block & inline code rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render code blocks.
|
||||
render_modes = false,
|
||||
-- Turn on / off any sign column related rendering.
|
||||
sign = true,
|
||||
-- Determines how code blocks & inline code are rendered.
|
||||
-- | none | disables all rendering |
|
||||
-- | normal | background highlighting + padding |
|
||||
-- | language | language heading with icon + sign column |
|
||||
-- | full | normal + language |
|
||||
style = "full",
|
||||
-- Whether to conceal nodes at the top and bottom of code blocks.
|
||||
conceal_delimiters = true,
|
||||
-- Turn on / off any language heading related rendering.
|
||||
language = true,
|
||||
-- Determines where language icon is rendered.
|
||||
-- | right | right side of code block |
|
||||
-- | left | left side of code block |
|
||||
position = "left",
|
||||
-- Whether to include the language icon above code blocks.
|
||||
language_icon = true,
|
||||
-- Whether to include the language name above code blocks.
|
||||
language_name = true,
|
||||
-- Whether to include the language info above code blocks.
|
||||
language_info = true,
|
||||
-- Amount of padding to add around the language.
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
language_pad = 0,
|
||||
-- A list of language names for which background highlighting will be disabled.
|
||||
-- Likely because that language has background highlights itself.
|
||||
-- Use a boolean to make behavior apply to all languages.
|
||||
-- Borders above & below blocks will continue to be rendered.
|
||||
disable_background = { "diff" },
|
||||
-- Width of the code block background.
|
||||
-- | block | width of the code block |
|
||||
-- | full | full width of the window |
|
||||
width = "full",
|
||||
-- Amount of margin to add to the left of code blocks.
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
-- Margin available space is computed after accounting for padding.
|
||||
left_margin = 0,
|
||||
-- Amount of padding to add to the left of code blocks.
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
left_pad = 0,
|
||||
-- Amount of padding to add to the right of code blocks when width is 'block'.
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
right_pad = 0,
|
||||
-- Minimum width to use for code blocks when width is 'block'.
|
||||
min_width = 0,
|
||||
-- Determines how the top / bottom of code block are rendered.
|
||||
-- | none | do not render a border |
|
||||
-- | thick | use the same highlight as the code body |
|
||||
-- | thin | when lines are empty overlay the above & below icons |
|
||||
-- | hide | conceal lines unless language name or icon is added |
|
||||
border = "hide",
|
||||
-- Used above code blocks to fill remaining space around language.
|
||||
language_border = "█",
|
||||
-- Added to the left of language.
|
||||
language_left = "",
|
||||
-- Added to the right of language.
|
||||
language_right = "",
|
||||
-- Used above code blocks for thin border.
|
||||
above = "▄",
|
||||
-- Used below code blocks for thin border.
|
||||
below = "▀",
|
||||
-- Icon to add to the left of inline code.
|
||||
inline_left = "",
|
||||
-- Icon to add to the right of inline code.
|
||||
inline_right = "",
|
||||
-- Padding to add to the left & right of inline code.
|
||||
inline_pad = 0,
|
||||
-- Highlight for code blocks.
|
||||
highlight = "RenderMarkdownCode",
|
||||
-- Highlight for code info section, after the language.
|
||||
highlight_info = "RenderMarkdownCodeInfo",
|
||||
-- Highlight for language, overrides icon provider value.
|
||||
highlight_language = nil,
|
||||
-- Highlight for border, use false to add no highlight.
|
||||
highlight_border = "RenderMarkdownCodeBorder",
|
||||
-- Highlight for language, used if icon provider does not have a value.
|
||||
highlight_fallback = "RenderMarkdownCodeFallback",
|
||||
-- Highlight for inline code.
|
||||
highlight_inline = "RenderMarkdownCodeInline",
|
||||
},
|
||||
dash = {
|
||||
-- Turn on / off thematic break rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render dash.
|
||||
render_modes = false,
|
||||
-- Replaces '---'|'***'|'___'|'* * *' of 'thematic_break'.
|
||||
-- The icon gets repeated across the window's width.
|
||||
icon = "─",
|
||||
-- Width of the generated line.
|
||||
-- | <number> | a hard coded width value |
|
||||
-- | full | full width of the window |
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
width = "full",
|
||||
-- Amount of margin to add to the left of dash.
|
||||
-- If a float < 1 is provided it is treated as a percentage of available window space.
|
||||
left_margin = 0,
|
||||
-- Highlight for the whole line generated from the icon.
|
||||
highlight = "RenderMarkdownDash",
|
||||
},
|
||||
document = {
|
||||
-- Turn on / off document rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render document.
|
||||
render_modes = false,
|
||||
-- Ability to conceal arbitrary ranges of text based on lua patterns, @see :h lua-patterns.
|
||||
-- Relies entirely on user to set patterns that handle their edge cases.
|
||||
conceal = {
|
||||
-- Matched ranges will be concealed using character level conceal.
|
||||
char_patterns = {},
|
||||
-- Matched ranges will be concealed using line level conceal.
|
||||
line_patterns = {},
|
||||
},
|
||||
},
|
||||
bullet = {
|
||||
-- Useful context to have when evaluating values.
|
||||
-- | level | how deeply nested the list is, 1-indexed |
|
||||
-- | index | how far down the item is at that level, 1-indexed |
|
||||
-- | value | text value of the marker node |
|
||||
|
||||
-- Turn on / off list bullet rendering
|
||||
enabled = true,
|
||||
-- Additional modes to render list bullets
|
||||
render_modes = false,
|
||||
-- Replaces '-'|'+'|'*' of 'list_item'.
|
||||
-- If the item is a 'checkbox' a conceal is used to hide the bullet instead.
|
||||
-- Output is evaluated depending on the type.
|
||||
-- | function | `value(context)` |
|
||||
-- | string | `value` |
|
||||
-- | string[] | `cycle(value, context.level)` |
|
||||
-- | string[][] | `clamp(cycle(value, context.level), context.index)` |
|
||||
icons = { "●", "○", "◆", "◇" },
|
||||
-- Replaces 'n.'|'n)' of 'list_item'.
|
||||
-- Output is evaluated using the same logic as 'icons'.
|
||||
ordered_icons = function(ctx)
|
||||
local value = vim.trim(ctx.value)
|
||||
local index = tonumber(value:sub(1, #value - 1))
|
||||
return ("%d."):format(index > 1 and index or ctx.index)
|
||||
end,
|
||||
-- Padding to add to the left of bullet point.
|
||||
-- Output is evaluated depending on the type.
|
||||
-- | function | `value(context)` |
|
||||
-- | integer | `value` |
|
||||
left_pad = 0,
|
||||
-- Padding to add to the right of bullet point.
|
||||
-- Output is evaluated using the same logic as 'left_pad'.
|
||||
right_pad = 0,
|
||||
-- Highlight for the bullet icon.
|
||||
-- Output is evaluated using the same logic as 'icons'.
|
||||
highlight = "RenderMarkdownBullet",
|
||||
-- Highlight for item associated with the bullet point.
|
||||
-- Output is evaluated using the same logic as 'icons'.
|
||||
scope_highlight = {},
|
||||
},
|
||||
checkbox = {
|
||||
-- Checkboxes are a special instance of a 'list_item' that start with a 'shortcut_link'.
|
||||
-- There are two special states for unchecked & checked defined in the markdown grammar.
|
||||
|
||||
-- Turn on / off checkbox state rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render checkboxes.
|
||||
render_modes = false,
|
||||
-- Render the bullet point before the checkbox.
|
||||
bullet = false,
|
||||
-- Padding to add to the right of checkboxes.
|
||||
right_pad = 1,
|
||||
unchecked = {
|
||||
-- Replaces '[ ]' of 'task_list_marker_unchecked'.
|
||||
icon = " ",
|
||||
-- Highlight for the unchecked icon.
|
||||
highlight = "RenderMarkdownUnchecked",
|
||||
-- Highlight for item associated with unchecked checkbox.
|
||||
scope_highlight = nil,
|
||||
},
|
||||
checked = {
|
||||
-- Replaces '[x]' of 'task_list_marker_checked'.
|
||||
icon = " ",
|
||||
-- Highlight for the checked icon.
|
||||
highlight = "RenderMarkdownChecked",
|
||||
-- Highlight for item associated with checked checkbox.
|
||||
scope_highlight = nil,
|
||||
},
|
||||
-- Define custom checkbox states, more involved, not part of the markdown grammar.
|
||||
-- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks.
|
||||
-- The key is for healthcheck and to allow users to change its values, value type below.
|
||||
-- | raw | matched against the raw text of a 'shortcut_link' |
|
||||
-- | rendered | replaces the 'raw' value when rendering |
|
||||
-- | highlight | highlight for the 'rendered' icon |
|
||||
-- | scope_highlight | optional highlight for item associated with custom checkbox |
|
||||
-- stylua: ignore
|
||||
custom = {
|
||||
todo = { raw = '[-]', rendered = ' ', highlight = 'RenderMarkdownTodo', scope_highlight = nil },
|
||||
},
|
||||
},
|
||||
quote = {
|
||||
-- Turn on / off block quote & callout rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render quotes.
|
||||
render_modes = false,
|
||||
-- Replaces '>' of 'block_quote'.
|
||||
icon = "▋",
|
||||
-- Whether to repeat icon on wrapped lines. Requires neovim >= 0.10. This will obscure text
|
||||
-- if incorrectly configured with :h 'showbreak', :h 'breakindent' and :h 'breakindentopt'.
|
||||
-- A combination of these that is likely to work follows.
|
||||
-- | showbreak | ' ' (2 spaces) |
|
||||
-- | breakindent | true |
|
||||
-- | breakindentopt | '' (empty string) |
|
||||
-- These are not validated by this plugin. If you want to avoid adding these to your main
|
||||
-- configuration then set them in win_options for this plugin.
|
||||
repeat_linebreak = false,
|
||||
-- Highlight for the quote icon.
|
||||
-- If a list is provided output is evaluated by `cycle(value, level)`.
|
||||
highlight = {
|
||||
"RenderMarkdownQuote1",
|
||||
"RenderMarkdownQuote2",
|
||||
"RenderMarkdownQuote3",
|
||||
"RenderMarkdownQuote4",
|
||||
"RenderMarkdownQuote5",
|
||||
"RenderMarkdownQuote6",
|
||||
},
|
||||
},
|
||||
pipe_table = {
|
||||
-- Turn on / off pipe table rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render pipe tables.
|
||||
render_modes = false,
|
||||
-- Pre configured settings largely for setting table border easier.
|
||||
-- | heavy | use thicker border characters |
|
||||
-- | double | use double line border characters |
|
||||
-- | round | use round border corners |
|
||||
-- | none | does nothing |
|
||||
preset = "none",
|
||||
-- Determines how the table as a whole is rendered.
|
||||
-- | none | disables all rendering |
|
||||
-- | normal | applies the 'cell' style rendering to each row of the table |
|
||||
-- | full | normal + a top & bottom line that fill out the table when lengths match |
|
||||
style = "full",
|
||||
-- Determines how individual cells of a table are rendered.
|
||||
-- | overlay | writes completely over the table, removing conceal behavior and highlights |
|
||||
-- | raw | replaces only the '|' characters in each row, leaving the cells unmodified |
|
||||
-- | padded | raw + cells are padded to maximum visual width for each column |
|
||||
-- | trimmed | padded except empty space is subtracted from visual width calculation |
|
||||
cell = "padded",
|
||||
-- Amount of space to put between cell contents and border.
|
||||
padding = 1,
|
||||
-- Minimum column width to use for padded or trimmed cell.
|
||||
min_width = 0,
|
||||
-- Characters used to replace table border.
|
||||
-- Correspond to top(3), delimiter(3), bottom(3), vertical, & horizontal.
|
||||
-- stylua: ignore
|
||||
border = {
|
||||
'┌', '┬', '┐',
|
||||
'├', '┼', '┤',
|
||||
'└', '┴', '┘',
|
||||
'│', '─',
|
||||
},
|
||||
-- Always use virtual lines for table borders instead of attempting to use empty lines.
|
||||
-- Will be automatically enabled if indentation module is enabled.
|
||||
border_virtual = false,
|
||||
-- Gets placed in delimiter row for each column, position is based on alignment.
|
||||
alignment_indicator = "━",
|
||||
-- Highlight for table heading, delimiter, and the line above.
|
||||
head = "RenderMarkdownTableHead",
|
||||
-- Highlight for everything else, main table rows and the line below.
|
||||
row = "RenderMarkdownTableRow",
|
||||
-- Highlight for inline padding used to add back concealed space.
|
||||
filler = "RenderMarkdownTableFill",
|
||||
},
|
||||
callout = {
|
||||
-- Callouts are a special instance of a 'block_quote' that start with a 'shortcut_link'.
|
||||
-- The key is for healthcheck and to allow users to change its values, value type below.
|
||||
-- | raw | matched against the raw text of a 'shortcut_link', case insensitive |
|
||||
-- | rendered | replaces the 'raw' value when rendering |
|
||||
-- | highlight | highlight for the 'rendered' text and quote markers |
|
||||
-- | quote_icon | optional override for quote.icon value for individual callout |
|
||||
-- | category | optional metadata useful for filtering |
|
||||
|
||||
note = {
|
||||
raw = "[!NOTE]",
|
||||
rendered = " Note",
|
||||
highlight = "RenderMarkdownInfo",
|
||||
category = "github",
|
||||
},
|
||||
tip = {
|
||||
raw = "[!TIP]",
|
||||
rendered = " Tip",
|
||||
highlight = "RenderMarkdownSuccess",
|
||||
category = "github",
|
||||
},
|
||||
important = {
|
||||
raw = "[!IMPORTANT]",
|
||||
rendered = " Important",
|
||||
highlight = "RenderMarkdownHint",
|
||||
category = "github",
|
||||
},
|
||||
warning = {
|
||||
raw = "[!WARNING]",
|
||||
rendered = " Warning",
|
||||
highlight = "RenderMarkdownWarn",
|
||||
category = "github",
|
||||
},
|
||||
caution = {
|
||||
raw = "[!CAUTION]",
|
||||
rendered = " Caution",
|
||||
highlight = "RenderMarkdownError",
|
||||
category = "github",
|
||||
},
|
||||
-- Obsidian: https://help.obsidian.md/Editing+and+formatting/Callouts
|
||||
abstract = {
|
||||
raw = "[!ABSTRACT]",
|
||||
rendered = " Abstract",
|
||||
highlight = "RenderMarkdownInfo",
|
||||
category = "obsidian",
|
||||
},
|
||||
summary = {
|
||||
raw = "[!SUMMARY]",
|
||||
rendered = " Summary",
|
||||
highlight = "RenderMarkdownInfo",
|
||||
category = "obsidian",
|
||||
},
|
||||
tldr = {
|
||||
raw = "[!TLDR]",
|
||||
rendered = " Tldr",
|
||||
highlight = "RenderMarkdownInfo",
|
||||
category = "obsidian",
|
||||
},
|
||||
info = {
|
||||
raw = "[!INFO]",
|
||||
rendered = " Info",
|
||||
highlight = "RenderMarkdownInfo",
|
||||
category = "obsidian",
|
||||
},
|
||||
todo = {
|
||||
raw = "[!TODO]",
|
||||
rendered = " Todo",
|
||||
highlight = "RenderMarkdownInfo",
|
||||
category = "obsidian",
|
||||
},
|
||||
hint = {
|
||||
raw = "[!HINT]",
|
||||
rendered = " Hint",
|
||||
highlight = "RenderMarkdownSuccess",
|
||||
category = "obsidian",
|
||||
},
|
||||
success = {
|
||||
raw = "[!SUCCESS]",
|
||||
rendered = " Success",
|
||||
highlight = "RenderMarkdownSuccess",
|
||||
category = "obsidian",
|
||||
},
|
||||
check = {
|
||||
raw = "[!CHECK]",
|
||||
rendered = " Check",
|
||||
highlight = "RenderMarkdownSuccess",
|
||||
category = "obsidian",
|
||||
},
|
||||
done = {
|
||||
raw = "[!DONE]",
|
||||
rendered = " Done",
|
||||
highlight = "RenderMarkdownSuccess",
|
||||
category = "obsidian",
|
||||
},
|
||||
question = {
|
||||
raw = "[!QUESTION]",
|
||||
rendered = " Question",
|
||||
highlight = "RenderMarkdownWarn",
|
||||
category = "obsidian",
|
||||
},
|
||||
help = {
|
||||
raw = "[!HELP]",
|
||||
rendered = " Help",
|
||||
highlight = "RenderMarkdownWarn",
|
||||
category = "obsidian",
|
||||
},
|
||||
faq = {
|
||||
raw = "[!FAQ]",
|
||||
rendered = " Faq",
|
||||
highlight = "RenderMarkdownWarn",
|
||||
category = "obsidian",
|
||||
},
|
||||
attention = {
|
||||
raw = "[!ATTENTION]",
|
||||
rendered = " Attention",
|
||||
highlight = "RenderMarkdownWarn",
|
||||
category = "obsidian",
|
||||
},
|
||||
failure = {
|
||||
raw = "[!FAILURE]",
|
||||
rendered = " Failure",
|
||||
highlight = "RenderMarkdownError",
|
||||
category = "obsidian",
|
||||
},
|
||||
fail = {
|
||||
raw = "[!FAIL]",
|
||||
rendered = " Fail",
|
||||
highlight = "RenderMarkdownError",
|
||||
category = "obsidian",
|
||||
},
|
||||
missing = {
|
||||
raw = "[!MISSING]",
|
||||
rendered = " Missing",
|
||||
highlight = "RenderMarkdownError",
|
||||
category = "obsidian",
|
||||
},
|
||||
danger = {
|
||||
raw = "[!DANGER]",
|
||||
rendered = " Danger",
|
||||
highlight = "RenderMarkdownError",
|
||||
category = "obsidian",
|
||||
},
|
||||
error = {
|
||||
raw = "[!ERROR]",
|
||||
rendered = " Error",
|
||||
highlight = "RenderMarkdownError",
|
||||
category = "obsidian",
|
||||
},
|
||||
bug = {
|
||||
raw = "[!BUG]",
|
||||
rendered = " Bug",
|
||||
highlight = "RenderMarkdownError",
|
||||
category = "obsidian",
|
||||
},
|
||||
example = {
|
||||
raw = "[!EXAMPLE]",
|
||||
rendered = " Example",
|
||||
highlight = "RenderMarkdownHint",
|
||||
category = "obsidian",
|
||||
},
|
||||
quote = {
|
||||
raw = "[!QUOTE]",
|
||||
rendered = " Quote",
|
||||
highlight = "RenderMarkdownQuote",
|
||||
category = "obsidian",
|
||||
},
|
||||
cite = {
|
||||
raw = "[!CITE]",
|
||||
rendered = " Cite",
|
||||
highlight = "RenderMarkdownQuote",
|
||||
category = "obsidian",
|
||||
},
|
||||
},
|
||||
link = {
|
||||
-- Turn on / off inline link icon rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render links.
|
||||
render_modes = false,
|
||||
-- How to handle footnote links, start with a '^'.
|
||||
footnote = {
|
||||
-- Turn on / off footnote rendering.
|
||||
enabled = true,
|
||||
-- Replace value with superscript equivalent.
|
||||
superscript = true,
|
||||
-- Added before link content.
|
||||
prefix = "",
|
||||
-- Added after link content.
|
||||
suffix = "",
|
||||
},
|
||||
-- Inlined with 'image' elements.
|
||||
image = " ",
|
||||
-- Inlined with 'email_autolink' elements.
|
||||
email = " ",
|
||||
-- Fallback icon for 'inline_link' and 'uri_autolink' elements.
|
||||
hyperlink = " ",
|
||||
-- Applies to the inlined icon as a fallback.
|
||||
highlight = "RenderMarkdownLink",
|
||||
-- Applies to WikiLink elements.
|
||||
wiki = {
|
||||
icon = " ",
|
||||
body = function()
|
||||
return nil
|
||||
end,
|
||||
highlight = "RenderMarkdownWikiLink",
|
||||
},
|
||||
-- Define custom destination patterns so icons can quickly inform you of what a link
|
||||
-- contains. Applies to 'inline_link', 'uri_autolink', and wikilink nodes. When multiple
|
||||
-- patterns match a link the one with the longer pattern is used.
|
||||
-- The key is for healthcheck and to allow users to change its values, value type below.
|
||||
-- | pattern | matched against the destination text |
|
||||
-- | icon | gets inlined before the link text |
|
||||
-- | kind | optional determines how pattern is checked |
|
||||
-- | | pattern | @see :h lua-patterns, is the default if not set |
|
||||
-- | | suffix | @see :h vim.endswith() |
|
||||
-- | priority | optional used when multiple match, uses pattern length if empty |
|
||||
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
|
||||
custom = {
|
||||
web = { pattern = "^http", icon = " " },
|
||||
discord = { pattern = "discord%.com", icon = " " },
|
||||
github = { pattern = "github%.com", icon = " " },
|
||||
gitlab = { pattern = "gitlab%.com", icon = " " },
|
||||
google = { pattern = "google%.com", icon = " " },
|
||||
neovim = { pattern = "neovim%.io", icon = " " },
|
||||
reddit = { pattern = "reddit%.com", icon = " " },
|
||||
stackoverflow = { pattern = "stackoverflow%.com", icon = " " },
|
||||
wikipedia = { pattern = "wikipedia%.org", icon = " " },
|
||||
youtube = { pattern = "youtube%.com", icon = " " },
|
||||
},
|
||||
},
|
||||
sign = {
|
||||
-- Turn on / off sign rendering.
|
||||
enabled = true,
|
||||
-- Applies to background of sign text.
|
||||
highlight = "RenderMarkdownSign",
|
||||
},
|
||||
inline_highlight = {
|
||||
-- Mimics Obsidian inline highlights when content is surrounded by double equals.
|
||||
-- The equals on both ends are concealed and the inner content is highlighted.
|
||||
|
||||
-- Turn on / off inline highlight rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render inline highlights.
|
||||
render_modes = false,
|
||||
-- Applies to background of surrounded text.
|
||||
highlight = "RenderMarkdownInlineHighlight",
|
||||
},
|
||||
indent = {
|
||||
-- Mimic org-indent-mode behavior by indenting everything under a heading based on the
|
||||
-- level of the heading. Indenting starts from level 2 headings onward by default.
|
||||
|
||||
-- Turn on / off org-indent-mode.
|
||||
enabled = false,
|
||||
-- Additional modes to render indents.
|
||||
render_modes = false,
|
||||
-- Amount of additional padding added for each heading level.
|
||||
per_level = 2,
|
||||
-- Heading levels <= this value will not be indented.
|
||||
-- Use 0 to begin indenting from the very first level.
|
||||
skip_level = 1,
|
||||
-- Do not indent heading titles, only the body.
|
||||
skip_heading = false,
|
||||
-- Prefix added when indenting, one per level.
|
||||
icon = "▎",
|
||||
-- Priority to assign to extmarks.
|
||||
priority = 0,
|
||||
-- Applied to icon.
|
||||
highlight = "RenderMarkdownIndent",
|
||||
},
|
||||
html = {
|
||||
-- Turn on / off all HTML rendering.
|
||||
enabled = true,
|
||||
-- Additional modes to render HTML.
|
||||
render_modes = false,
|
||||
comment = {
|
||||
-- Turn on / off HTML comment concealing.
|
||||
conceal = true,
|
||||
-- Optional text to inline before the concealed comment.
|
||||
text = nil,
|
||||
-- Highlight for the inlined text.
|
||||
highlight = "RenderMarkdownHtmlComment",
|
||||
},
|
||||
-- HTML tags whose start and end will be hidden and icon shown.
|
||||
-- The key is matched against the tag name, value type below.
|
||||
-- | icon | gets inlined at the start |
|
||||
-- | highlight | highlight for the icon |
|
||||
tag = {},
|
||||
},
|
||||
win_options = {
|
||||
-- Window options to use that change between rendered and raw view.
|
||||
|
||||
-- @see :h 'conceallevel'
|
||||
conceallevel = {
|
||||
-- Used when not being rendered, get user setting.
|
||||
default = vim.o.conceallevel,
|
||||
-- Used when being rendered, concealed text is completely hidden.
|
||||
rendered = 3,
|
||||
},
|
||||
-- @see :h 'concealcursor'
|
||||
concealcursor = {
|
||||
-- Used when not being rendered, get user setting.
|
||||
default = vim.o.concealcursor,
|
||||
-- Used when being rendered, show concealed text in all modes.
|
||||
rendered = "",
|
||||
},
|
||||
},
|
||||
overrides = {
|
||||
-- More granular configuration mechanism, allows different aspects of buffers to have their own
|
||||
-- behavior. Values default to the top level configuration if no override is provided. Supports
|
||||
-- the following fields:
|
||||
-- enabled, max_file_size, debounce, render_modes, anti_conceal, padding, heading, paragraph,
|
||||
-- code, dash, bullet, checkbox, quote, pipe_table, callout, link, sign, indent, latex, html,
|
||||
-- win_options
|
||||
|
||||
-- Override for different buflisted values, @see :h 'buflisted'.
|
||||
buflisted = {},
|
||||
-- Override for different buftype values, @see :h 'buftype'.
|
||||
buftype = {
|
||||
nofile = {
|
||||
render_modes = true,
|
||||
padding = { highlight = "NormalFloat" },
|
||||
sign = { enabled = false },
|
||||
},
|
||||
},
|
||||
-- Override for different filetype values, @see :h 'filetype'.
|
||||
filetype = {},
|
||||
},
|
||||
custom_handlers = {
|
||||
-- Mapping from treesitter language to user defined handlers.
|
||||
-- @see [Custom Handlers](doc/custom-handlers.md)
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
require "nvchad.mappings"
|
||||
|
||||
-- add yours here
|
||||
|
||||
local map = vim.keymap.set
|
||||
|
||||
map("n", "gd", vim.lsp.buf.definition, { desc = "Go to definition" })
|
||||
map("n", "gD", "<cmd>Telescope lsp_definitions<CR>", { desc = "Go to Definitions" })
|
||||
map("n", "grr", "<cmd>Telescope lsp_references<CR>", { desc = "Go to references" })
|
||||
map("n", "<leader>da", ":lua vim.lsp.buf.code_action()<cr>", { desc = "Code actions", noremap = true, silent = true })
|
||||
map("n", "<leader>dh", ":lua vim.diagnostic.open_float()<CR>", { desc = "Show diagnostics" })
|
||||
map("n", "<leader>dj", function()
|
||||
vim.diagnostic.jump { count = 1, float = true }
|
||||
end, { desc = "Go to next" })
|
||||
map("n", "<leader>dk", function()
|
||||
vim.diagnostic.jump { count = -1, float = true }
|
||||
end, { desc = "Go to previous" })
|
||||
-- Telescope
|
||||
map("n", "<leader>fr", ":Telescope resume<CR>", { desc = "Resume last search" })
|
||||
map("n", "<leader>fs", ":Telescope grep_string<CR>", { desc = "Find selected string" })
|
||||
map("n", "<leader>fk", ":Telescope keymaps<CR>", { desc = "Find keymaps" })
|
||||
map("n", "<leader>fd", ":Telescope diagnostics<CR>", { desc = "Diagnostics" })
|
||||
-- Remaps
|
||||
map({ "n", "v" }, "x", '"_x', { desc = "Delete char without yanking" })
|
||||
map({ "n", "v" }, "c", '"_c', { desc = "Change without yanking" })
|
||||
@@ -0,0 +1,6 @@
|
||||
require "nvchad.options"
|
||||
|
||||
-- add yours here!
|
||||
|
||||
-- local o = vim.o
|
||||
-- o.cursorlineopt ='both' -- to enable cursorline!
|
||||
@@ -0,0 +1,87 @@
|
||||
return {
|
||||
{
|
||||
"stevearc/conform.nvim",
|
||||
event = "BufWritePre", -- uncomment for format on save
|
||||
opts = require "configs.conform",
|
||||
},
|
||||
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
config = function()
|
||||
require "configs.lspconfig"
|
||||
end,
|
||||
},
|
||||
|
||||
{
|
||||
"nvim-treesitter/nvim-treesitter",
|
||||
branch = "main",
|
||||
opts = {
|
||||
ensure_installed = {
|
||||
"vim",
|
||||
"vimdoc",
|
||||
"lua",
|
||||
"luadoc",
|
||||
"printf",
|
||||
"html",
|
||||
"css",
|
||||
"typescript",
|
||||
"javascript",
|
||||
"markdown",
|
||||
"scss",
|
||||
"svelte",
|
||||
"typst",
|
||||
"vue",
|
||||
"regex",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"MeanderingProgrammer/render-markdown.nvim",
|
||||
ft = { "markdown", "gitcommit" },
|
||||
opts = function()
|
||||
return require "configs.render-markdown"
|
||||
end,
|
||||
},
|
||||
|
||||
-- snacks.indent (below) draws the indent guides — disable NvChad's indent-blankline
|
||||
-- so they don't render doubled
|
||||
{ "lukas-reineke/indent-blankline.nvim", enabled = false },
|
||||
|
||||
{
|
||||
"folke/snacks.nvim",
|
||||
priority = 1000,
|
||||
lazy = false,
|
||||
---@type snacks.Config
|
||||
opts = {
|
||||
-- your configuration comes here
|
||||
-- or leave it empty to use the default settings
|
||||
-- refer to the configuration section below
|
||||
bigfile = { enabled = false },
|
||||
dashboard = { enabled = false },
|
||||
explorer = { enabled = true },
|
||||
indent = { enabled = true },
|
||||
input = { enabled = true },
|
||||
picker = { enabled = true },
|
||||
notifier = { enabled = true },
|
||||
quickfile = { enabled = true },
|
||||
scope = { enabled = true },
|
||||
scroll = { enabled = true },
|
||||
statuscolumn = { enabled = true },
|
||||
words = { enabled = true },
|
||||
},
|
||||
},
|
||||
|
||||
-- These are some examples, uncomment them if you want to see them work!
|
||||
--
|
||||
-- {
|
||||
-- "nvim-treesitter/nvim-treesitter",
|
||||
-- opts = {
|
||||
-- ensure_installed = {
|
||||
-- "vim", "lua", "vimdoc",
|
||||
-- "html", "css"
|
||||
-- },
|
||||
-- },
|
||||
-- },
|
||||
--
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"plugin": [
|
||||
"opencode-openai-codex-auth"
|
||||
],
|
||||
"provider": {
|
||||
"openai": {
|
||||
"options": {
|
||||
"reasoningEffort": "medium",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium",
|
||||
"include": [
|
||||
"reasoning.encrypted_content"
|
||||
],
|
||||
"store": false
|
||||
},
|
||||
"models": {
|
||||
"gpt-5.2": {
|
||||
"name": "GPT 5.2 (OAuth)",
|
||||
"limit": {
|
||||
"context": 272000,
|
||||
"output": 128000
|
||||
},
|
||||
"modalities": {
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"output": [
|
||||
"text"
|
||||
]
|
||||
},
|
||||
"variants": {
|
||||
"none": {
|
||||
"reasoningEffort": "none",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"low": {
|
||||
"reasoningEffort": "low",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"medium": {
|
||||
"reasoningEffort": "medium",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"high": {
|
||||
"reasoningEffort": "high",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"xhigh": {
|
||||
"reasoningEffort": "xhigh",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gpt-5.2-codex": {
|
||||
"name": "GPT 5.2 Codex (OAuth)",
|
||||
"limit": {
|
||||
"context": 272000,
|
||||
"output": 128000
|
||||
},
|
||||
"modalities": {
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"output": [
|
||||
"text"
|
||||
]
|
||||
},
|
||||
"variants": {
|
||||
"low": {
|
||||
"reasoningEffort": "low",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"medium": {
|
||||
"reasoningEffort": "medium",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"high": {
|
||||
"reasoningEffort": "high",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"xhigh": {
|
||||
"reasoningEffort": "xhigh",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gpt-5.1-codex-max": {
|
||||
"name": "GPT 5.1 Codex Max (OAuth)",
|
||||
"limit": {
|
||||
"context": 272000,
|
||||
"output": 128000
|
||||
},
|
||||
"modalities": {
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"output": [
|
||||
"text"
|
||||
]
|
||||
},
|
||||
"variants": {
|
||||
"low": {
|
||||
"reasoningEffort": "low",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"medium": {
|
||||
"reasoningEffort": "medium",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"high": {
|
||||
"reasoningEffort": "high",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"xhigh": {
|
||||
"reasoningEffort": "xhigh",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gpt-5.1-codex": {
|
||||
"name": "GPT 5.1 Codex (OAuth)",
|
||||
"limit": {
|
||||
"context": 272000,
|
||||
"output": 128000
|
||||
},
|
||||
"modalities": {
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"output": [
|
||||
"text"
|
||||
]
|
||||
},
|
||||
"variants": {
|
||||
"low": {
|
||||
"reasoningEffort": "low",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"medium": {
|
||||
"reasoningEffort": "medium",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"high": {
|
||||
"reasoningEffort": "high",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gpt-5.1-codex-mini": {
|
||||
"name": "GPT 5.1 Codex Mini (OAuth)",
|
||||
"limit": {
|
||||
"context": 272000,
|
||||
"output": 128000
|
||||
},
|
||||
"modalities": {
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"output": [
|
||||
"text"
|
||||
]
|
||||
},
|
||||
"variants": {
|
||||
"medium": {
|
||||
"reasoningEffort": "medium",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"high": {
|
||||
"reasoningEffort": "high",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gpt-5.1": {
|
||||
"name": "GPT 5.1 (OAuth)",
|
||||
"limit": {
|
||||
"context": 272000,
|
||||
"output": 128000
|
||||
},
|
||||
"modalities": {
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"output": [
|
||||
"text"
|
||||
]
|
||||
},
|
||||
"variants": {
|
||||
"none": {
|
||||
"reasoningEffort": "none",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"low": {
|
||||
"reasoningEffort": "low",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "low"
|
||||
},
|
||||
"medium": {
|
||||
"reasoningEffort": "medium",
|
||||
"reasoningSummary": "auto",
|
||||
"textVerbosity": "medium"
|
||||
},
|
||||
"high": {
|
||||
"reasoningEffort": "high",
|
||||
"reasoningSummary": "detailed",
|
||||
"textVerbosity": "high"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
||||
"small_model": "llama.cpp/gemma-4-E4B-it-UD-Q8_K_XL",
|
||||
"instructions": ["CLAUDE.md", "AGENTS.md"],
|
||||
"share": "disabled",
|
||||
"autoupdate": "notify",
|
||||
"disabled_providers": [
|
||||
"gemini",
|
||||
"anthropic",
|
||||
"groq",
|
||||
"openrouter",
|
||||
"opencode"
|
||||
],
|
||||
"permission": {
|
||||
"edit": "deny",
|
||||
"webfetch": "ask",
|
||||
"websearch": "ask",
|
||||
"external_directory": "ask",
|
||||
"read": {
|
||||
"*": "allow",
|
||||
"**/.env*": "deny",
|
||||
"**/*.env": "deny",
|
||||
"**/*.pem": "deny",
|
||||
"**/*.key": "deny",
|
||||
"**/*.p12": "deny",
|
||||
"**/*.pfx": "deny",
|
||||
"**/*.keystore": "deny",
|
||||
"**/id_rsa*": "deny",
|
||||
"**/.ssh/**": "deny",
|
||||
"**/.aws/**": "deny",
|
||||
"**/.npmrc": "deny",
|
||||
"**/.netrc": "deny"
|
||||
},
|
||||
"bash": {
|
||||
"*": "ask",
|
||||
|
||||
"ls *": "allow",
|
||||
"cat *": "allow",
|
||||
"grep *": "allow",
|
||||
"rg *": "allow",
|
||||
"find *": "allow",
|
||||
"fd *": "allow",
|
||||
"which *": "allow",
|
||||
"file *": "allow",
|
||||
"stat *": "allow",
|
||||
"wc *": "allow",
|
||||
"tree *": "allow",
|
||||
"diff *": "allow",
|
||||
"sort *": "allow",
|
||||
"uniq *": "allow",
|
||||
"echo *": "ask",
|
||||
"pwd": "allow",
|
||||
"date": "allow",
|
||||
"whoami": "allow",
|
||||
"jq *": "allow",
|
||||
"tsc *": "allow",
|
||||
"mkdir *": "ask",
|
||||
"touch *": "ask",
|
||||
|
||||
"git *": "ask",
|
||||
"git status": "allow",
|
||||
"git status *": "allow",
|
||||
"git diff": "allow",
|
||||
"git diff *": "allow",
|
||||
"git log": "allow",
|
||||
"git log *": "allow",
|
||||
"git show *": "allow",
|
||||
"git branch": "allow",
|
||||
"git remote -v": "allow",
|
||||
|
||||
"npm *": "ask",
|
||||
"pnpm *": "ask",
|
||||
"npx *": "ask",
|
||||
"npm list": "allow",
|
||||
"npm help": "allow",
|
||||
"npm version": "allow",
|
||||
"pnpm list": "allow",
|
||||
"pnpm help": "allow",
|
||||
"npx --version": "allow",
|
||||
|
||||
"curl *": "ask",
|
||||
"wget *": "ask",
|
||||
|
||||
"rm *": "deny",
|
||||
"rmdir *": "deny",
|
||||
"dd *": "deny",
|
||||
"mkfs*": "deny",
|
||||
"shred *": "deny",
|
||||
"chmod -R *": "deny",
|
||||
"sudo *": "deny",
|
||||
"doas *": "deny",
|
||||
|
||||
"npm install*": "deny",
|
||||
"npm i": "deny",
|
||||
"npm i *": "deny",
|
||||
"npm ci*": "deny",
|
||||
"pnpm install*": "deny",
|
||||
"pnpm i": "deny",
|
||||
"pnpm i *": "deny",
|
||||
"pnpm add*": "deny",
|
||||
"yarn add*": "deny",
|
||||
"yarn install*": "deny",
|
||||
"pip install*": "deny",
|
||||
"pip3 install*": "deny",
|
||||
"pipx install*": "deny",
|
||||
"cargo install*": "deny",
|
||||
"go install*": "deny",
|
||||
"gem install*": "deny",
|
||||
"brew install*": "deny",
|
||||
|
||||
"pacman *": "deny",
|
||||
"yay *": "deny",
|
||||
"apt *": "deny",
|
||||
"apt-get *": "deny",
|
||||
"dnf *": "deny",
|
||||
|
||||
"cat .env*": "deny",
|
||||
"cat *.env": "deny",
|
||||
"cat *.pem": "deny",
|
||||
"cat *.key": "deny",
|
||||
"cat *id_rsa*": "deny",
|
||||
"cat *secret*": "deny",
|
||||
"cat *credential*": "deny",
|
||||
"cat ~/.ssh/*": "deny",
|
||||
"cat ~/.aws/*": "deny",
|
||||
"grep .env*": "deny",
|
||||
"grep * .env*": "deny"
|
||||
}
|
||||
},
|
||||
"provider": {
|
||||
"duskadiy": {
|
||||
"npm": "@ai-sdk/openai-compatible",
|
||||
"name": "DuskaDIY",
|
||||
"options": {
|
||||
"baseURL": "https://llm.duskadiy.com/api/v1"
|
||||
},
|
||||
"models": {
|
||||
"Qwen3-Coder-30B-Instruct-UD-Q3_K_XL": { "name": "Qwen3 Coder 30B · 32k — main agent coder (remote)", "limit": { "context": 32768, "output": 4096 } },
|
||||
"Qwen3-Coder-Next-UD-IQ3_XXS": { "name": "Qwen3 Coder Next 80B · 128k — long sessions (remote)", "limit": { "context": 131072, "output": 16384 } },
|
||||
"Qwen3.6-35B-A3B-MTP-UD-IQ3_XXS": { "name": "Qwen3.6 35B · 24k · vision — daily driver (remote)", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||
"Qwen3.6-35B-A3B-Thinking": { "name": "Qwen3.6 35B Thinking · 24k · vision — hard problems (remote)", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||
"Qwen3.5-9B-UD-Q6_K_XL": { "name": "Qwen3.5 9B · 32k · vision — quick tasks (remote)", "attachment": true, "limit": { "context": 32768, "output": 8192 } },
|
||||
"gemma-4-26B-A4B-it-UD-IQ4_XS": { "name": "Gemma 4 26B · 24k · vision — quality generalist (remote)", "attachment": true, "limit": { "context": 24576, "output": 4096 } },
|
||||
"gemma-4-E4B-it-UD-Q8_K_XL": { "name": "Gemma 4 E4B · 64k · vision — fast generalist, long docs (remote)", "attachment": true, "limit": { "context": 65536, "output": 16384 } },
|
||||
"GLM-4.7-Flash-UD-Q4_K_XL": { "name": "GLM-4.7 Flash · 24k — quality coder (remote)", "limit": { "context": 24576, "output": 8192 } },
|
||||
"gpt-oss-20b": { "name": "gpt-oss 20B · 64k — fast reasoning + tools (remote)", "limit": { "context": 65536, "output": 8192 } },
|
||||
"gpt-oss-20b-low": { "name": "gpt-oss 20B low · 64k — snappy answers (remote)", "limit": { "context": 65536, "output": 8192 } }
|
||||
}
|
||||
},
|
||||
"llama.cpp": {
|
||||
"npm": "@ai-sdk/openai-compatible",
|
||||
"name": "llamacpp",
|
||||
"options": {
|
||||
"baseURL": "http://192.168.0.204:11343/v1"
|
||||
},
|
||||
"models": {
|
||||
"Qwen3-Coder-Next-UD-IQ3_XXS": { "name": "Qwen3 Coder Next 80B · 128k — long sessions", "limit": { "context": 131072, "output": 16384 } },
|
||||
"Qwen3-Coder-30B-Instruct-UD-Q3_K_XL": { "name": "Qwen3 Coder 30B · 32k — main agent coder", "limit": { "context": 32768, "output": 4096 } },
|
||||
"Qwen3.6-35B-A3B-MTP-UD-IQ3_XXS": { "name": "Qwen3.6 35B · 24k · vision — daily driver", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||
"Qwen3.6-35B-A3B-Thinking": { "name": "Qwen3.6 35B Thinking · 24k · vision — hard problems", "attachment": true, "limit": { "context": 24576, "output": 8192 } },
|
||||
"Qwen3.5-9B-UD-Q6_K_XL": { "name": "Qwen3.5 9B · 32k · vision — quick tasks", "attachment": true, "limit": { "context": 32768, "output": 8192 } },
|
||||
"gemma-4-26B-A4B-it-UD-IQ4_XS": { "name": "Gemma 4 26B · 24k · vision — quality generalist", "attachment": true, "limit": { "context": 24576, "output": 4096 } },
|
||||
"gemma-4-E4B-it-UD-Q8_K_XL": { "name": "Gemma 4 E4B · 64k · vision — fast generalist, long docs", "attachment": true, "limit": { "context": 65536, "output": 16384 } },
|
||||
"GLM-4.7-Flash-UD-Q4_K_XL": { "name": "GLM-4.7 Flash · 24k — quality coder", "limit": { "context": 24576, "output": 8192 } },
|
||||
"gpt-oss-20b": { "name": "gpt-oss 20B · 64k — fast reasoning + tools", "limit": { "context": 65536, "output": 8192 } },
|
||||
"gpt-oss-20b-low": { "name": "gpt-oss 20B low · 64k — snappy answers", "limit": { "context": 65536, "output": 8192 } }
|
||||
}
|
||||
}
|
||||
},
|
||||
"agent": {
|
||||
"plan": {
|
||||
"mode": "primary",
|
||||
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
||||
"permission": {
|
||||
"edit": "deny"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"mode": "primary",
|
||||
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
||||
"permission": {
|
||||
"edit": {
|
||||
"*": "allow",
|
||||
"**/.env*": "deny",
|
||||
"**/*.env": "deny",
|
||||
"**/*.pem": "deny",
|
||||
"**/*.key": "deny",
|
||||
"**/id_rsa*": "deny",
|
||||
"**/.ssh/**": "deny",
|
||||
"**/.aws/**": "deny",
|
||||
"**/.git/**": "deny",
|
||||
"**/.npmrc": "deny",
|
||||
"**/.netrc": "deny"
|
||||
}
|
||||
}
|
||||
},
|
||||
"code-reviewer": {
|
||||
"description": "Reviews code for best practices and potential issues",
|
||||
"prompt": "You are a code reviewer. Focus on security, performance, and maintainability.",
|
||||
"mode": "subagent",
|
||||
"model": "llama.cpp/GLM-4.7-Flash-UD-Q4_K_XL",
|
||||
"permission": {
|
||||
"edit": "deny"
|
||||
}
|
||||
},
|
||||
"test-runner": {
|
||||
"description": "Runs and interprets test suites",
|
||||
"prompt": "You are a test runner. Focus on identifying failing tests and providing clear reproduction steps.",
|
||||
"mode": "subagent",
|
||||
"model": "llama.cpp/GLM-4.7-Flash-UD-Q4_K_XL",
|
||||
"permission": {
|
||||
"edit": "deny"
|
||||
}
|
||||
},
|
||||
"doc-writer": {
|
||||
"description": "Maintains project documentation and docstrings",
|
||||
"prompt": "You are a technical writer. Focus on clarity, accuracy, and keeping documentation in sync with code changes.",
|
||||
"mode": "subagent",
|
||||
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
||||
"permission": {
|
||||
"edit": {
|
||||
"*": "deny",
|
||||
"**/*.md": "allow",
|
||||
"**/*.mdx": "allow",
|
||||
"**/*.markdown": "allow",
|
||||
"**/*.txt": "allow",
|
||||
"**/*.rst": "allow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"security-auditor": {
|
||||
"description": "Scans for security vulnerabilities and hardcoded secrets",
|
||||
"prompt": "You are a security auditor. Focus on OWASP principles, secret detection, and dependency vulnerabilities.",
|
||||
"mode": "subagent",
|
||||
"model": "llama.cpp/GLM-4.7-Flash-UD-Q4_K_XL",
|
||||
"permission": {
|
||||
"edit": "deny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/tui.json",
|
||||
"theme": "lucent-orng"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/mfontanini/presenterm/master/config-file-schema.json
|
||||
defaults:
|
||||
# override the terminal font size when in windows or when using sixel.
|
||||
terminal_font_size: 16
|
||||
|
||||
# the theme to use by default in every presentation unless overridden.
|
||||
theme: dark
|
||||
|
||||
# the image protocol to use.
|
||||
image_protocol: kitty-local
|
||||
|
||||
typst:
|
||||
# the pixels per inch when rendering latex/typst formulas.
|
||||
ppi: 300
|
||||
|
||||
mermaid:
|
||||
# the scale parameter passed to the mermaid CLI (mmdc).
|
||||
scale: 1
|
||||
|
||||
options:
|
||||
# whether slides are automatically terminated when a slide title is found.
|
||||
implicit_slide_ends: false
|
||||
|
||||
# the prefix to use for commands.
|
||||
command_prefix: ""
|
||||
|
||||
# show all lists incrementally, by implicitly adding pauses in between elements.
|
||||
incremental_lists: false
|
||||
|
||||
# this option tells presenterm you don't care about extra parameters in
|
||||
# presentation's front matter. This can be useful if you're trying to load a
|
||||
# presentation made for another tool
|
||||
strict_front_matter_parsing: true
|
||||
|
||||
# whether to treat a thematic break as a slide end.
|
||||
end_slide_shorthand: false
|
||||
|
||||
snippet:
|
||||
exec:
|
||||
# enable code snippet execution. Use at your own risk!
|
||||
enable: true
|
||||
|
||||
exec_replace:
|
||||
# enable code snippet automatic execution + replacing the snippet with its output. Use at your own risk!
|
||||
enable: true
|
||||
|
||||
render:
|
||||
# the number of threads to use when rendering `+render` code snippets.
|
||||
threads: 2
|
||||
|
||||
speaker_notes:
|
||||
# The endpoint to listen for speaker note events.
|
||||
listen_address: "127.0.0.1:59418"
|
||||
|
||||
# The endpoint to publish speaker note events.
|
||||
publish_address: "127.0.0.1:59418"
|
||||
|
||||
# Whether to always publish speaker notes even when `--publish-speaker-notes` is not set.
|
||||
always_publish: false
|
||||
|
||||
bindings:
|
||||
# the keys that cause the presentation to move forwards.
|
||||
next: ["l", "j", "<right>", "<page_down>", "<down>", " "]
|
||||
|
||||
# the keys that cause the presentation to move forwards fast.
|
||||
next_fast: ["n"]
|
||||
|
||||
# the keys that cause the presentation to move backwards.
|
||||
previous: ["h", "k", "<left>", "<page_up>", "<up>"]
|
||||
|
||||
# the keys that cause the presentation to move backwards fast
|
||||
previous_fast: ["p"]
|
||||
|
||||
# the key binding to jump to the first slide.
|
||||
first_slide: ["gg"]
|
||||
|
||||
# the key binding to jump to the last slide.
|
||||
last_slide: ["G"]
|
||||
|
||||
# the key binding to jump to a specific slide.
|
||||
go_to_slide: ["<number>G"]
|
||||
|
||||
# the key binding to execute a piece of shell code.
|
||||
execute_code: ["<c-e>"]
|
||||
|
||||
# the key binding to reload the presentation.
|
||||
reload: ["<c-r>"]
|
||||
|
||||
# the key binding to toggle the slide index modal.
|
||||
toggle_slide_index: ["<c-p>"]
|
||||
|
||||
# the key binding to toggle the key bindings modal.
|
||||
toggle_bindings: ["?"]
|
||||
|
||||
# the key binding to close the currently open modal.
|
||||
close_modal: ["<esc>"]
|
||||
|
||||
# the key binding to close the application.
|
||||
exit: ["<c-c>", "q"]
|
||||
|
||||
# the key binding to suspend the application.
|
||||
suspend: ["<c-z>"]
|
||||
|
||||
# the key binding to skip all pauses in the current slide.
|
||||
skip_pauses: ["s"]
|
||||
@@ -0,0 +1,45 @@
|
||||
# PyRadio Setup
|
||||
|
||||
This repository contains a custom configuration and station list for [PyRadio](https://github.com/coderholic/pyradio), a terminal-based radio player.
|
||||
|
||||
## Kitty Music Session
|
||||
|
||||
To get a full-screen, immersive music player experience, you can use a custom [Kitty terminal session](https://sw.kovidgoyal.net/kitty/sessions/).
|
||||
|
||||
The configuration file `music.conf` (found in your kitty config directory) sets up a layout that includes:
|
||||
- A `pyradio` terminal.
|
||||
- A `cava` terminal for audio visualization.
|
||||
- A `pipes-rs` terminal for some visual flair.
|
||||
|
||||
### Launching the Session
|
||||
|
||||
Use keybind `$mainMod + R` or run the following command to launch the music session:
|
||||
|
||||
```bash
|
||||
kitty --session ~/.config/kitty/music.conf
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
1. **Install PyRadio**: Ensure you have `pyradio` installed on your system.
|
||||
2. **Configuration**:
|
||||
* Copy the `config` file to your PyRadio configuration directory (usually `~/.config/pyradio/config`).
|
||||
* Copy the `stations.csv` file to your PyRadio directory.
|
||||
3. **Using Custom Stations**:
|
||||
* PyRadio can be configured to use a custom stations file. Ensure your `config` points to the `stations.csv` provided here if you want to use this specific collection of stations.
|
||||
|
||||
## Station Sources
|
||||
|
||||
The stations in `stations.csv` are curated from various sources, often utilizing the [Radio Browser](https://www.radio-browser.info/) API.
|
||||
|
||||
### About Radio Browser
|
||||
[Radio Browser](https://www.radio-browser.info/) is a community-driven database of internet radio stations. It is a free, open-source project that provides a massive API for accessing thousands of radio streams worldwide. It's a great resource for discovering new music and finding niche genres that might not be available on mainstream services.
|
||||
|
||||
## Alternatives to PyRadio
|
||||
|
||||
If you are looking for other ways to listen to internet radio in the terminal or via other interfaces, consider these alternatives:
|
||||
|
||||
* **[Web Radio Clients](https://www.radio-browser.info/users)**: Many users of Radio Browser utilize various web-based players or custom scripts that interface directly with the Radio Browser API.
|
||||
* **[MPV (Command Line)](https://mpv.io/)**: Terminal player pyradio uses as a backend `mpv <stream_url>`
|
||||
* **[VLC (Command Line)](https://www.videolan.org/vlc/)**: You can play many radio streams directly from the terminal using `cvlc --play-and-exit <stream_url>`.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# PyRadio User Configuration File
|
||||
# To get a full list of options execute: pyradio -pc
|
||||
# or examine the file: /usr/lib/python3.13/site-packages/pyradio/config
|
||||
#
|
||||
theme = blue-by-boxer
|
||||
use_transparency = True
|
||||
@@ -0,0 +1,61 @@
|
||||
Ambient Psychill [1.FM],http://strm112.1.fm/ambientpsy_mobile_mp3,,
|
||||
Chilltrax,http://server1.chilltrax.com:9000/,,
|
||||
Chillout [psyradio*fm],http://streamer.psyradio.org:8020/;listen.mp3,,
|
||||
Chillout [Psyndora],http://cast.magicstreams.gr:9125/stream,,
|
||||
Chillout (Groove Salad) [SomaFM],https://hls.somafm.com/hls/groovesalad/320k/program.m3u8,,
|
||||
Groove Salad Classic (Early 2000s Ambient),https://somafm.com/gsclassic.pls,,
|
||||
Ambient and Experimental [n5MD],https://somafm.com/n5md.pls,,
|
||||
Suomisaundi [Caprice],http://79.120.77.11:8004/suomisaundi,,
|
||||
Vaporwaves [SomaFM],https://somafm.com/vaporwaves.pls,,
|
||||
Space Music [Synphaera],https://somafm.com/synphaera.pls,,
|
||||
Downtempo (Secret Agent) [SomaFM],http://somafm.com/secretagent.pls,,
|
||||
Dub Step (Beyond) [SomaFM],http://somafm.com/dubstep.pls,,
|
||||
Dub Techno [Schizoid], http://94.130.113.214:8000/dubtechno,nocon,
|
||||
Dubplate.fm,https://sc2.dubplate.fm/radio/8030/dnb/uhifi,,
|
||||
Liquid funk [Caprice], http://79.111.119.111:9115/,,
|
||||
Liquid funk,https://radiorecord.hostingradio.ru/liquidfunk96.aacp,,
|
||||
Liqui Radio,https://stream-162.zeno.fm/ug59eq099yzuv?zs=zaqVusVSQuWMN3O5gnh8xA,,
|
||||
Liquid DnB,http://95.47.244.172:8000/live,,
|
||||
Acid Techno,https://radiorecord.hostingradio.ru/techno96.aacp,,
|
||||
Dark Techno [Caprice],http://79.111.14.76:8000/darktechno,,
|
||||
Deep Techno/House [1.FM],http://strm112.1.fm/deeptech_mobile_mp3,,
|
||||
90s90s Techno,http://streams.90s90s.de/techno/mp3-192/radiode/,,
|
||||
The Trip: [SomaFM],https://somafm.com/thetrip.pls,,
|
||||
ToXoRs minimalRADIO,http://95.216.245.239:8000/stream/1/,,
|
||||
Minimalradio.de,https://azurafallback.de:8010/320.mp3,,
|
||||
Minimal [Technolovers],https://stream.technolovers.fm/minimal,,
|
||||
Suomisaundi / Freeform Psytrance / Spugedelic Trance [Caprice],http://79.120.77.11:8000/suomisaundi,,
|
||||
Psychedelic Secret,https://solid48.streamupsolutions.com/proxy/bglsokon?mp=/=stream,,
|
||||
Full-on psytrance [Caprice],http://79.111.14.76:9019/,,
|
||||
Magnathospere Morning,https://listen7.myradio24.com/magnatos,,
|
||||
Psytrance [Psyndora],https://cast.magicstreams.gr/sc/psyndora/stream,,
|
||||
Hirschmilch Psytrance,https://hirschmilch.de:7001/psytrance.mp3,,
|
||||
Bluffphonica,http://bluffphonica.stream.laut.fm/bluffphonica?pl=m3u&t302=2024-09-17_23-09-40&uuid=ce6a1b0b-1654-4d08-afbc-31b028f8f23b,,
|
||||
BOM Psytrance [1.FM],http://strm112.1.fm/psytrance_mobile_mp3,,
|
||||
TL_Psytrance,https://stream.technolovers.fm/psytrance,,
|
||||
Record Goa Psy,https://radiorecord.hostingradio.ru/goa96.aacp,,
|
||||
Psytrance 24/7 [DMT FM],https://dc1.serverse.com/proxy/ywycfrxn/live,,
|
||||
Trance [RadiOzora],http://trance.out.airtime.pro:8000/trance_a,,
|
||||
Uplifting trance [Technolovers],https://0nlineradio.stream13.radiohost.de/technolovers-uplifting-trance,,
|
||||
Uplift [RadioRecord],https://radiorecord.hostingradio.ru/uplift96.aacp,,
|
||||
Alternative [BAGeL],https://ais-sa3.cdnstream1.com/2606_128.aac,,
|
||||
Celtic (ThistleRadio) [SomaFM],http://somafm.com/thistle.pls,,
|
||||
Commodore 64 Remixes [Slay],http://www.slayradio.org/tune_in.php/128kbps/listen.m3u,,
|
||||
Covers [SomaFM],http://somafm.com/covers.pls,,
|
||||
Indie Pop [SomaFM],http://somafm.com/indiepop130.pls,,
|
||||
Jazz (Sonic Universe) [SomaFM],http://somafm.com/startstream=sonicuniverse.pls,,
|
||||
Pop (PopTron) [SomaFM],http://somafm.com/poptron.pls,,
|
||||
Pop/Rock/Urban (Frequence 3 - Paris),http://streams.frequence3.net/hd-mp3.m3u,,
|
||||
Progressive (Tags Trance Trip) [SomaFM],http://somafm.com/tagstrance.pls,,
|
||||
Public Radio (NPR National Public Radio Stream),https://npr-ice.streamguys1.com/live.mp3,,
|
||||
Heavyweight Reggae,https://somafm.com/reggae.pls,,
|
||||
Rock (Digitalis) [SomaFM],http://somafm.com/digitalis.pls,,
|
||||
Metal Detector,https://somafm.com/metal.pls,,
|
||||
JazzGroove,https://www.internet-radio.com/servers/tools/playlistgenerator/?u=http://199.180.72.2:8015/listen.pls?sid=1&t=.pls,,
|
||||
Main Mix [Paradise],http://stream.radioparadise.com/aac-128,,
|
||||
Mellow Mix [Paradise] ,http://stream.radioparadise.com/mellow-128,,
|
||||
Rock Mix [Paradise],http://stream.radioparadise.com/rock-128,,
|
||||
Eclectic Mix [Paradise],http://stream.radioparadise.com/eclectic-128,,
|
||||
Echoes of Bluemars,http://streams.echoesofbluemars.org:8000/bluemars.m3u,,
|
||||
Cryosleep [Echoes of Bluemars] ,http://streams.echoesofbluemars.org:8000/cryosleep.m3u,,
|
||||
Voices from Within [Echoes of Bluemars],http://streams.echoesofbluemars.org:8000/voicesfromwithin.m3u,,
|
||||
|
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# CPU utilisation (%) averaged over the interval since the PREVIOUS status refresh:
|
||||
# /proc/stat totals persist in a state file between runs (same pattern as net.sh),
|
||||
# so the value covers the whole status-interval. (The old version slept 0.3s and
|
||||
# sampled just that window — a 6% duty cycle that aliased bursty loads.) No sleep,
|
||||
# ~5ms. First run (no state yet) shows the since-boot average. Glyph = Waybar's
|
||||
# cpu module icon (U+F035B).
|
||||
printf '\U000f035b '
|
||||
rt="${XDG_RUNTIME_DIR:-/tmp}"
|
||||
st="$rt/tmux_cpu_stat" # previous totals: tot idle
|
||||
|
||||
read -r _ u n s i w rest < /proc/stat
|
||||
idle=$((i + w)); tot=$((u + n + s + i + w)); for v in $rest; do tot=$((tot + v)); done
|
||||
|
||||
p_tot=0; p_idle=0
|
||||
[ -r "$st" ] && read -r p_tot p_idle < "$st"
|
||||
[ "$p_tot" -gt "$tot" ] && { p_tot=0; p_idle=0; } # stale state from a previous boot
|
||||
printf '%s %s\n' "$tot" "$idle" > "$st"
|
||||
|
||||
dt=$((tot - p_tot)); di=$((idle - p_idle))
|
||||
if [ "$dt" -le 0 ]; then printf -- '--%%'; else printf '%d%%' $(((100 * (dt - di) + dt / 2) / dt)); fi
|
||||