diff --git a/.gitignore b/.gitignore index 6fe4fa8..33212be 100644 --- a/.gitignore +++ b/.gitignore @@ -64,7 +64,6 @@ zshell/** !zshell/.zshrc KeePass Signal -fish go helm pulseaudio-ctl diff --git a/README.md b/README.md index 61e8934..40332c3 100644 --- a/README.md +++ b/README.md @@ -5,79 +5,13 @@ configuration repository on - Raspberry Pi OS Lite - pop! os +- Ubuntu ## Software used -- neovim (v0.10.3) -- zsh -- tmux - -## Setup from scratch on debian system - -This setup is applicable to debian and ubuntu - -### Install dependencies - -```bash -sudo apt install git nodejs -``` - -### Node Installation - -Install node via nvm - -See: https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating - -### Zshell installation - -- Install zsh - -```bash -sudo apt install zsh -``` - -https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH - -- Install oh my zsh - -See https://ohmyz.sh/#install - - -- Install zsh-autosuggestions - -See https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md#oh-my-zsh - -- Install atuin - -https://atuin.sh/ - -### Clone dotfiles - -Clone dotfiles from [github](https://github.com/wserr/dotfiles) - -```bash -ssh-keygen # pick the default options - -# install public key (id_rsa.pub) in github -# configure username and password -git config --global user.email "serruys.willem@hotmail.com" -git config --global user.name "wserr" - -cd ~ -mkdir system && cd system -git clone git@github.com:wserr/dotfiles.git - -cd dotfiles -cp -r nvim ~/.config/nvim -cp zshell/.zshrc ~/ -cp tmux/tmux.conf ~/.tmux.conf -``` - -### Tmux installation - -```bash -sudo apt install tmux -``` +- neovim (v0.11.2) +- zellij +- fish ### Neovim installation & configuration @@ -100,6 +34,6 @@ git checkout stable > NOTE: when updating neovim version, first remove the .deps folder before rebuilding. ```bash -sudo rm -r deps +sudo rm -r .deps ... ``` diff --git a/fish/completions/copilot.fish b/fish/completions/copilot.fish new file mode 100644 index 0000000..9dcc50f --- /dev/null +++ b/fish/completions/copilot.fish @@ -0,0 +1,176 @@ +# fish completion for copilot +# Generated by `copilot completion fish`. Do not edit by hand. + +complete -c copilot -n '__fish_use_subcommand' -f -a 'login' -d 'Authenticate with Copilot' +complete -c copilot -n '__fish_use_subcommand' -f -a 'help' -d 'Display help information' +complete -c copilot -n '__fish_use_subcommand' -f -a 'init' -d 'Initialize Copilot instructions' +complete -c copilot -n '__fish_use_subcommand' -f -a 'update' -d 'Download the latest version' +complete -c copilot -n '__fish_use_subcommand' -f -a 'version' -d 'Display version information' +complete -c copilot -n '__fish_use_subcommand' -f -a 'plugin' -d 'Manage plugins' +complete -c copilot -n '__fish_use_subcommand' -f -a 'mcp' -d 'Manage MCP servers' +complete -c copilot -n '__fish_use_subcommand' -f -a 'plugins' -d 'Inspect configured plugins across kinds' +complete -c copilot -n '__fish_use_subcommand' -f -a 'skill' -d 'Manage skills' +complete -c copilot -n '__fish_use_subcommand' -f -a 'completion' -d 'Generate a shell completion script' +complete -c copilot -l version -s v -f -d 'show version information' +complete -c copilot -l interactive -s i -r -d 'Start interactive mode and automatically execute this prompt' +complete -c copilot -l prompt -s p -r -d 'Execute a prompt in non-interactive mode (exits after completion)' +complete -c copilot -l silent -s s -f -d 'Output only the agent response (no stats), useful for scripting with -p' +complete -c copilot -l enable-memory -f -d 'Enable memory in prompt mode (disabled by default)' +complete -c copilot -l model -r -d 'Set the AI model to use (use \'auto\' to let Copilot pick automatically)' +complete -c copilot -l effort -l reasoning-effort -r -f -d 'Set the reasoning effort level' -a 'none minimal low medium high xhigh max' +complete -c copilot -l context -r -f -d 'Set the context window tier (overrides persisted setting)' -a 'default long_context' +complete -c copilot -l enable-reasoning-summaries -f -d 'Request reasoning summaries for OpenAI models' +complete -c copilot -l agent -r -d 'Specify a custom agent to use' +complete -c copilot -l resume -s r -r -d 'Resume from a previous session (optionally specify existing session ID, task ID, ID prefix, or name; name matching is exact, case-insensitive)' +complete -c copilot -l continue -f -d 'Resume the most recent session' +complete -c copilot -l name -s n -r -d 'Set a name for the new session' +complete -c copilot -l session-id -r -d 'Resume an existing session or task by ID, or set the UUID for a new session' +complete -c copilot -l connect -r -d 'Connect directly to a remote session (optionally specify session ID or task ID)' +complete -c copilot -l allow-all-tools -f -d 'Allow all tools to run automatically without confirmation; required for non-interactive mode' +complete -c copilot -l allow-all-paths -f -d 'Disable file path verification and allow access to any path' +complete -c copilot -l disallow-temp-dir -f -d 'Prevent automatic access to the system temporary directory' +complete -c copilot -l no-custom-instructions -f -d 'Disable loading of custom instructions from AGENTS.md and related files' +complete -c copilot -l no-auto-update -f -d 'Disable downloading CLI update automatically (disabled by default in CI environments)' +complete -c copilot -l no-ask-user -f -d 'Disable the ask_user tool (agent works autonomously without asking questions)' +complete -c copilot -l banner -f -d 'Show the startup banner' +complete -c copilot -l no-color -f -d 'Disable all color output' +complete -c copilot -l screen-reader -f -d 'Enable screen reader optimizations' +complete -c copilot -l plain-diff -f -d 'Disable rich diff rendering (syntax highlighting via diff tool specified by git config)' +complete -c copilot -s C -r -d 'Change working directory before doing anything else' +complete -c copilot -l log-dir -r -d 'Set log file directory (default: ~/.copilot/logs/)' +complete -c copilot -l extension-sdk-path -r -d 'Override the bundled @github/copilot-sdk injected into extension subprocesses with a local `copilot-sdk/` folder. Invalid paths fall back to the bundled SDK.' +complete -c copilot -l log-level -r -f -d 'Set the log level' -a 'none error warning info debug all default' +complete -c copilot -l stream -r -f -d 'Enable or disable streaming mode' -a 'on off' +complete -c copilot -l output-format -r -f -d 'Output format: \'text\' (default) or \'json\' (JSONL, one JSON object per line)' -a 'text json' +complete -c copilot -l share -r -d 'Share session to markdown file after completion in non-interactive mode (default: ./copilot-session-.md)' +complete -c copilot -l share-gist -f -d 'Share session to a secret GitHub gist after completion in non-interactive mode' +complete -c copilot -l add-dir -r -d 'Add a directory to the allowed list for file access (can be used multiple times)' +complete -c copilot -l attachment -r -d 'Attach a file (image or native document) to the initial prompt; only valid in non-interactive mode (can be used multiple times)' +complete -c copilot -l disable-mcp-server -r -d 'Disable a specific MCP server (can be used multiple times)' +complete -c copilot -l disable-builtin-mcps -f -d 'Disable all built-in MCP servers (currently: github-mcp-server)' +complete -c copilot -l enable-all-github-mcp-tools -f -d 'Enable all GitHub MCP server tools instead of the default CLI subset. Overrides --add-github-mcp-toolset and --add-github-mcp-tool options.' +complete -c copilot -l add-github-mcp-toolset -r -d 'Add a toolset to enable for the GitHub MCP server instead of the default CLI subset (can be used multiple times). Use "all" for all toolsets.' +complete -c copilot -l add-github-mcp-tool -r -d 'Add a tool to enable for the GitHub MCP server instead of the default CLI subset (can be used multiple times). Use "*" for all tools.' +complete -c copilot -l plugin-dir -r -d 'Load a plugin from a local directory (can be used multiple times)' +complete -c copilot -l additional-mcp-config -r -d 'Additional MCP servers configuration as JSON string or file path (prefix with @) (can be used multiple times; augments config from ~/.copilot/mcp-config.json for this session)' +complete -c copilot -l allow-all-mcp-server-instructions -f -d 'Include initialization instructions from all MCP servers in the system prompt instead of only allowlisted servers' +complete -c copilot -l allow-tool -r -d 'Tools the CLI has permission to use; will not prompt for permission' +complete -c copilot -l deny-tool -r -d 'Tools the CLI does not have permission to use; will not prompt for permission' +complete -c copilot -l available-tools -r -d 'Only these tools will be available to the model' +complete -c copilot -l excluded-tools -r -d 'These tools will not be available to the model' +complete -c copilot -l secret-env-vars -r -d 'Environment variable names whose values are stripped from shell and MCP server environments and redacted from output (e.g., --secret-env-vars=MY_KEY,OTHER_KEY)' +complete -c copilot -l allow-url -r -d 'Allow access to specific URLs or domains' +complete -c copilot -l deny-url -r -d 'Deny access to specific URLs or domains, takes precedence over --allow-url' +complete -c copilot -l allow-all-urls -f -d 'Allow access to all URLs without confirmation' +complete -c copilot -l allow-all -f -d 'Enable all permissions (equivalent to --allow-all-tools --allow-all-paths --allow-all-urls)' +complete -c copilot -l yolo -f -d 'Enable all permissions (equivalent to --allow-all-tools --allow-all-paths --allow-all-urls)' +complete -c copilot -l max-autopilot-continues -r -d 'Maximum number of continuation messages in autopilot mode' +complete -c copilot -l mode -r -f -d 'Set the initial agent mode' -a 'interactive plan autopilot' +complete -c copilot -l autopilot -f -d 'Start in autopilot mode' +complete -c copilot -l plan -f -d 'Start in plan mode' +complete -c copilot -l experimental -f -d 'Enable experimental features' +complete -c copilot -l no-experimental -f -d 'Disable experimental features' +complete -c copilot -l bash-env -r -d 'Enable BASH_ENV support for bash shells (on|off)' +complete -c copilot -l no-bash-env -f -d 'Disable BASH_ENV support for bash shells' +complete -c copilot -l mouse -r -d 'Enable mouse support in alt screen mode (on|off)' +complete -c copilot -l no-mouse -f -d 'Disable mouse support in alt screen mode' +complete -c copilot -l acp -f -d 'Start as Agent Client Protocol server' +complete -c copilot -l remote -f -d 'Enable remote control of your session from GitHub web and mobile' +complete -c copilot -l no-remote -f -d 'Disable remote control of your session from GitHub web and mobile' +complete -c copilot -l remote-export -f -d 'Export your session to GitHub web and mobile (read-only; does not enable remote control)' +complete -c copilot -l no-remote-export -f -d 'Disable exporting your session to GitHub web and mobile (also disables remote control)' +complete -c copilot -l max-ai-credits -r -d 'Set max AI credits for this session' +complete -c copilot -n '__fish_seen_subcommand_from login' -l host -r -d 'GitHub host URL (default: https://github.com)' +complete -c copilot -n '__fish_seen_subcommand_from update' -f -a 'stable prerelease' +complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'install' -d 'Install a plugin' +complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'uninstall' -d 'Uninstall a plugin' +complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'update' -d 'Update a plugin' +complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'list' -d 'List installed and --plugin-dir plugins' +complete -c copilot -n '__fish_seen_subcommand_from plugin' -f -a 'marketplace' -d 'Manage plugin marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from update' -l all -f -d 'Update all installed plugins' +complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'add' -d 'Add a marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'remove' -d 'Remove a marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'list' -d 'List registered marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'browse' -d 'Browse plugins in a marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace' -f -a 'update' -d 'Update marketplace plugin catalogs' +complete -c copilot -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from marketplace; and __fish_seen_subcommand_from remove' -l force -s f -f -d 'Force removal even if plugins are installed' +complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'list' -d 'List configured MCP servers' +complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'get' -d 'Show server details' +complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'add' -d 'Add an MCP server' +complete -c copilot -n '__fish_seen_subcommand_from mcp' -f -a 'remove' -d 'Remove an MCP server' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from list' -l json -f -d 'Output as JSON' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from get' -l json -f -d 'Output as JSON' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from get' -l show-secrets -f -d 'Show full environment variable and header values (masked by default)' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l transport -r -f -d 'Server transport' -a 'stdio http sse' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l env -r -d 'Environment variable (KEY=VALUE, can be repeated)' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l header -r -d 'HTTP header for remote servers, can be repeated' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l tools -r -d 'Tool filter: "*" for all, comma-separated list, or "" for none' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l timeout -r -d 'Timeout in milliseconds' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l json -f -d 'Output added config as JSON' +complete -c copilot -n '__fish_seen_subcommand_from mcp; and __fish_seen_subcommand_from add' -l show-secrets -f -d 'Show full environment variable and header values in output, masked by default' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'list' -d 'List configured plugins across kinds' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'enable' -d 'Enable a configured tool' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'disable' -d 'Disable a configured tool' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'remove' -d 'Remove an installed tool' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'rm' -d 'Remove an installed tool' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'install' -d 'Install a new tool' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'add' -d 'Install a new tool' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'update' -d 'Update a plugin' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'marketplace' -d 'Manage plugin marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugins' -f -a 'marketplaces' -d 'Manage plugin marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from list' -l kind -r -d 'Filter by kind. Repeatable or comma-separated. Supported: plugin, mcp, skill, instruction, lsp.' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from list' -l scope -r -d 'Filter by scope. Repeatable or comma-separated. Supported: user, repository, organization, plugin, builtin, unknown.' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from list' -l json -f -d 'Emit machine-readable JSON instead of grouped text' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from enable' -l plugin -f -d 'Target a plugin (default)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from enable' -l mcp -f -d 'Target an MCP server' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from enable' -l skill -f -d 'Target a skill' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from disable' -l plugin -f -d 'Target a plugin (default)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from disable' -l mcp -f -d 'Target an MCP server' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from disable' -l skill -f -d 'Target a skill' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from remove' -l plugin -f -d 'Remove a plugin (default)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from remove' -l mcp -f -d 'Remove an MCP server' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from remove' -l skill -f -d 'Remove a personal or project skill' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from rm' -l plugin -f -d 'Remove a plugin (default)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from rm' -l mcp -f -d 'Remove an MCP server' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from rm' -l skill -f -d 'Remove a personal or project skill' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from install' -l plugin -f -d 'Install a plugin (default)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from install' -l skill -f -d 'Install a skill from a local path or URL' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from install' -l mcp -f -d 'Install an MCP server (not supported here — see below)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from install' -l scope -r -f -d 'Install target for a file/URL --skill: user (default) or project' -a 'user project' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from add' -l plugin -f -d 'Install a plugin (default)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from add' -l skill -f -d 'Install a skill from a local path or URL' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from add' -l mcp -f -d 'Install an MCP server (not supported here — see below)' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from add' -l scope -r -f -d 'Install target for a file/URL --skill: user (default) or project' -a 'user project' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from update' -l all -f -d 'Update all installed plugins' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'list' -d 'List registered plugin marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'ls' -d 'List registered plugin marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'add' -d 'Add a plugin marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'remove' -d 'Remove a plugin marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'rm' -d 'Remove a plugin marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'browse' -d 'Browse plugins in a marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'update' -d 'Refresh marketplace plugin catalogs' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace' -f -a 'refresh' -d 'Refresh marketplace plugin catalogs' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace; and __fish_seen_subcommand_from list' -l json -f -d 'Emit machine-readable JSON instead of grouped text' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace; and __fish_seen_subcommand_from ls' -l json -f -d 'Emit machine-readable JSON instead of grouped text' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace; and __fish_seen_subcommand_from remove' -l force -f -d 'Also uninstall every plugin sourced from this marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace; and __fish_seen_subcommand_from rm' -l force -f -d 'Also uninstall every plugin sourced from this marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplace; and __fish_seen_subcommand_from browse' -l json -f -d 'Emit machine-readable JSON instead of grouped text' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'list' -d 'List registered plugin marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'ls' -d 'List registered plugin marketplaces' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'add' -d 'Add a plugin marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'remove' -d 'Remove a plugin marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'rm' -d 'Remove a plugin marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'browse' -d 'Browse plugins in a marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'update' -d 'Refresh marketplace plugin catalogs' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces' -f -a 'refresh' -d 'Refresh marketplace plugin catalogs' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces; and __fish_seen_subcommand_from list' -l json -f -d 'Emit machine-readable JSON instead of grouped text' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces; and __fish_seen_subcommand_from ls' -l json -f -d 'Emit machine-readable JSON instead of grouped text' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces; and __fish_seen_subcommand_from remove' -l force -f -d 'Also uninstall every plugin sourced from this marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces; and __fish_seen_subcommand_from rm' -l force -f -d 'Also uninstall every plugin sourced from this marketplace' +complete -c copilot -n '__fish_seen_subcommand_from plugins; and __fish_seen_subcommand_from marketplaces; and __fish_seen_subcommand_from browse' -l json -f -d 'Emit machine-readable JSON instead of grouped text' +complete -c copilot -n '__fish_seen_subcommand_from skill' -f -a 'list' -d 'List available skills' +complete -c copilot -n '__fish_seen_subcommand_from skill' -f -a 'add' -d 'Add a skill from a file, URL, or directory' +complete -c copilot -n '__fish_seen_subcommand_from skill' -f -a 'remove' -d 'Remove a skill or custom skill directory' +complete -c copilot -n '__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from list' -l json -f -d 'Output as JSON' +complete -c copilot -n '__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from add' -l project -f -d 'Install the skill into the project\'s .github/skills directory' +complete -c copilot -n '__fish_seen_subcommand_from completion' -f -a 'bash zsh fish' diff --git a/fish/completions/fisher.fish b/fish/completions/fisher.fish new file mode 100644 index 0000000..6d23ce4 --- /dev/null +++ b/fish/completions/fisher.fish @@ -0,0 +1,7 @@ +complete --command fisher --exclusive --long help --description "Print help" +complete --command fisher --exclusive --long version --description "Print version" +complete --command fisher --exclusive --condition __fish_use_subcommand --arguments install --description "Install plugins" +complete --command fisher --exclusive --condition __fish_use_subcommand --arguments update --description "Update installed plugins" +complete --command fisher --exclusive --condition __fish_use_subcommand --arguments remove --description "Remove installed plugins" +complete --command fisher --exclusive --condition __fish_use_subcommand --arguments list --description "List installed plugins matching regex" +complete --command fisher --exclusive --condition "__fish_seen_subcommand_from update remove" --arguments "(fisher list)" diff --git a/fish/completions/kcong.fish b/fish/completions/kcong.fish new file mode 100644 index 0000000..a882fc6 --- /dev/null +++ b/fish/completions/kcong.fish @@ -0,0 +1,9 @@ +#kafka-consumer-groups.sh --bootstrap-server pkc-57q33g.westeurope.azure.confluent.cloud:9092 --command-config "./admin.properties.confluent" --describe --all-groups > consumer-groups.txt +complete -c kcong -f + +complete -c kcong -l bootstrap-server -a "(cat ~/.config/kafka/bootstrap-servers)" -d "Kafka bootstrap server" +complete -c kcong -l command-config -a "(find /home/willem/.config/kafka/clusters -type f)" -d "properties file" + +complete -c kcong -l describe +complete -c kcong -l all-groups +complete -c kcong -l group diff --git a/fish/completions/kcons.fish b/fish/completions/kcons.fish new file mode 100644 index 0000000..9305b5f --- /dev/null +++ b/fish/completions/kcons.fish @@ -0,0 +1,6 @@ +#kafka-consumer-groups.sh --bootstrap-server pkc-57q33g.westeurope.azure.confluent.cloud:9092 --command-config "./admin.properties.confluent" --describe --all-groups > consumer-groups.txt +complete -c kcons -f + +complete -c kcons -l bootstrap-server -a "(cat ~/.config/kafka/bootstrap-servers)" -d "Kafka bootstrap server" +complete -c kcons -l consumer.config -a "(find /home/willem/.config/kafka/clusters -type f)" -d "properties file" +complete -c kcons -l topic diff --git a/fish/completions/kprod.fish b/fish/completions/kprod.fish new file mode 100644 index 0000000..ddaaf71 --- /dev/null +++ b/fish/completions/kprod.fish @@ -0,0 +1,6 @@ +#kafka-consumer-groups.sh --bootstrap-server pkc-57q33g.westeurope.azure.confluent.cloud:9092 --command-config "./admin.properties.confluent" --describe --all-groups > consumer-groups.txt +complete -c kprod -f + +complete -c kprod -l bootstrap-server -a "(cat ~/.config/kafka/bootstrap-servers)" -d "Kafka bootstrap server" +complete -c kprod -l producer.config -a "(find /home/willem/.config/kafka/clusters -type f)" -d "properties file" +complete -c kprod -l topic diff --git a/fish/completions/nvm.fish b/fish/completions/nvm.fish new file mode 100644 index 0000000..14be1b7 --- /dev/null +++ b/fish/completions/nvm.fish @@ -0,0 +1,21 @@ +complete --command nvm --exclusive +complete --command nvm --exclusive --long version --description "Print version" +complete --command nvm --exclusive --long help --description "Print help" +complete --command nvm --long silent --description "Suppress standard output" + +complete --command nvm --exclusive --condition __fish_use_subcommand --arguments install --description "Download and activate the specified Node version" +complete --command nvm --exclusive --condition __fish_use_subcommand --arguments use --description "Activate the specified Node version in the current shell" +complete --command nvm --exclusive --condition __fish_use_subcommand --arguments list --description "List installed Node versions" +complete --command nvm --exclusive --condition __fish_use_subcommand --arguments list-remote --description "List available Node versions to install" +complete --command nvm --exclusive --condition __fish_use_subcommand --arguments current --description "Print the currently-active Node version" +complete --command nvm --exclusive --condition "__fish_seen_subcommand_from install" --arguments "( + test -e $nvm_data && string split ' ' <$nvm_data/.index +)" +complete --command nvm --exclusive --condition "__fish_seen_subcommand_from use" --arguments "(_nvm_list | string split ' ')" +complete --command nvm --exclusive --condition __fish_use_subcommand --arguments uninstall --description "Uninstall the specified Node version" +complete --command nvm --exclusive --condition "__fish_seen_subcommand_from uninstall" --arguments "( + _nvm_list | string split ' ' | string replace system '' +)" +complete --command nvm --exclusive --condition "__fish_seen_subcommand_from use uninstall" --arguments "( + set --query nvm_default_version && echo default +)" diff --git a/fish/completions/timedatectl.fish b/fish/completions/timedatectl.fish new file mode 100644 index 0000000..1d8a792 --- /dev/null +++ b/fish/completions/timedatectl.fish @@ -0,0 +1,52 @@ +# All subcommands that timedatectl knows - this is useful for later. +set -l commands status set-time set-timezone list-timezones set-local-rtc set-ntp + +# Disable file completions for the entire command +# because it does not take files anywhere +# Note that this can be undone by using "-F". +# +# File completions also need to be disabled +# if you want to have more control over what files are offered +# (e.g. just directories, or just files ending in ".mp3"). +complete -c timedatectl -f + +# This line offers the subcommands +# -"status", +# -"set-timezone", +# -"set-time" +# -"list-timezones" +# if no subcommand has been given so far. +# +# The `-n`/`--condition` option takes script as a string, which it executes. +# If it returns true, the completion is offered. +# Here the condition is the `__fish_seen_subcommand_from` helper function. +# It returns true if any of the given commands is used on the commandline, +# as determined by a simple heuristic. +# For more complex uses, you can write your own function. +# See e.g. the git completions for an example. +# +complete -c timedatectl -n "not __fish_seen_subcommand_from $commands" \ + -a "status set-time set-timezone list-timezones" + +# If the "set-timezone" subcommand is used, +# offer the output of `timedatectl list-timezones` as completions. +# Each line of output is used as a separate candidate, +# and anything after a tab is taken as the description. +# It's often useful to transform command output with `string` into that form. +complete -c timedatectl -n "__fish_seen_subcommand_from set-timezone" \ + -a "(timedatectl list-timezones)" + +# Completion candidates can also be described via `-d`, +# which is useful if the description is constant. +# Try to keep these short, because that means the user gets to see more at once. +complete -c timedatectl -n "not __fish_seen_subcommand_from $commands" \ + -a "set-local-rtc" -d "Maintain RTC in local time" + +# We can also limit options to certain subcommands by using conditions. +complete -c timedatectl -n "__fish_seen_subcommand_from set-local-rtc" \ + -l adjust-system-clock -d 'Synchronize system clock from the RTC' + +# These are simple options that can be used everywhere. +complete -c timedatectl -s h -l help -d 'Print a short help text and exit' +complete -c timedatectl -l version -d 'Print a short version string and exit' +complete -c timedatectl -l no-pager -d 'Do not pipe output into a pager' diff --git a/fish/conf.d/atuin.env.fish b/fish/conf.d/atuin.env.fish new file mode 100644 index 0000000..1abe1d1 --- /dev/null +++ b/fish/conf.d/atuin.env.fish @@ -0,0 +1,2 @@ + +#source "$HOME/.atuin/bin/env.fish" diff --git a/fish/conf.d/deno.fish b/fish/conf.d/deno.fish new file mode 100644 index 0000000..5aabcea --- /dev/null +++ b/fish/conf.d/deno.fish @@ -0,0 +1 @@ +source "/home/willem/.deno/env.fish" diff --git a/fish/conf.d/fish_frozen_key_bindings.fish b/fish/conf.d/fish_frozen_key_bindings.fish new file mode 100644 index 0000000..495aee9 --- /dev/null +++ b/fish/conf.d/fish_frozen_key_bindings.fish @@ -0,0 +1,14 @@ +# This file was created by fish when upgrading to version 4.3, to migrate +# the 'fish_key_bindings' variable from its old default scope (universal) +# to its new default scope (global). We recommend you delete this file +# and configure key bindings in ~/.config/fish/config.fish if needed. + +# set --global fish_key_bindings fish_default_key_bindings + +# Prior to version 4.3, fish shipped an event handler that runs +# `set --universal fish_key_bindings fish_default_key_bindings` +# whenever the fish_key_bindings variable is erased. +# This means that as long as any fish < 4.3 is still running on this system, +# we cannot complete the migration. +# As a workaround, erase the universal variable at every shell startup. +set --erase --universal fish_key_bindings diff --git a/fish/conf.d/fish_frozen_key_bindings.fish.bak b/fish/conf.d/fish_frozen_key_bindings.fish.bak new file mode 100644 index 0000000..495aee9 --- /dev/null +++ b/fish/conf.d/fish_frozen_key_bindings.fish.bak @@ -0,0 +1,14 @@ +# This file was created by fish when upgrading to version 4.3, to migrate +# the 'fish_key_bindings' variable from its old default scope (universal) +# to its new default scope (global). We recommend you delete this file +# and configure key bindings in ~/.config/fish/config.fish if needed. + +# set --global fish_key_bindings fish_default_key_bindings + +# Prior to version 4.3, fish shipped an event handler that runs +# `set --universal fish_key_bindings fish_default_key_bindings` +# whenever the fish_key_bindings variable is erased. +# This means that as long as any fish < 4.3 is still running on this system, +# we cannot complete the migration. +# As a workaround, erase the universal variable at every shell startup. +set --erase --universal fish_key_bindings diff --git a/fish/conf.d/fish_frozen_theme.fish b/fish/conf.d/fish_frozen_theme.fish new file mode 100644 index 0000000..3761338 --- /dev/null +++ b/fish/conf.d/fish_frozen_theme.fish @@ -0,0 +1,45 @@ +# This file was created by fish when upgrading to version 4.3, to migrate +# theme variables from universal to global scope. +# Don't edit this file, as it will be written by the web-config tool (`fish_config`). +# To customize your theme, delete this file and see +# help interactive#syntax-highlighting +# or +# man fish-interactive | less +/^SYNTAX.HIGHLIGHTING +# for appropriate commands to add to ~/.config/fish/config.fish instead. +# See also the release notes for fish 4.3.0 (run `help relnotes`). + +set --global fish_color_autosuggestion 555 +set --global fish_color_cancel -r +set --global fish_color_command brblue +set --global fish_color_comment brblack +set --global fish_color_cwd brgreen +set --global fish_color_cwd_root brred +set --global fish_color_end brgreen +set --global fish_color_error brred +set --global fish_color_escape bryellow +set --global fish_color_history_current --bold +set --global fish_color_host normal +set --global fish_color_host_remote bryellow +set --global fish_color_normal normal +set --global fish_color_operator brmagenta +set --global fish_color_param brcyan +set --global fish_color_quote bryellow +set --global fish_color_redirection brmagenta --bold +set --global fish_color_search_match bryellow --background=brblack --bold +set --global fish_color_selection brwhite --background=brblack --bold +set --global fish_color_status brred +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 yellow -i +set --global fish_pager_color_prefix normal --bold --underline +set --global fish_pager_color_progress brwhite --background=cyan --bold +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 -r +set --global fish_pager_color_selected_completion +set --global fish_pager_color_selected_description +set --global fish_pager_color_selected_prefix diff --git a/fish/conf.d/fish_frozen_theme.fish.bak b/fish/conf.d/fish_frozen_theme.fish.bak new file mode 100644 index 0000000..3761338 --- /dev/null +++ b/fish/conf.d/fish_frozen_theme.fish.bak @@ -0,0 +1,45 @@ +# This file was created by fish when upgrading to version 4.3, to migrate +# theme variables from universal to global scope. +# Don't edit this file, as it will be written by the web-config tool (`fish_config`). +# To customize your theme, delete this file and see +# help interactive#syntax-highlighting +# or +# man fish-interactive | less +/^SYNTAX.HIGHLIGHTING +# for appropriate commands to add to ~/.config/fish/config.fish instead. +# See also the release notes for fish 4.3.0 (run `help relnotes`). + +set --global fish_color_autosuggestion 555 +set --global fish_color_cancel -r +set --global fish_color_command brblue +set --global fish_color_comment brblack +set --global fish_color_cwd brgreen +set --global fish_color_cwd_root brred +set --global fish_color_end brgreen +set --global fish_color_error brred +set --global fish_color_escape bryellow +set --global fish_color_history_current --bold +set --global fish_color_host normal +set --global fish_color_host_remote bryellow +set --global fish_color_normal normal +set --global fish_color_operator brmagenta +set --global fish_color_param brcyan +set --global fish_color_quote bryellow +set --global fish_color_redirection brmagenta --bold +set --global fish_color_search_match bryellow --background=brblack --bold +set --global fish_color_selection brwhite --background=brblack --bold +set --global fish_color_status brred +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 yellow -i +set --global fish_pager_color_prefix normal --bold --underline +set --global fish_pager_color_progress brwhite --background=cyan --bold +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 -r +set --global fish_pager_color_selected_completion +set --global fish_pager_color_selected_description +set --global fish_pager_color_selected_prefix diff --git a/fish/conf.d/nvm.fish b/fish/conf.d/nvm.fish new file mode 100644 index 0000000..7545699 --- /dev/null +++ b/fish/conf.d/nvm.fish @@ -0,0 +1,28 @@ +set --query XDG_DATA_HOME || set --local XDG_DATA_HOME ~/.local/share +set --query nvm_mirror || set --global nvm_mirror https://nodejs.org/dist +set --query nvm_data || set --global nvm_data $XDG_DATA_HOME/nvm + +function _nvm_install --on-event nvm_install + test ! -d $nvm_data && command mkdir -p $nvm_data + echo "Downloading the Node distribution index..." 2>/dev/null + _nvm_index_update +end + +function _nvm_update --on-event nvm_update + set --query --universal nvm_data && set --erase --universal nvm_data + set --query --universal nvm_mirror && set --erase --universal nvm_mirror + set --query nvm_mirror || set --global nvm_mirror https://nodejs.org/dist +end + +function _nvm_uninstall --on-event nvm_uninstall + command rm -rf $nvm_data + + set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version + + set --names | string replace --filter --regex -- "^nvm" "set --erase nvm" | source + functions --erase (functions --all | string match --entire --regex -- "^_nvm_") +end + +if status is-interactive && set --query nvm_default_version && ! set --query nvm_current_version + nvm use --silent $nvm_default_version +end diff --git a/fish/config.fish b/fish/config.fish new file mode 100644 index 0000000..acb5231 --- /dev/null +++ b/fish/config.fish @@ -0,0 +1,27 @@ +set -gx EDITOR nvim + +if status is-interactive + # Commands to run in interactive sessions can go here +end + +# pnpm +set -gx PNPM_HOME "/home/willem/.local/share/pnpm" +if not string match -q -- $PNPM_HOME $PATH + set -gx PATH "$PNPM_HOME" $PATH +end +# pnpm end + +# bun +set --export BUN_INSTALL "$HOME/.bun" +set --export PATH $HOME/.local/share/nvm/v25.6.1/bin $BUN_INSTALL/bin $PATH +set --export DOTNET_ROOT "$HOME/.dotnet" +set --export PATH $DOTNET_ROOT $DOTNET_ROOT/tools $PATH +set --export PATH $BUN_INSTALL/bin $PATH +set --export PATH /usr/local/go/bin $PATH +set --export PATH $HOME/Repos/Work/flutter/bin $PATH +set --export PATH $HOME/.pub-cache/bin $PATH + +set --export CHROME_DEVEL_SANDBOX "/opt/google/chrome/chrome-sandbox" + +# opencode +fish_add_path /home/willem/.opencode/bin diff --git a/fish/fish_plugins b/fish/fish_plugins new file mode 100644 index 0000000..9673b42 --- /dev/null +++ b/fish/fish_plugins @@ -0,0 +1,2 @@ +jorgebucaran/fisher +jorgebucaran/nvm.fish diff --git a/fish/fish_variables b/fish/fish_variables new file mode 100644 index 0000000..c955974 --- /dev/null +++ b/fish/fish_variables @@ -0,0 +1,9 @@ +# This file contains fish universal variable definitions. +# VERSION: 3.0 +SETUVAR --export EDITOR:nvim +SETUVAR __fish_initialized:4300 +SETUVAR _fisher_jorgebucaran_2F_fisher_files:\x7e/\x2econfig/fish/functions/fisher\x2efish\x1e\x7e/\x2econfig/fish/completions/fisher\x2efish +SETUVAR _fisher_jorgebucaran_2F_nvm_2E_fish_files:\x7e/\x2econfig/fish/functions/_nvm_index_update\x2efish\x1e\x7e/\x2econfig/fish/functions/_nvm_list\x2efish\x1e\x7e/\x2econfig/fish/functions/_nvm_version_activate\x2efish\x1e\x7e/\x2econfig/fish/functions/_nvm_version_deactivate\x2efish\x1e\x7e/\x2econfig/fish/functions/nvm\x2efish\x1e\x7e/\x2econfig/fish/conf\x2ed/nvm\x2efish\x1e\x7e/\x2econfig/fish/completions/nvm\x2efish +SETUVAR _fisher_plugins:jorgebucaran/fisher\x1ejorgebucaran/nvm\x2efish +SETUVAR _fisher_upgraded_to_4_4:\x1d +SETUVAR fish_user_paths:/home/willem/\x2eopencode/bin\x1e/home/willem/\x2elocal/bin\x1e/home/willem/\x2ecargo/bin\x1e/usr/local/kafka/bin diff --git a/fish/functions/_nvm_index_update.fish b/fish/functions/_nvm_index_update.fish new file mode 100644 index 0000000..c66753d --- /dev/null +++ b/fish/functions/_nvm_index_update.fish @@ -0,0 +1,20 @@ +function _nvm_index_update + test ! -d $nvm_data && command mkdir -p $nvm_data + + set --local index $nvm_data/.index + + if not command curl -q --location --silent $nvm_mirror/index.tab >$index.temp + command rm -f $index.temp + echo "nvm: Can't update index, host unavailable: \"$nvm_mirror\"" >&2 + return 1 + end + + command awk -v OFS=\t ' + /v0.9.12/ { exit } # Unsupported + NR > 1 { + print $1 (NR == 2 ? " latest" : $10 != "-" ? " lts/" tolower($10) : "") + } + ' $index.temp >$index + + command rm -f $index.temp +end diff --git a/fish/functions/_nvm_list.fish b/fish/functions/_nvm_list.fish new file mode 100644 index 0000000..1623bb8 --- /dev/null +++ b/fish/functions/_nvm_list.fish @@ -0,0 +1,14 @@ +function _nvm_list + set --local versions $nvm_data/* + + set --query versions[1] && + string match --entire --regex -- ( + string replace --all -- $nvm_data/ "" $versions | + string match --regex -- "v\d.+" | + string escape --style=regex | + string join "|" + ) <$nvm_data/.index + + command --all node | + string match --quiet --invert --regex -- "^$nvm_data" && echo system +end diff --git a/fish/functions/_nvm_version_activate.fish b/fish/functions/_nvm_version_activate.fish new file mode 100644 index 0000000..f7dfef7 --- /dev/null +++ b/fish/functions/_nvm_version_activate.fish @@ -0,0 +1,4 @@ +function _nvm_version_activate --argument-names ver + set --global --export nvm_current_version $ver + set --prepend PATH $nvm_data/$ver/bin +end diff --git a/fish/functions/_nvm_version_deactivate.fish b/fish/functions/_nvm_version_deactivate.fish new file mode 100644 index 0000000..24dd36e --- /dev/null +++ b/fish/functions/_nvm_version_deactivate.fish @@ -0,0 +1,5 @@ +function _nvm_version_deactivate --argument-names ver + test "$nvm_current_version" = "$ver" && set --erase nvm_current_version + set --local index (contains --index -- $nvm_data/$ver/bin $PATH) && + set --erase PATH[$index] +end diff --git a/fish/functions/azpr.fish b/fish/functions/azpr.fish new file mode 100644 index 0000000..bd2e94b --- /dev/null +++ b/fish/functions/azpr.fish @@ -0,0 +1,3 @@ +function azpr + az repos pr create +end diff --git a/fish/functions/checkfolder.fish b/fish/functions/checkfolder.fish new file mode 100644 index 0000000..418998d --- /dev/null +++ b/fish/functions/checkfolder.fish @@ -0,0 +1,3 @@ +function checkfolder --description "Shows folders bigger than 1 Gb" + du -h $argv 2>/dev/null | grep '[0-9\.]\+G' +end diff --git a/fish/functions/fisher.fish b/fish/functions/fisher.fish new file mode 100644 index 0000000..4f5be4f --- /dev/null +++ b/fish/functions/fisher.fish @@ -0,0 +1,251 @@ +function fisher --argument-names cmd --description "A plugin manager for Fish" + set --query fisher_path || set --local fisher_path $__fish_config_dir + set --local fisher_version 4.4.8 + set --local fish_plugins $__fish_config_dir/fish_plugins + + switch "$cmd" + case -v --version + echo "fisher, version $fisher_version" + case "" -h --help + echo "Usage: fisher install Install plugins" + echo " fisher remove Remove installed plugins" + echo " fisher uninstall Remove installed plugins (alias)" + echo " fisher update Update installed plugins" + echo " fisher update Update all installed plugins" + echo " fisher list [] List installed plugins matching regex" + echo "Options:" + echo " -v, --version Print version" + echo " -h, --help Print this help message" + echo "Variables:" + echo " \$fisher_path Plugin installation path. Default: $__fish_config_dir" | string replace --regex -- $HOME \~ + case ls list + string match --entire --regex -- "$argv[2]" $_fisher_plugins + case install update remove uninstall + isatty || read --local --null --array stdin && set --append argv $stdin + + test "$cmd" = uninstall && set cmd remove + + set --local install_plugins + set --local update_plugins + set --local remove_plugins + set --local arg_plugins $argv[2..-1] + set --local old_plugins $_fisher_plugins + set --local new_plugins + + test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins | string replace -- \~ ~) + + if ! set --query argv[2] + if test "$cmd" != update + echo "fisher: Not enough arguments for command: \"$cmd\"" >&2 && return 1 + else if ! set --query file_plugins + echo "fisher: \"$fish_plugins\" file not found: \"$cmd\"" >&2 && return 1 + end + set arg_plugins $file_plugins + else if test "$cmd" = install && ! set --query old_plugins[1] + set --append arg_plugins $file_plugins + end + + for plugin in $arg_plugins + set plugin (test -e "$plugin" && realpath $plugin || string lower -- $plugin) + contains -- "$plugin" $new_plugins || set --append new_plugins $plugin + end + + if set --query argv[2] + for plugin in $new_plugins + if contains -- "$plugin" $old_plugins + test "$cmd" = remove && + set --append remove_plugins $plugin || + set --append update_plugins $plugin + else if test "$cmd" = install + set --append install_plugins $plugin + else + echo "fisher: Plugin not installed: \"$plugin\"" >&2 && return 1 + end + end + else + for plugin in $new_plugins + contains -- "$plugin" $old_plugins && + set --append update_plugins $plugin || + set --append install_plugins $plugin + end + + for plugin in $old_plugins + contains -- "$plugin" $new_plugins || set --append remove_plugins $plugin + end + end + + set --local pid_list + set --local source_plugins + set --local fetch_plugins $update_plugins $install_plugins + set --local fish_path (status fish-path) + + echo (set_color --bold)fisher $cmd version $fisher_version(set_color normal) + + for plugin in $fetch_plugins + set --local source (command mktemp -d) + set --append source_plugins $source + + command mkdir -p $source/{completions,conf.d,themes,functions} + + $fish_path --command " + if test -e $plugin + command cp -Rf $plugin/* $source + else + set resp (command mktemp) + set temp (command mktemp -d) + set repo (string split -- \@ $plugin) || set repo[2] HEAD + + if set path (string replace --regex -- '^(https://)?gitlab.com/' '' \$repo[1]) + set name (string split -- / \$path)[-1] + set url https://gitlab.com/\$path/-/archive/\$repo[2]/\$name-\$repo[2].tar.gz + else + set url https://api.github.com/repos/\$repo[1]/tarball/\$repo[2] + end + + echo Fetching (set_color --underline)\$url(set_color normal) + + set http (command curl -q --silent -L -o \$resp -w %{http_code} \$url) + + if test \"\$http\" = 200 && command tar -xzC \$temp -f \$resp 2>/dev/null + command cp -Rf \$temp/*/* $source + else if test \"\$http\" = 403 + echo fisher: GitHub API rate limit exceeded \(HTTP 403\) >&2 + command rm -rf $source + else + echo fisher: Invalid plugin name or host unavailable: \\\"$plugin\\\" >&2 + command rm -rf $source + end + + command rm -rf \$temp + end + + set files $source/* && string match --quiet --regex -- .+\.fish\\\$ \$files + " & + + set --append pid_list (jobs --last --pid) + end + + wait $pid_list 2>/dev/null + + for plugin in $fetch_plugins + if set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] && test ! -e $source + if set --local index (contains --index -- "$plugin" $install_plugins) + set --erase install_plugins[$index] + else + set --erase update_plugins[(contains --index -- "$plugin" $update_plugins)] + end + end + end + + for plugin in $update_plugins $remove_plugins + if set --local index (contains --index -- "$plugin" $_fisher_plugins) + set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files + + if contains -- "$plugin" $remove_plugins + for name in (string replace --filter --regex -- '.+/conf\.d/([^/]+)\.fish$' '$1' $$plugin_files_var) + emit {$name}_uninstall + end + printf "%s\n" Removing\ (set_color red --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~ + set --erase _fisher_plugins[$index] + end + + command rm -rf (string replace -- \~ ~ $$plugin_files_var) + + functions --erase (string replace --filter --regex -- '.+/functions/([^/]+)\.fish$' '$1' $$plugin_files_var) + + for name in (string replace --filter --regex -- '.+/completions/([^/]+)\.fish$' '$1' $$plugin_files_var) + complete --erase --command $name + end + + set --erase $plugin_files_var + end + end + + if set --query update_plugins[1] || set --query install_plugins[1] + command mkdir -p $fisher_path/{functions,themes,conf.d,completions} + end + + for plugin in $update_plugins $install_plugins + set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] + set --local files $source/{functions,themes,conf.d,completions}/* + + if set --local index (contains --index -- $plugin $install_plugins) + set --local user_files $fisher_path/{functions,themes,conf.d,completions}/* + set --local conflict_files + + for file in (string replace -- $source/ $fisher_path/ $files) + contains -- $file $user_files && set --append conflict_files $file + end + + if set --query conflict_files[1] && set --erase install_plugins[$index] + echo -s "fisher: Cannot install \"$plugin\": please remove or move conflicting files first:" \n" "$conflict_files >&2 + continue + end + end + + for file in (string replace -- $source/ "" $files) + command cp -RLf $source/$file $fisher_path/$file + end + + set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files + + set --query files[1] && set --universal $plugin_files_var (string replace -- $source $fisher_path $files | string replace -- ~ \~) + + contains -- $plugin $_fisher_plugins || set --universal --append _fisher_plugins $plugin + contains -- $plugin $install_plugins && set --local event install || set --local event update + + printf "%s\n" Installing\ (set_color --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~ + + for file in (string match --regex -- '.+/[^/]+\.fish$' $$plugin_files_var | string replace -- \~ ~) + source $file + if set --local name (string replace --regex -- '.+conf\.d/([^/]+)\.fish$' '$1' $file) + emit {$name}_$event + end + end + end + + command rm -rf $source_plugins + + if set --query _fisher_plugins[1] + set --local commit_plugins + + for plugin in $file_plugins + contains -- (string lower -- $plugin) (string lower -- $_fisher_plugins) && set --append commit_plugins $plugin + end + + for plugin in $_fisher_plugins + contains -- (string lower -- $plugin) (string lower -- $commit_plugins) || set --append commit_plugins $plugin + end + + string replace --regex -- $HOME \~ $commit_plugins >$fish_plugins + else + set --erase _fisher_plugins + command rm -f $fish_plugins + end + + set --local total (count $install_plugins) (count $update_plugins) (count $remove_plugins) + + test "$total" != "0 0 0" && echo (string join ", " ( + test $total[1] = 0 || echo "Installed $total[1]") ( + test $total[2] = 0 || echo "Updated $total[2]") ( + test $total[3] = 0 || echo "Removed $total[3]") + ) plugin/s + case \* + echo "fisher: Unknown command: \"$cmd\"" >&2 && return 1 + end +end + +if ! set --query _fisher_upgraded_to_4_4 + set --universal _fisher_upgraded_to_4_4 + if functions --query _fisher_list + set --query XDG_DATA_HOME[1] || set --local XDG_DATA_HOME ~/.local/share + command rm -rf $XDG_DATA_HOME/fisher + functions --erase _fisher_{list,plugin_parse} + fisher update >/dev/null 2>/dev/null + else + for var in (set --names | string match --entire --regex '^_fisher_.+_files$') + set $var (string replace -- ~ \~ $$var) + end + functions --erase _fisher_fish_postexec + end +end diff --git a/fish/functions/ga.fish b/fish/functions/ga.fish new file mode 100644 index 0000000..01118e0 --- /dev/null +++ b/fish/functions/ga.fish @@ -0,0 +1,3 @@ +function ga + git add . +end diff --git a/fish/functions/gc.fish b/fish/functions/gc.fish new file mode 100644 index 0000000..bbf245d --- /dev/null +++ b/fish/functions/gc.fish @@ -0,0 +1,3 @@ +function gc + git commit -m $argv +end diff --git a/fish/functions/gcb.fish b/fish/functions/gcb.fish new file mode 100644 index 0000000..976566c --- /dev/null +++ b/fish/functions/gcb.fish @@ -0,0 +1,3 @@ +function gcb + git checkout -B $argv +end diff --git a/fish/functions/gp.fish b/fish/functions/gp.fish new file mode 100644 index 0000000..ac19e3c --- /dev/null +++ b/fish/functions/gp.fish @@ -0,0 +1,4 @@ +function gp + git push +end + diff --git a/fish/functions/gpus.fish b/fish/functions/gpus.fish new file mode 100644 index 0000000..f787c17 --- /dev/null +++ b/fish/functions/gpus.fish @@ -0,0 +1,3 @@ +function gpus + git push --set-upstream origin $(git status | head -n +1 | awk '{print $NF}') +end diff --git a/fish/functions/kconc.fish b/fish/functions/kconc.fish new file mode 100644 index 0000000..adc52fd --- /dev/null +++ b/fish/functions/kconc.fish @@ -0,0 +1,2 @@ +#kafka-consumer-groups.sh --bootstrap-server pkc-57q33g.westeurope.azure.confluent.cloud:9092 --command-config "./admin.properties.confluent" --describe --all-groups > consumer-groups.txt + diff --git a/fish/functions/kcong.fish b/fish/functions/kcong.fish new file mode 100644 index 0000000..be942cd --- /dev/null +++ b/fish/functions/kcong.fish @@ -0,0 +1,3 @@ +function kcong + kafka-consumer-groups.sh $argv +end diff --git a/fish/functions/kcons.fish b/fish/functions/kcons.fish new file mode 100644 index 0000000..874ff67 --- /dev/null +++ b/fish/functions/kcons.fish @@ -0,0 +1,3 @@ +function kcons + kafka-console-consumer.sh $argv +end diff --git a/fish/functions/kprod.fish b/fish/functions/kprod.fish new file mode 100644 index 0000000..d8b39f4 --- /dev/null +++ b/fish/functions/kprod.fish @@ -0,0 +1,3 @@ +function kprod + kafka-console-producer.sh $argv +end diff --git a/fish/functions/n.fish b/fish/functions/n.fish new file mode 100644 index 0000000..a5e0b14 --- /dev/null +++ b/fish/functions/n.fish @@ -0,0 +1,4 @@ +function n + nvim . +end + diff --git a/fish/functions/nvm.fish b/fish/functions/nvm.fish new file mode 100644 index 0000000..64d94c5 --- /dev/null +++ b/fish/functions/nvm.fish @@ -0,0 +1,237 @@ +function nvm --description "Node version manager" + for silent in --silent -s + if set --local index (contains --index -- $silent $argv) + set --erase argv[$index] && break + end + set --erase silent + end + + set --local cmd $argv[1] + set --local ver $argv[2] + + if set --query silent && ! set --query cmd[1] + echo "nvm: Version number not specified (see nvm -h for usage)" >&2 + return 1 + end + + if ! set --query ver[1] && contains -- "$cmd" install use + for file in .nvmrc .node-version + set file (_nvm_find_up $PWD $file) && read ver <$file && break + end + + if ! set --query ver[1] + echo "nvm: Invalid version or missing \".nvmrc\" file" >&2 + return 1 + end + end + + set --local their_version $ver + + switch "$cmd" + case -v --version + echo "nvm, version 2.2.18" + case "" -h --help + echo "Usage: nvm install Download and activate the specified Node version" + echo " nvm install Install the version specified in the nearest .nvmrc file" + echo " nvm use Activate the specified Node version in the current shell" + echo " nvm use Activate the version specified in the nearest .nvmrc file" + echo " nvm list List installed Node versions" + echo " nvm list-remote List available Node versions to install" + echo " nvm list-remote List Node versions matching a given regex pattern" + echo " nvm current Print the currently-active Node version" + echo " nvm uninstall Uninstall the specified Node version" + echo "Options:" + echo " -s, --silent Suppress standard output" + echo " -v, --version Print the version of nvm" + echo " -h, --help Print this help message" + echo "Variables:" + echo " nvm_arch Override architecture, e.g. x64-musl" + echo " nvm_mirror Use a mirror for downloading Node binaries" + echo " nvm_default_version Set the default version for new shells" + echo " nvm_default_packages Install a list of packages every time a Node version is installed" + echo " nvm_data Set a custom directory for storing nvm data" + echo "Examples:" + echo " nvm install latest Install the latest version of Node" + echo " nvm use 14.15.1 Use Node version 14.15.1" + echo " nvm use system Activate the system's Node version" + + case install + _nvm_index_update + + string match --entire --regex -- (_nvm_version_match $ver) <$nvm_data/.index | read ver alias + + if ! set --query ver[1] + echo "nvm: Invalid version number or alias: \"$their_version\"" >&2 + return 1 + end + + if test ! -e $nvm_data/$ver + set --local os (command uname -s | string lower) + set --local ext tar.gz + set --local arch (command uname -m) + set --local tarcmd tar + + switch $os + case aix + set arch ppc64 + case sunos + case linux + case darwin + case {msys_nt,mingw\*_nt}\* + set os win + set ext zip + set tarcmd bsdtar + case \* + echo "nvm: Unsupported operating system: \"$os\"" >&2 + return 1 + end + + switch $arch + case i\*86 + set arch x86 + case x86_64 + set arch x64 + case arm64 + string match --regex --quiet "v(?\d+)" $ver + if test "$os" = darwin -a $major -lt 16 + set arch x64 + end + case armv6 armv6l + set arch armv6l + case armv7 armv7l + set arch armv7l + case armv8 armv8l aarch64 + set arch arm64 + end + + set --query nvm_arch && set arch $nvm_arch + + set --local dir "node-$ver-$os-$arch" + set --local url $nvm_mirror/$ver/$dir.$ext + + command mkdir -p $nvm_data/$ver + + if ! set --query silent + echo -e "Installing Node \x1b[1m$ver\x1b[22m $alias" + echo -e "Fetching \x1b[4m$url\x1b[24m\x1b[7m" + end + + if ! command curl -q $silent --progress-bar --location $url | + command $tarcmd --extract --gzip --directory $nvm_data/$ver 2>/dev/null + command rm -rf $nvm_data/$ver + echo -e "\033[F\33[2K\x1b[0mnvm: Invalid mirror or host unavailable: \"$url\"" >&2 + return 1 + end + + set --query silent || echo -en "\033[F\33[2K\x1b[0m" + + if test "$os" = win + command mv $nvm_data/$ver/$dir $nvm_data/$ver/bin + else + command mv $nvm_data/$ver/$dir/* $nvm_data/$ver + command rm -rf $nvm_data/$ver/$dir + end + end + + if test $ver != "$nvm_current_version" + set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version + _nvm_version_activate $ver + + set --query nvm_default_packages[1] && npm install --global $silent $nvm_default_packages + end + + set --query silent || printf "Now using Node %s (npm %s) %s\n" (_nvm_node_info) + case use + test $ver = default && set ver $nvm_default_version + _nvm_list | string match --entire --regex -- (_nvm_version_match $ver) | read ver __ + + if ! set --query ver[1] + echo "nvm: Can't use Node \"$their_version\", version must be installed first" >&2 + return 1 + end + + if test $ver != "$nvm_current_version" + set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version + test $ver != system && _nvm_version_activate $ver + end + + set --query silent || printf "Now using Node %s (npm %s) %s\n" (_nvm_node_info) + case uninstall + if test -z "$ver" + echo "nvm: Not enough arguments for command: \"$cmd\"" >&2 + return 1 + end + + test $ver = default && test ! -z "$nvm_default_version" && set ver $nvm_default_version + + _nvm_list | string match --entire --regex -- (_nvm_version_match $ver) | read ver __ + + if ! set -q ver[1] + echo "nvm: Node version not installed or invalid: \"$their_version\"" >&2 + return 1 + end + + set --query silent || printf "Uninstalling Node %s %s\n" $ver (string replace ~ \~ "$nvm_data/$ver/bin/node") + + _nvm_version_deactivate $ver + + command rm -rf $nvm_data/$ver + case current + _nvm_current + case ls list + _nvm_list | _nvm_list_format (_nvm_current) $argv[2] + case lsr {ls,list}-remote + _nvm_index_update || return + _nvm_list | command awk ' + FILENAME == "-" && (is_local[$1] = FNR == NR) { next } { + print $0 (is_local[$1] ? " ✓" : "") + } + ' - $nvm_data/.index | _nvm_list_format (_nvm_current) $argv[2] + case \* + echo "nvm: Unknown command or option: \"$cmd\" (see nvm -h for usage)" >&2 + return 1 + end +end + +function _nvm_find_up --argument-names path file + test -e "$path/$file" && echo $path/$file || begin + test ! -z "$path" || return + _nvm_find_up (string replace --regex -- '/[^/]*$' "" $path) $file + end +end + +function _nvm_version_match --argument-names ver + string replace --regex -- '^v?(\d+|\d+\.\d+)$' 'v$1.' $ver | + string replace --filter --regex -- '^v?(\d+)' 'v$1' | + string escape --style=regex || string lower '\b'$ver'(?:/\w+)?$' +end + +function _nvm_list_format --argument-names current regex + command awk -v current="$current" -v regex="$regex" ' + $0 ~ regex { + aliases[versions[i++] = $1] = $2 " " $3 + pad = (n = length($1)) > pad ? n : pad + } + END { + if (!i) exit 1 + while (i--) + printf((current == versions[i] ? " ▶ " : " ") "%"pad"s %s\n", + versions[i], aliases[versions[i]]) + } + ' +end + +function _nvm_current + command --search --quiet node || return + set --query nvm_current_version && echo $nvm_current_version || echo system +end + +function _nvm_node_info + set --local npm_path (string replace bin/npm-cli.js "" (realpath (command --search npm))) + test -f $npm_path/package.json || set --local npm_version_default (command npm --version) + command node --eval " + console.log(process.version) + console.log('$npm_version_default' ? '$npm_version_default': require('$npm_path/package.json').version) + console.log(process.execPath) + " | string replace -- ~ \~ +end diff --git a/fish/functions/pdf.fish b/fish/functions/pdf.fish new file mode 100644 index 0000000..9064ad7 --- /dev/null +++ b/fish/functions/pdf.fish @@ -0,0 +1,3 @@ +function pdf --description "Convert all files in current folder to pdf" + find docs -name "*.md" -exec sh -c 'mkdir -p "pdf/$(dirname "$1")" && pandoc "$1" -o "pdf/${1%.md}.pdf" --pdf-engine=pdflatex' _ {} \; +end diff --git a/fish/functions/streamizinit.fish b/fish/functions/streamizinit.fish new file mode 100644 index 0000000..4f43cb4 --- /dev/null +++ b/fish/functions/streamizinit.fish @@ -0,0 +1,4 @@ +function streamizinit + dotnet add package Streamiz.Kafka.Net --version 1.8.1 + dotnet add package Streamiz.Kafka.Net.SchemaRegistry.SerDes --version 1.8.1 +end diff --git a/fish/functions/toreview.fish b/fish/functions/toreview.fish new file mode 100644 index 0000000..eb87c03 --- /dev/null +++ b/fish/functions/toreview.fish @@ -0,0 +1,7 @@ +function toreview + az repos pr list --reviewer EDA-REVIEW --project governance --output table + echo "---" + az repos pr list --reviewer EDA-REVIEW --project EDA-IAC --output table + echo "---" + az repos pr list --reviewer EDA-REVIEW --project EDA-SCHEMAS --output table +end diff --git a/fish/functions/wip.fish b/fish/functions/wip.fish new file mode 100644 index 0000000..a7442d6 --- /dev/null +++ b/fish/functions/wip.fish @@ -0,0 +1,5 @@ +function ga + git add . + git commit -m "WIP" + git push +end diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..6cc35a7 --- /dev/null +++ b/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/bash + + +# Follow neovim installation in README + +# Add symbolic links +ln -s $1/dotfiles/nvim /home/willem/.config/ +ln -s $1/dotfiles/zellij /home/willem/.config/ +ln -s $1/dotfiles/fish /home/willem/.config/ +#https://docs.ansible.com/projects/ansible/latest/installation_guide/intro_installation.html#installing-and-upgrading-ansible +pipx install --include-deps ansible + diff --git a/kafka/test.sh b/kafka/test.sh new file mode 100644 index 0000000..e69de29 diff --git a/nvim/lua/config/functions.lua b/nvim/lua/config/functions.lua new file mode 100644 index 0000000..09c59f9 --- /dev/null +++ b/nvim/lua/config/functions.lua @@ -0,0 +1,62 @@ +local function delete_qf_items() + local mode = vim.api.nvim_get_mode()['mode'] + + local start_idx + local count + + if mode == 'n' then + -- Normal mode + start_idx = vim.fn.line('.') + count = vim.v.count > 0 and vim.v.count or 1 + else + -- Visual mode + local v_start_idx = vim.fn.line('v') + local v_end_idx = vim.fn.line('.') + + start_idx = math.min(v_start_idx, v_end_idx) + count = math.abs(v_end_idx - v_start_idx) + 1 + + -- Go back to normal + vim.api.nvim_feedkeys( + vim.api.nvim_replace_termcodes( + '', -- what to escape + true, -- Vim leftovers + false, -- Also replace ``? + true -- Replace keycodes (like ``)? + ), + 'x', -- Mode flag + false -- Should be false, since we already `nvim_replace_termcodes()` + ) + end + + local qflist = vim.fn.getqflist() + + for _ = 1, count, 1 do + table.remove(qflist, start_idx) + end + + vim.fn.setqflist(qflist, 'r') + vim.fn.cursor(start_idx, 1) +end + +vim.api.nvim_create_autocmd('FileType', { + group = custom_group, + pattern = 'qf', + callback = function() + -- Do not show quickfix in buffer lists. + vim.api.nvim_buf_set_option(0, 'buflisted', false) + + -- Escape closes quickfix window. + vim.keymap.set( + 'n', + '', + 'cclose', + { buffer = true, remap = false, silent = true } + ) + + -- `dd` deletes an item from the list. + vim.keymap.set('n', 'dd', delete_qf_items, { buffer = true }) + vim.keymap.set('x', 'd', delete_qf_items, { buffer = true }) + end, + desc = 'Quickfix tweaks', +}) diff --git a/nvim/lua/config/init.lua b/nvim/lua/config/init.lua index 1f57ff0..1815495 100644 --- a/nvim/lua/config/init.lua +++ b/nvim/lua/config/init.lua @@ -2,13 +2,15 @@ require("config.lazy") require("config.langservers.lua") require("config.langservers.csharp") +require("config.langservers.java") require("config.langservers.docker") require("config.langservers.docker-compose") -require("config.langservers.systemd") require("config.langservers.terraform") require("config.langservers.marksman") require("config.langservers.rust") -require("config.langservers.typescript") +require("config.langservers.python") +require("config.langservers.cue") require("config.cmp") require("config.treesitter") +require("config.functions") diff --git a/nvim/lua/config/langservers/csharp.lua b/nvim/lua/config/langservers/csharp.lua index 9c97dcb..70bf8ba 100644 --- a/nvim/lua/config/langservers/csharp.lua +++ b/nvim/lua/config/langservers/csharp.lua @@ -1 +1,21 @@ -require'lspconfig'.csharp_ls.setup{} +local util = require('lspconfig.util') + +vim.lsp.config("csharp_ls", { + cmd = { 'csharp-ls' }, + root_dir = function(bufnr, on_dir) + local fname = vim.api.nvim_buf_get_name(bufnr) + on_dir(util.root_pattern('*.sln', '*.slnx', '*.csproj')(fname)) + end, + filetypes = { 'cs' }, + init_options = { + AutomaticWorkspaceInit = true, + }, + get_language_id = function(_, ft) + if ft == 'cs' then + return 'csharp' + end + return ft + end, +}) + +vim.lsp.enable("csharp_ls") diff --git a/nvim/lua/config/langservers/cue.lua b/nvim/lua/config/langservers/cue.lua new file mode 100644 index 0000000..4dfada3 --- /dev/null +++ b/nvim/lua/config/langservers/cue.lua @@ -0,0 +1 @@ +vim.lsp.enable('cue') diff --git a/nvim/lua/config/langservers/docker-compose.lua b/nvim/lua/config/langservers/docker-compose.lua index d4f6e7e..ec0b543 100644 --- a/nvim/lua/config/langservers/docker-compose.lua +++ b/nvim/lua/config/langservers/docker-compose.lua @@ -1 +1 @@ -require'lspconfig'.docker_compose_language_service.setup{} +vim.lsp.config["docker_compose_language_service"] = {} diff --git a/nvim/lua/config/langservers/docker.lua b/nvim/lua/config/langservers/docker.lua index 270ea7b..89d21ca 100644 --- a/nvim/lua/config/langservers/docker.lua +++ b/nvim/lua/config/langservers/docker.lua @@ -1 +1 @@ -require'lspconfig'.dockerls.setup{} +vim.lsp.config["dockerls"] = {} diff --git a/nvim/lua/config/langservers/java.lua b/nvim/lua/config/langservers/java.lua new file mode 100644 index 0000000..ca67a20 --- /dev/null +++ b/nvim/lua/config/langservers/java.lua @@ -0,0 +1,9 @@ +vim.lsp.config("jdtls", { + settings = { + java = { + -- Custom eclipse.jdt.ls options go here + }, + }, +}) + +vim.lsp.enable("jdtls") diff --git a/nvim/lua/config/langservers/lua.lua b/nvim/lua/config/langservers/lua.lua index f01bcd0..c0dbbb7 100644 --- a/nvim/lua/config/langservers/lua.lua +++ b/nvim/lua/config/langservers/lua.lua @@ -1,4 +1,4 @@ -require("lspconfig").lua_ls.setup({ +vim.lsp.config["lua_ls"] = { on_init = function(client) if client.workspace_folders then local path = client.workspace_folders[1].name @@ -30,4 +30,4 @@ require("lspconfig").lua_ls.setup({ settings = { Lua = {}, }, -}) +} diff --git a/nvim/lua/config/langservers/marksman.lua b/nvim/lua/config/langservers/marksman.lua index dbf21ae..e9f6edf 100644 --- a/nvim/lua/config/langservers/marksman.lua +++ b/nvim/lua/config/langservers/marksman.lua @@ -1,3 +1,3 @@ -require("lspconfig").marksman.setup({ +vim.lsp.config['marksman'] = { filetypes = { "markdown" }, -}) +} diff --git a/nvim/lua/config/langservers/python.lua b/nvim/lua/config/langservers/python.lua new file mode 100644 index 0000000..2201418 --- /dev/null +++ b/nvim/lua/config/langservers/python.lua @@ -0,0 +1,14 @@ +vim.lsp.config('pylsp', { + settings = { + pylsp = { + plugins = { + pycodestyle = { + ignore = {'W391'}, + maxLineLength = 100 + } + } + } + } +}) + +vim.lsp.enable('pylsp') diff --git a/nvim/lua/config/langservers/rust.lua b/nvim/lua/config/langservers/rust.lua index e0349e4..7a06674 100644 --- a/nvim/lua/config/langservers/rust.lua +++ b/nvim/lua/config/langservers/rust.lua @@ -1,4 +1,5 @@ -require'lspconfig'.rust_analyzer.setup{ + +vim.lsp.config["rust_analyzer"] = { settings = { ['rust-analyzer'] = { check = { diff --git a/nvim/lua/config/langservers/systemd.lua b/nvim/lua/config/langservers/systemd.lua deleted file mode 100644 index 8884401..0000000 --- a/nvim/lua/config/langservers/systemd.lua +++ /dev/null @@ -1,25 +0,0 @@ -local lspconfig = require("lspconfig") -local configs = require("lspconfig.configs") - -if not configs.systemd_ls then - configs.systemd_ls = { - default_config = { - cmd = { "systemd-language-server" }, - filetypes = { "systemd" }, - root_dir = function() - return nil - end, - single_file_support = true, - settings = {}, - }, - docs = { - description = [[ -https://github.com/psacawa/systemd-language-server - -Language Server for Systemd unit files. -]], - }, - } -end - -lspconfig.systemd_ls.setup({}) diff --git a/nvim/lua/config/langservers/terraform.lua b/nvim/lua/config/langservers/terraform.lua index 0102a95..62a8c25 100644 --- a/nvim/lua/config/langservers/terraform.lua +++ b/nvim/lua/config/langservers/terraform.lua @@ -1,8 +1,19 @@ local util = require 'lspconfig.util' -require 'lspconfig'.terraformls.setup { - -- default setup - cmd = { 'terraform-ls', 'serve' }, - filetypes = { 'terraform', 'terraform-vars' }, - root_dir = util.root_pattern('.terraform', '.git'), +vim.lsp.config["terraformls"] = { + on_attach = function(client, bufnr) + if client.supports_method("textDocument/formatting") then + vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr }) + vim.api.nvim_create_autocmd("BufWritePre", { + group = augroup, + buffer = bufnr, + callback = function() + vim.lsp.buf.format() + end, + }) + end + end, + sources = sources, } + +vim.lsp.enable("terraformls") diff --git a/nvim/lua/config/langservers/typescript.lua b/nvim/lua/config/langservers/typescript.lua deleted file mode 100644 index fc6868a..0000000 --- a/nvim/lua/config/langservers/typescript.lua +++ /dev/null @@ -1,11 +0,0 @@ -local nvim_lsp = require('lspconfig') -nvim_lsp.denols.setup { - on_attach = on_attach, - root_dir = nvim_lsp.util.root_pattern("deno.json", "deno.jsonc"), -} - -nvim_lsp.ts_ls.setup { - on_attach = on_attach, - root_dir = nvim_lsp.util.root_pattern("package.json"), - single_file_support = false -} diff --git a/nvim/lua/config/lazy.lua b/nvim/lua/config/lazy.lua index b05b6f7..6115bd5 100644 --- a/nvim/lua/config/lazy.lua +++ b/nvim/lua/config/lazy.lua @@ -35,18 +35,21 @@ vim.opt.rtp:prepend(lazypath) -- This is also a good place to setup other settings (vim.opt) -- vim.g.mapleader = " " -- vim.g.maplocalleader = "\\" +-- vim.filetype.add({ extension = { mdx = "markdown", unit = "systemd", - timer = "systemd" + timer = "systemd", + avdl = "avdl", }, }) vim.filetype.add({ filename = { ['docker-compose.yml'] = 'yaml.docker-compose', - }, + ['justfile'] = 'justfile', + } }) vim.opt.nu = true vim.opt.relativenumber = true diff --git a/nvim/lua/plugins/99.lua b/nvim/lua/plugins/99.lua new file mode 100644 index 0000000..2fb1762 --- /dev/null +++ b/nvim/lua/plugins/99.lua @@ -0,0 +1,103 @@ +return { + "ThePrimeagen/99", + config = function() + local _99 = require("99") + + -- For logging that is to a file if you wish to trace through requests + -- for reporting bugs, i would not rely on this, but instead the provided + -- logging mechanisms within 99. This is for more debugging purposes + local cwd = vim.uv.cwd() + local basename = vim.fs.basename(cwd) + _99.setup({ + provider = _99.Providers.ClaudeCodeProvider, -- default: OpenCodeProvider + model = "claude-sonnet-4-6", + logger = { + level = _99.DEBUG, + path = "/tmp/" .. basename .. ".99.debug", + print_on_error = true, + }, + -- When setting this to something that is not inside the CWD tools + -- such as claude code or opencode will have permission issues + -- and generation will fail refer to tool documentation to resolve + -- https://opencode.ai/docs/permissions/#external-directories + -- https://code.claude.com/docs/en/permissions#read-and-edit + tmp_dir = "./tmp", + + --- Completions: #rules and @files in the prompt buffer + completion = { + -- I am going to disable these until i understand the + -- problem better. Inside of cursor rules there is also + -- application rules, which means i need to apply these + -- differently + -- cursor_rules = "" + + --- A list of folders where you have your own SKILL.md + --- Expected format: + --- /path/to/dir//SKILL.md + --- + --- Example: + --- Input Path: + --- "scratch/custom_rules/" + --- + --- Output Rules: + --- {path = "scratch/custom_rules/vim/SKILL.md", name = "vim"}, + --- ... the other rules in that dir ... + --- + custom_rules = { + "scratch/custom_rules/", + }, + + --- Configure @file completion (all fields optional, sensible defaults) + files = { + -- enabled = true, + -- max_file_size = 102400, -- bytes, skip files larger than this + -- max_files = 5000, -- cap on total discovered files + -- exclude = { ".env", ".env.*", "node_modules", ".git", ... }, + }, + --- File Discovery: + --- - In git repos: Uses `git ls-files` which automatically respects .gitignore + --- - Non-git repos: Falls back to filesystem scanning with manual excludes + --- - Both methods apply the configured `exclude` list on top of gitignore + + --- What autocomplete engine to use. Defaults to native (built-in) if not specified. + source = "native", -- "native" (default), "cmp", or "blink" + }, + + --- WARNING: if you change cwd then this is likely broken + --- ill likely fix this in a later change + --- + --- md_files is a list of files to look for and auto add based on the location + --- of the originating request. That means if you are at /foo/bar/baz.lua + --- the system will automagically look for: + --- /foo/bar/AGENT.md + --- /foo/AGENT.md + --- assuming that /foo is project root (based on cwd) + md_files = { + "AGENT.md", + }, + }) + + -- take extra note that i have visual selection only in v mode + -- technically whatever your last visual selection is, will be used + -- so i have this set to visual mode so i dont screw up and use an + -- old visual selection + -- + -- likely ill add a mode check and assert on required visual mode + -- so just prepare for it now + vim.keymap.set("v", "9v", function() + _99.visual() + end) + + --- if you have a request you dont want to make any changes, just cancel it + vim.keymap.set("n", "9x", function() + _99.stop_all_requests() + end) + + vim.keymap.set("n", "9s", function() + _99.search() + end) + vim.keymap.set("n", "9l", function() + _99.view_logs() + end) + end, +} diff --git a/nvim/lua/plugins/cmp.lua b/nvim/lua/plugins/cmp.lua index 05f9cb5..d89478d 100644 --- a/nvim/lua/plugins/cmp.lua +++ b/nvim/lua/plugins/cmp.lua @@ -1,13 +1,20 @@ +local map = vim.keymap.set + +map({ 'i', 's' }, '', function() + return require('snippy').can_expand_or_advance() and '(snippy-expand-or-advance)' or '' +end, { expr = true }) +map({ 'i', 's' }, '', function() + return require('snippy').can_jump(-1) and '(snippy-previous)' or '' +end, { expr = true }) +map('x', '', '(snippy-cut-text)') + + return { { "hrsh7th/nvim-cmp", event = "VeryLazy" }, { "dcampos/cmp-snippy", event = "VeryLazy" }, { "hrsh7th/cmp-nvim-lsp", event = "VeryLazy" }, { "dcampos/nvim-snippy", - keys = { - { "", mode = { "i", "x" } }, - "g", - }, ft = "snippets", cmd = { "SnippyEdit", "SnippyReload" }, event = "VeryLazy", diff --git a/nvim/lua/plugins/formatter.lua b/nvim/lua/plugins/formatter.lua index 57cfe95..d1df070 100644 --- a/nvim/lua/plugins/formatter.lua +++ b/nvim/lua/plugins/formatter.lua @@ -26,7 +26,7 @@ return { rust = { function() return { - exe = "rustfmt", + exe = " cargo fmt", stdin = true, } end, diff --git a/nvim/lua/plugins/jdtls.lua b/nvim/lua/plugins/jdtls.lua new file mode 100644 index 0000000..7994cca --- /dev/null +++ b/nvim/lua/plugins/jdtls.lua @@ -0,0 +1,6 @@ +return { + { + "mfussenegger/nvim-jdtls", + event = "VeryLazy", + }, +} diff --git a/nvim/lua/plugins/markdown-preview.lua b/nvim/lua/plugins/markdown-preview.lua index f725a17..3bc4fac 100644 --- a/nvim/lua/plugins/markdown-preview.lua +++ b/nvim/lua/plugins/markdown-preview.lua @@ -1,11 +1,12 @@ vim.keymap.set("n", "mp", "MarkdownPreview") +-- install with yarn or npm return { - { - "iamcco/markdown-preview.nvim", - cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, - build = "cd app && npm install", - ft = { "markdown" }, - event = "VeryLazy", - }, + "iamcco/markdown-preview.nvim", + cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, + build = "cd app && yarn install", + init = function() + vim.g.mkdp_filetypes = { "markdown" } + end, + ft = { "markdown" }, } diff --git a/nvim/lua/plugins/neogit.lua b/nvim/lua/plugins/neogit.lua new file mode 100644 index 0000000..ed861e0 --- /dev/null +++ b/nvim/lua/plugins/neogit.lua @@ -0,0 +1,18 @@ +return { + "NeogitOrg/neogit", + lazy = true, + dependencies = { + "nvim-lua/plenary.nvim", -- required + "sindrets/diffview.nvim", -- optional - Diff integration + + -- Only one of these is needed. + "nvim-telescope/telescope.nvim", -- optional + "ibhagwan/fzf-lua", -- optional + "nvim-mini/mini.pick", -- optional + "folke/snacks.nvim", -- optional + }, + cmd = "Neogit", + keys = { + { "gg", "Neogit", desc = "Show Neogit UI" } + } +} diff --git a/nvim/lua/plugins/tokyonight.lua b/nvim/lua/plugins/nightfox.lua similarity index 80% rename from nvim/lua/plugins/tokyonight.lua rename to nvim/lua/plugins/nightfox.lua index b1718c2..580acea 100644 --- a/nvim/lua/plugins/tokyonight.lua +++ b/nvim/lua/plugins/nightfox.lua @@ -1,12 +1,12 @@ return { -- the colorscheme should be available when starting Neovim { - "folke/tokyonight.nvim", + "EdenEast/nightfox.nvim", lazy = false, -- make sure we load this during startup if it is your main colorscheme priority = 1000, -- make sure to load this before all the other start plugins config = function() -- load the colorscheme here - vim.cmd([[colorscheme tokyonight-night]]) + vim.cmd([[colorscheme carbonfox]]) end, }, } diff --git a/nvim/lua/plugins/nvim-telescope.lua b/nvim/lua/plugins/nvim-telescope.lua index 4259556..d564560 100644 --- a/nvim/lua/plugins/nvim-telescope.lua +++ b/nvim/lua/plugins/nvim-telescope.lua @@ -60,7 +60,7 @@ return { extensions = { file_browser = { - theme = "ivy", + -- theme = "ivy", -- disables netrw and use telescope-file-browser in its place hijack_netrw = true, depth = 1, diff --git a/nvim/lua/plugins/typescript-tools.lua b/nvim/lua/plugins/typescript-tools.lua new file mode 100644 index 0000000..83e1ea0 --- /dev/null +++ b/nvim/lua/plugins/typescript-tools.lua @@ -0,0 +1,5 @@ +return { + "pmizio/typescript-tools.nvim", + dependencies = { "nvim-lua/plenary.nvim", "neovim/nvim-lspconfig" }, + opts = {}, +} diff --git a/nvim/lua/plugins/which-key.lua b/nvim/lua/plugins/which-key.lua deleted file mode 100644 index 696e46a..0000000 --- a/nvim/lua/plugins/which-key.lua +++ /dev/null @@ -1,20 +0,0 @@ -return { - { - "folke/which-key.nvim", - event = "VeryLazy", - opts = { - -- your configuration comes here - -- or leave it empty to use the default settings - -- refer to the configuration section below - }, - keys = { - { - "?", - function() - require("which-key").show({ global = false }) - end, - desc = "Buffer Local Keymaps (which-key)", - }, - }, - }, -} diff --git a/nvim/snippets/.editorconfig.snippets b/nvim/snippets/.editorconfig.snippets new file mode 100644 index 0000000..616110e --- /dev/null +++ b/nvim/snippets/.editorconfig.snippets @@ -0,0 +1,20 @@ +snippet sample + [*.{cs,csx}] + # Non-configurable behaviors + charset = utf-8 + insert_final_newline = true + trim_trailing_whitespace = true + dotnet_sort_system_directives_first = true + dotnet_separate_import_directive_groups = false + + # Configurable behaviors + # end_of_line = lf - there is no 'auto' with an .editorconfig + indent_style = space + indent_size = 4 + max_line_length = 100 + + [*.{csproj,props,targets,xml,config}] + # Configurable behaviors + indent_style = space + indent_size = 2 + max_line_length = 100 diff --git a/nvim/snippets/avdl.snippets b/nvim/snippets/avdl.snippets new file mode 100644 index 0000000..ff24285 --- /dev/null +++ b/nvim/snippets/avdl.snippets @@ -0,0 +1,18 @@ +snippet sample + namespace Slack; + + record SlackEvent { + string type; + string user; + string event_ts; + string? text; + string? reaction; + Item? item; + } + + record Item + { + string type; + string channel; + string ts; + } diff --git a/nvim/snippets/cs.snippets b/nvim/snippets/cs.snippets new file mode 100644 index 0000000..d560fa3 --- /dev/null +++ b/nvim/snippets/cs.snippets @@ -0,0 +1,909 @@ +# Region EFCore +snippet efcoreContext + internal class ${1:NAME}Context(DbContextOptions<${1:NAME}Context> options) : DbContext(options) + { + public DbSet<${1:NAME}> ${1:NAME}s { get; set; } + } + +snippet efcoreInjection + builder.Services.AddDbContext<${1:NAME}Context>( + options => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")), + ServiceLifetime.Singleton + ); + +# Region Kafka +snippet kafkaProducerInit + var config = new ProducerConfig + { + BootstrapServers = "localhost:9092", + MessageSendMaxRetries = 10, + }; + + var schemaRegistry = new CachedSchemaRegistryClient( + new SchemaRegistryConfig { Url = options.SchemaRegistryUrl } + ); + + _producer = new ProducerBuilder<${1:KEY_TYPE}, ${2:VALUE_TYPE}>(config) + .SetValueSerializer(new AvroSerializer<$(2:VALUETYPE)>(schemaRegistry)) + .Build(); + +snippet kafkaConsumerInit + // Meant to run inside a worker service + // StoppingToken is used in this example + var conf = new ConsumerConfig + { + GroupId = "test-consumer-group", + BootstrapServers = "localhost:9092", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnableAutoCommit = false, + }; + + return Task.Run( + () => + { + using var c = new ConsumerBuilder<${1:KEY_TYPE}, ${2:VALUE_TYPE}>(conf).Build(); + c.Subscribe(${3:TOPIC_NAME}); + try + { + while (true) + { + try + { + var cr = c.Consume(stoppingToken); + + // TODO add consumer logic + + c.Commit(); + } + catch (ConsumeException e) + { + Console.WriteLine($"Error occured: {e.Error.Reason}"); + } + } + } + catch (OperationCanceledException) + { + // Ensure the consumer leaves the group cleanly and final offsets are committed. + c.Close(); + } + }, + stoppingToken + ); + +snippet kafkaStreamConfig + public static class KafkaConfig + { + public static StreamConfig GetConfig() + { + var config = new StreamConfig() + { + ApplicationId = "streamiz", + BootstrapServers = "localhost:9092", + AutoOffsetReset = Confluent.Kafka.AutoOffsetReset.Earliest, + AllowAutoCreateTopics = false, + }; + return config; + } + } + +snippet kafkaStreamApplication + var builder = new StreamBuilder(); + StreamTopology.Configure(builder); + + var t = builder.Build(); + var stream = new KafkaStream(t, KafkaConfig.GetConfig()); + + await stream.StartAsync(); + +snippet kafkaStreamTopology + public class StreamTopology + { + + public static void Configure(StreamBuilder builder) + { + } + } + +snippet kafkaStream + var weatherStream = builder.Stream( + "${1:TOPIC_NAME}", + new StringSerDes(), + weatherReadingSerDes + ); + +snippet kafkaStreamFilter + var temperatureStream = weatherStream.Filter((k, v, c) => v.type == "temperature"); + +snippet kafkaStreamJoin + var joinedStream = temperatureStream.Join< + WeatherReading, + CombinedReading, + JsonSerDes, + JsonSerDes + >( + humidityStream, + (t, h) => + new CombinedReading( + ), + JoinWindowOptions.Of(10_000), + StreamJoinProps.As("") + ); +snippet kafkaStreamAggregation + temperatureStream + .GroupByKey() + .WindowedBy(TumblingWindowOptions.Of(20_000, 7_400_000)) + .Aggregate( + () => new Statistic(0, 0), + (_, v, c) => new Statistic(c.amount + 1, c.value + v.value), + Materialized> + .Create("") + .With(new StringSerDes(), new JsonSerDes()) + ) + .MapValues((k, _) => () + .ToStream() +snippet currentKafkaStreamConfig + public static class KafkaConfig + { + public static StreamConfig GetConfig() + { + var config = new StreamConfig() + { + ApplicationId = "current-example", + BootstrapServers = "localhost:9092", + AutoOffsetReset = Confluent.Kafka.AutoOffsetReset.Earliest, + AllowAutoCreateTopics = true, + }; + return config; + } + } +snippet currentKafkaRecords + public record WeatherStationRecord(string weatherStationId, string name); + public record EnrichedWeatherRecord(Guid messageId, string weatherStationId, string weatherStationName, double value, long originalMessageTimestamp, long currentMessageTimestamp); + public record WeatherRecord(Guid messageId, string weatherStationId, double value, long timeStamp); + +snippet currentKafkaTableDefinition + var weatherStationsTable = builder.GlobalTable( + "weather.stations", + new StringSerDes(), + new JsonSerDes() + ); + +snippet currentaStreamDefinition + var weatherRecordStream = builder.Stream( + "weather.data", + new StringSerDes(), + new JsonSerDes() + ); + +snippet currentKafkaStreamTableJoin + var enrichedWeatherRecordStream = weatherRecordStream.Join( + weatherStationsTable, + (id, weatherRecord) => weatherRecord.weatherStationId, + (weatherRecord, station) => + new EnrichedWeatherRecord( + weatherRecord.messageId, + weatherRecord.value, + weatherRecord.timeStamp, + DateTimeOffset.Now.ToUnixTimeMilliseconds() + ) + ); + + enrichedWeatherRecordStream.To>("demo.result"); + +snippet patternSingleton + class ${1:NAME} + { + private static ${1:NAME} instance; + + // Constructor is private + private ${1:NAME}() + { + Console.WriteLine("${1:NAME} was instantiated"); + } + + // If singleton needs to be shared across threads, use a lock object + private static readonly object syncLock = new object(); + public static ${1:NAME} getInstance() + { + lock (syncLock) + { + if (instance == null) + { + instance = new ${1:NAME}(); + } + return instance; + } + } + + public void Print() + { + // Functionality of the singleton class + Console.WriteLine("Hi, I'm a singleton!"); + } + } +snippet patternFactory + // Singleton pattern + class ${1:NAME}Factory + { + private static ${1:NAME}Factory instance; + + private ${1:NAME}Factory() { } + + private Dictionary registered${1:NAME}s = + new Dictionary(); + + // Registration pattern + // Can also be done using reflection + public void Register${1:NAME}(string key, ${1:NAME} value) + { + registered${1:NAME}s.Add(key, value); + } + + public static ${1:NAME}Factory getInstance() + { + if (instance == null) + { + instance = new ${1:NAME}Factory(); + } + return instance; + } + + public ${1:NAME} Create${1:NAME}(string type) + { + return registered${1:NAME}s.GetValueOrDefault(type).create${1:NAME}(); + } + } + + class Import${1:NAME} : ${1:NAME} + { + public static void Register() + { + ${1:NAME}Factory.getInstance().Register${1:NAME}("Import${1:NAME}", new Import${1:NAME}()); + } + + public override ${1:NAME} create${1:NAME}() + { + return new Import${1:NAME}(); + } + } + + class Export${1:NAME} : ${1:NAME} + { + public static void Register() + { + ${1:NAME}Factory.getInstance().Register${1:NAME}("Export${1:NAME}", new Export${1:NAME}()); + } + + public override ${1:NAME} create${1:NAME}() + { + return new Export${1:NAME}(); + } + } + + abstract class ${1:NAME} + { + public abstract ${1:NAME} create${1:NAME}(); + } +snippet patternFactoryMethod + // Singleton pattern + class ${1:NAME}Factory : Factory + { + private static ${1:NAME}Factory instance; + + private ${1:NAME}Factory() { } + + private Dictionary> registered${1:NAME}s = + new Dictionary>(); + + // Registration pattern + // Can also be done using reflection + public void Register${1:NAME}(string key, Func<${1:NAME}> value) + { + registered${1:NAME}s.Add(key, value); + } + + public static ${1:NAME}Factory getInstance() + { + if (instance == null) + { + instance = new ${1:NAME}Factory(); + } + return instance; + } + + public override ${1:NAME} CreateObject(string type) + { + return registered${1:NAME}s.GetValueOrDefault(type)(); + } + } + + abstract class Factory + { + public void anOperation(string type) + { + var entity = CreateObject(type); + Console.WriteLine(entity); + } + + public abstract ${1:NAME} CreateObject(string type); + } + + class Import${1:NAME} : ${1:NAME}, IRegistrable + { + public override void Print() + { + Console.WriteLine("I am an import bycicle"); + } + + public static void Register(string key, Func valueCreator) + { + ${1:NAME}Factory.getInstance().Register${1:NAME}(key, valueCreator); + } + } + + class Export${1:NAME} : ${1:NAME}, IRegistrable + { + public static void Register() { } + + public override void Print() + { + Console.WriteLine("I am an export bycicle"); + } + + public static void Register(string key, Func valueCreator) + { + ${1:NAME}Factory.getInstance().Register${1:NAME}(key, valueCreator); + } + } + + interface IRegistrable + where T : ${1:NAME} + { + static void Register(string key, Func valueCreator) + { + throw new NotImplementedException(); + } + } + + abstract class ${1:NAME} + { + public abstract void Print(); + } + +snippet patternBuilder + class ${1:NAME} + { + internal ${1:NAME}() + { + ChassisWelded = false; + Wheels = new List(); + } + + public bool ChassisWelded { get; private set; } + + public List Wheels { get; private set; } + + public void WeldChassis() + { + ChassisWelded = true; + } + + public void AddWheels(List wheels) + { + this.Wheels = wheels; + } + + public override string ToString() + { + return $"{ChassisWelded} - {String.Join(',', Wheels)}"; + } + } + + class Concrete${1:NAME}Builder : ${1:NAME}Builder + { + public Concrete${1:NAME}Builder() + { + Result = new ${1:NAME}(); + } + + private ${1:NAME} Result { get; init; } + + public override void AddWheels(int amount) + { + Result.AddWheels(Enumerable.Range(1, amount).ToList()); + } + + public override void WeldChassis() + { + Result.WeldChassis(); + } + + public ${1:NAME} GetResult() + { + return Result; + } + } + + class ${1:NAME}Director + { + private readonly Concrete${1:NAME}Builder builder; + + public ${1:NAME}Director(Concrete${1:NAME}Builder builder) + { + ArgumentNullException.ThrowIfNull(builder); + this.builder = builder; + } + + public ${1:NAME} Create${1:NAME}() + { + builder.AddWheels(4); + builder.WeldChassis(); + + return this.builder.GetResult(); + } + } + +snippet patternPrototype + class Maze : IPrototype + { + private Maze(List doors) + { + Doors = doors; + } + + public Maze() + { + Doors = new List() { new Door("test", 5, 5) }; + } + + public Maze clone() + { + return new Maze(Doors.Select(d => d.clone()).ToList()); + } + + public List Doors { get; private set; } + + public override string ToString() + { + List elements = new(); + elements.Add("This is a maze..."); + Doors.ForEach(d => + { + elements.Add($"{d.Name} - {d.PositionX} - {d.PositionY}"); + }); + return string.Join('\n', elements); + } + } + + class Door : IPrototype + { + public Door(string name, int positionX, int positionY) + { + Name = name; + PositionX = positionX; + PositionY = positionY; + } + + public string Name { get; } + public int PositionX { get; } + public int PositionY { get; } + + public Door clone() + { + var random = new Random(); + return new Door(Name, random.Next(), random.Next()); + } + } + + interface IPrototype + { + T clone(); + } +snippet patternObjectPool + InitializePool(); + + var tasks = new List(); + + for (var i = 0; i < 10; i++) + { + tasks.Add(TestTask(i.ToString())); + } + + await Task.WhenAll(tasks); + + Console.WriteLine("Done"); + + void InitializePool() + { + var pool = ReusablePool.getInstance(); + for (var i = 0; i < 1; i++) + { + WorkerReusable.Register(); + } + } + + async Task TestTask(string taskName) + { + var pool = ReusablePool.getInstance(); + var reusable = pool.AcquireReusable(); + var random = new Random(); + + for (var i = 0; i < 10; i++) + { + Console.WriteLine($"{taskName} - {Thread.CurrentThread.ManagedThreadId} - {i}"); + reusable.Print(); + Console.WriteLine(String.Empty); + + await Task.Delay(random.Next(1, 1000)); + } + pool.ReleaseReusable(reusable); + } + + class ReusablePool + { + private static ReusablePool instance; + + private ReusablePool() { } + + private record ReusableRecord(bool isInUse, IReusable reusable); + + private List Reusables = new List(); + + public void RegisterReusablePool(IReusable value) + { + Reusables.Add(new ReusableRecord(false, value)); + } + + private static readonly object getInstanceSyncLock = new object(); + + public static ReusablePool getInstance() + { + lock (getInstanceSyncLock) + { + if (instance == null) + { + instance = new ReusablePool(); + } + return instance; + } + } + + private static readonly object acquireSyncLock = new object(); + + public IReusable AcquireReusable() + { + lock (acquireSyncLock) + { + var reusable = Reusables.First(d => d.isInUse == false); + Reusables.Remove(reusable); + reusable = reusable with { isInUse = true }; + Reusables.Add(reusable); + return reusable.reusable; + } + } + + public void ReleaseReusable(IReusable reusable) + { + var reusableToRelease = Reusables.Single(d => d.reusable.Equals(reusable)); + if (reusableToRelease.isInUse == false) + { + // Should never happen + throw new InvalidOperationException("Reusable was not in use..."); + } + Reusables.Remove(reusableToRelease); + reusableToRelease = reusableToRelease with { isInUse = false }; + Reusables.Add(reusableToRelease); + } + } + + class WorkerReusable : IReusable + { + public static void Register() + { + ReusablePool.getInstance().RegisterReusablePool(new WorkerReusable()); + } + + public void Print() + { + Console.WriteLine("I'm a reusable..."); + } + } + + interface IReusable + { + void Print(); + } +snippet patternChainOfResponsibility + record Request(int Value); + + abstract class Handler + { + protected Handler Successor; + + public void SetSuccessor(Handler successor) + { + Successor = successor; + } + + public abstract bool HandleRequestImpl(Request request); + + public void HandleRequest(Request request) + { + var handledByThisNode = HandleRequestImpl(request); + + if (Successor != null && !handledByThisNode) + { + Successor.HandleRequest(request); + } + + // For testing purposes + if (handledByThisNode) + { + Console.WriteLine(GetType()); + } + } + } + + class NegativeValueHandler : Handler + { + public override bool HandleRequestImpl(Request request) + { + return request.Value < 0; + } + } + + class PositiveValueHandler : Handler + { + public override bool HandleRequestImpl(Request request) + { + return request.Value > 0; + } + } + + class ZeroValueHandler : Handler + { + public override bool HandleRequestImpl(Request request) + { + return request.Value == 0; + } + } +snippet patternInterpreter + string roman = "MCMXXVIII"; + Context context = new Context(roman); + + // Build the 'parse tree' + var tree = new List(); + tree.Add(new ThousandExpression()); + tree.Add(new HundredExpression()); + tree.Add(new TenExpression()); + tree.Add(new OneExpression()); + + foreach (var element in tree) + { + element.interpret(context); + } + + Console.WriteLine(context.getOutput()); + + class Context + { + private string input; + private int output; + + public Context(String input) + { + this.input = input; + } + + public string getInput() => input; + + public void setInput(string input) => this.input = input; + + public int getOutput() => output; + + public void setOutput(int output) => this.output = output; + } + + abstract class Expression + { + public void interpret(Context context) + { + if (context.getInput().Length == 0) + { + return; + } + + if (context.getInput().StartsWith(nine())) + { + context.setOutput(context.getOutput() + (9 * multiplier())); + context.setInput(context.getInput().Substring(2)); + } + if (context.getInput().StartsWith(four())) + { + context.setOutput(context.getOutput() + (4 * multiplier())); + context.setInput(context.getInput().Substring(2)); + } + if (context.getInput().StartsWith(five())) + { + context.setOutput(context.getOutput() + (5 * multiplier())); + context.setInput(context.getInput().Substring(1)); + } + while (context.getInput().StartsWith(one())) + { + context.setOutput(context.getOutput() + (1 * multiplier())); + context.setInput(context.getInput().Substring(1)); + } + } + + public abstract string one(); + public abstract string four(); + public abstract string five(); + public abstract string nine(); + public abstract int multiplier(); + } + + class ThousandExpression : Expression + { + public override string one() => "M"; + + public override string four() => " "; + + public override string five() => " "; + + public override string nine() => " "; + + public override int multiplier() => 1000; + } + + class HundredExpression : Expression + { + public override string one() => "C"; + + public override string four() => "CD"; + + public override string five() => "D"; + + public override string nine() => "CM"; + + public override int multiplier() => 100; + } + + class TenExpression : Expression + { + public override string one() => "X"; + + public override string four() => "XL"; + + public override string five() => "L"; + + public override string nine() => "XC"; + + public override int multiplier() => 10; + } + + class OneExpression : Expression + { + public override string one() => "I"; + + public override string four() => "IV"; + + public override string five() => "V"; + + public override string nine() => "IX"; + + public override int multiplier() => 1; + } +snippet patternMediator + class Mediator + { + public delegate void MessagePublishedEventHandler( + Colleague sender, + MessagePublishedEventArgs args + ); + + public event MessagePublishedEventHandler? MessagePublished; + + public Mediator() { } + + public void Send(Colleague me, string message) + { + MessagePublished?.Invoke(me, new MessagePublishedEventArgs(message)); + } + } + + class Colleague : IDisposable + { + private readonly Mediator mediator; + + public string Name { get; } + + public Colleague(string name, Mediator mediator) + { + Name = name; + this.mediator = mediator; + mediator.MessagePublished += OnReceive; + } + + public void SendMessage(string message) + { + mediator.Send(this, message); + } + + public void Dispose() + { + mediator.MessagePublished -= OnReceive; + Console.WriteLine($"{this.Name} has disconnected from the mediator"); + } + + private void OnReceive(Colleague sender, MessagePublishedEventArgs args) + { + // Make sure this method catches events, so other Colleagues that are subscribed still get this event + try + { + if (this.Name == "Wout") + { + throw new ArgumentException("test"); + } + if (sender.Name != this.Name) + { + Console.WriteLine($"{Name} - Message received from {sender.Name}: {args.message}"); + } + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } +snippet patternObserver + abstract class Observable + { + // Abstract implementation + // Responsible for notifying observers + private List observers = new List(); + + public void Attach(Observer observer) + { + observers.Add(observer); + } + + public void Detach(Observer observer) + { + observers.Remove(observer); + } + + public void Notify(int newValue) + { + foreach (var observer in observers) + { + observer.Update(newValue); + } + } + } + + class ConcreteObservable : Observable + { + // Actual implementation of observable + private int state; + + public int GetState() => state; + + public void SetState(int newState) + { + state = newState; + Notify(newState); + } + } + + abstract class Observer + { + public void Update(int newValue) + { + Console.WriteLine($"Observer was notified {newValue}"); + } + } + + class ConcreteObserver : Observer + { + // Maintain observer state + } diff --git a/nvim/snippets/dockerfile.snippets b/nvim/snippets/dockerfile.snippets new file mode 100644 index 0000000..b7267af --- /dev/null +++ b/nvim/snippets/dockerfile.snippets @@ -0,0 +1,52 @@ +snippet dotnetBuild + FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build + WORKDIR /src + + RUN dotnet tool install --global dotnet-ef + + # copy csproj and restore as distinct layers + COPY ${1:NAME}/*.csproj ./${1:NAME}/ + + WORKDIR /src/${1:NAME} + RUN dotnet restore + + WORKDIR /src + # copy everything else and build app + COPY ${1:NAME}/. ./${1:NAME}/ + COPY common/. ./common/ + + WORKDIR /src/${1:NAME} + RUN dotnet publish -c release -o /app + +snippet dotnetReleaseWeb + # final stage/image + FROM mcr.microsoft.com/dotnet/aspnet:9.0 + WORKDIR /app + COPY --from=build /app ./ + ENTRYPOINT ["dotnet", "${1:NAME}.dll"] + +snippet dotnetReleaseMigrations + FROM build AS migration + RUN dotnet build + ENV PATH="$PATH:/root/.dotnet/tools" + ENTRYPOINT ["dotnet-ef", "database", "update"] + +snippet dotnetGenerateFromAvro + FROM mcr.microsoft.com/dotnet/sdk:9.0-bookworm-slim AS build + RUN apt update && apt install -y findutils curl + WORKDIR /Generated/ + + RUN dotnet tool install --global Apache.Avro.Tools --version 1.12.0 + ENV PATH="$PATH:/root/.dotnet/tools" + + ENTRYPOINT find *avsc -exec avrogen -s {} ./cs \; + +snippet javaGenerateAvscFromAvdl + FROM openjdk:26-jdk-slim-bookworm + RUN apt update && apt install -y findutils curl + + WORKDIR /home/avro-gen/ + RUN curl -L -o /avro-tools.jar https://repo1.maven.org/maven2/org/apache/avro/avro-tools/1.12.0/avro-tools-1.12.0.jar + + ENTRYPOINT rm -r ./Generated/* && find *avdl -exec java -jar /avro-tools.jar idl2schemata ./{} ./Generated \; + diff --git a/nvim/snippets/java.snippets b/nvim/snippets/java.snippets new file mode 100644 index 0000000..71e9af3 --- /dev/null +++ b/nvim/snippets/java.snippets @@ -0,0 +1,208 @@ +snippet patternSingleton + class ${1:NAME} { + private static ${1:NAME} instance; + + private ${1:NAME}() { + System.out.println("Instance created"); + } + + // If shared across threads, use synchronized keyword + public static synchronized ${1:NAME} getInstance() { + if (instance == null) { + instance = new ${1:NAME}(); + } + return instance; + } + + public void showMessage() { + System.out.println("Hello from ${1:NAME}!"); + } + } + +snippet patternFactory + class ${1:NAME}Factory { + private static ${1:NAME}Factory instance; + + private Map registrations = new HashMap(); + + public void RegisterInstance(String key, ${1:NAME} value) { + registrations.put(key, value); + } + + private ${1:NAME}Factory() { + } + + // If shared across threads, use synchronized keyword + public static synchronized ${1:NAME}Factory getInstance() { + if (instance == null) { + instance = new ${1:NAME}Factory(); + } + return instance; + } + + public ${1:NAME} Create${1:NAME}(String key) { + var result = registrations.get(key); + return result.create${1:NAME}(); + } + + } + + abstract class ${1:NAME} { + public abstract ${1:NAME} create${1:NAME}(); + } + + class Import${1:NAME} extends ${1:NAME} { + public static void Register() { + ${1:NAME}Factory.getInstance().RegisterInstance("Import${1:NAME}", new Import${1:NAME}()); + } + + @Override + public ${1:NAME} create${1:NAME}() { + return new Import${1:NAME}(); + } + + private Import${1:NAME}() { + System.out.println("Import${1:NAME} Initialized"); + } + } + + class Export${1:NAME} extends ${1:NAME} { + public static void Register() { + ${1:NAME}Factory.getInstance().RegisterInstance("Export${1:NAME}", new Export${1:NAME}()); + } + + @Override + public ${1:NAME} create${1:NAME}() { + return new Export${1:NAME}(); + } + } +snippet patternFactoryMethod + class ${1:NAME}Factory extends Factory { + private static ${1:NAME}Factory instance; + + private Map registrations = new HashMap(); + + public void RegisterInstance(String key, ${1:NAME} value) { + registrations.put(key, value); + } + + private ${1:NAME}Factory() { + } + + // If shared across threads, use synchronized keyword + public static synchronized ${1:NAME}Factory getInstance() { + if (instance == null) { + instance = new ${1:NAME}Factory(); + } + return instance; + } + + public ${1:NAME} CreateObject(String key) { + return registrations.get(key); + } + } + + abstract class Factory { + public void anOperation(String type) { + var operationSubject = CreateObject(type); + operationSubject.Print(); + } + + public abstract ${1:NAME} CreateObject(String key); + } + + abstract class ${1:NAME} { + public abstract void Print(); + } + + class Import${1:NAME} extends ${1:NAME} { + public static void Register() { + ${1:NAME}Factory.getInstance().RegisterInstance("Import${1:NAME}", new Import${1:NAME}()); + } + + public void Print() { + System.out.println("I am an Import${1:NAME}"); + } + } + + class Export${1:NAME} extends ${1:NAME} { + public static void Register() { + ${1:NAME}Factory.getInstance().RegisterInstance("Export${1:NAME}", new Export${1:NAME}()); + } + + public void Print() { + System.out.println("I am an Export${1:NAME}"); + } + } +snippet patternAbstractFactory + + class ${1:NAME}FactoryCreator { + private static ${1:NAME}Factory instance; + + // If shared across threads, use synchronized keyword + public static synchronized ${1:NAME}Factory getInstance() { + if (instance == null) { + instance = new ${1:NAME}Factory(); + instance.RegisterA("A1", new ${1:NAME}A1()); + instance.RegisterB("B1", new ${1:NAME}B1()); + } + return instance; + } + + public void showMessage() { + System.out.println("Hello from ${1:NAME}FactoryFactory!"); + } + } + + class ${1:NAME}Factory { + protected Map registrationsA = new HashMap(); + protected Map registrationsB = new HashMap(); + + protected void RegisterA(String key, Abstract${1:NAME}A value) { + registrationsA.put(key, value); + } + + protected void RegisterB(String key, Abstract${1:NAME}B value) { + registrationsB.put(key, value); + } + + public Abstract${1:NAME}A CreateA(String key) { + return registrationsA.get(key); + } + + public Abstract${1:NAME}B CreateB(String key) { + return registrationsB.get(key); + } + } + + abstract class Abstract${1:NAME}A { + public abstract void Print(); + } + + class ${1:NAME}A1 extends Abstract${1:NAME}A { + public void Print() { + System.out.println("${1:NAME}A1"); + } + } + + class ${1:NAME}A2 extends Abstract${1:NAME}A { + public void Print() { + System.out.println("${1:NAME}A2"); + } + } + + abstract class Abstract${1:NAME}B { + public abstract void Print(); + } + + class ${1:NAME}B1 extends Abstract${1:NAME}B { + public void Print() { + System.out.println("${1:NAME}B1"); + } + } + + class ${1:NAME}B2 extends Abstract${1:NAME}B { + public void Print() { + System.out.println("${1:NAME}B2"); + } + } diff --git a/nvim/snippets/justfile.snippets b/nvim/snippets/justfile.snippets new file mode 100644 index 0000000..7950699 --- /dev/null +++ b/nvim/snippets/justfile.snippets @@ -0,0 +1,8 @@ +snippet init + hello-world: + echo "hello world!" + +snippet efcoreMigrations + run-migrations-exporter-reactions name: + export "DB__POSTGRES_CONNECTION_STRING"="Host=localhost;Port=5434;Database=postgres;Username=postgres;Password=postgres" && \ + dotnet ef migrations add {{ name }} --project exporter.infrastructure/exporter.infrastructure.csproj --startup-project exporter.service/exporter.service.csproj --context exporter.infrastructure.Database.SlackReactionContext diff --git a/nvim/snippets/markdown.snippets b/nvim/snippets/markdown.snippets index ce533e6..3e4f123 100644 --- a/nvim/snippets/markdown.snippets +++ b/nvim/snippets/markdown.snippets @@ -30,3 +30,11 @@ snippet timeHeading snippet timeRecord - HHuMM - HHuMM: + +snippet metaData + --- + title: ${1:title} + tags: + - ${2:tag} + --- + diff --git a/nvim/snippets/sh.snippets b/nvim/snippets/sh.snippets new file mode 100644 index 0000000..e9a00b4 --- /dev/null +++ b/nvim/snippets/sh.snippets @@ -0,0 +1,5 @@ +snippet kafkaTopics + #/bin/bash + kafka-topics --create --bootstrap-server broker:29092 --topic orders --partitions 2 + + exit 0; diff --git a/nvim/snippets/yaml.snippets b/nvim/snippets/yaml.snippets index d3af7cb..0fb306e 100644 --- a/nvim/snippets/yaml.snippets +++ b/nvim/snippets/yaml.snippets @@ -1,11 +1,11 @@ -snippet config +snippet kubernetesConfig apiVersion: v1 kind: ConfigMap metadata: name: ${1:name}-config data: test: "test" -snippet service +snippet kubernetesService apiVersion: v1 kind: Service metadata: @@ -18,7 +18,7 @@ snippet service selector: app: ${2:appname} -snippet deploy +snippet kubernetesDeploy apiVersion: apps/v1 kind: Deployment metadata: @@ -48,3 +48,123 @@ snippet deploy envFrom: - configMapRef: name: ${4:configmap} + +snippet dockerComposeKafkaBase + services: + broker-init: + image: confluentinc/cp-kafka:8.0.0 + command: [ "/bin/bash", "-c", "/create_topics.sh"] + depends_on: + broker: + condition: service_healthy + volumes: + - type: bind + source: ./create_topics.sh + target: /create_topics.sh + broker: + image: confluentinc/cp-kafka:8.0.0 + environment: + KAFKA_NODE_ID: 1 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT' + KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://broker:29092,PLAINTEXT_HOST://localhost:9092' + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0 + KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1 + KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 + KAFKA_JMX_PORT: 9101 + KAFKA_JMX_HOSTNAME: localhost + KAFKA_PROCESS_ROLES: 'broker,controller' + KAFKA_CONTROLLER_QUORUM_VOTERS: '1@broker:29093' + KAFKA_LISTENERS: 'PLAINTEXT://broker:29092,CONTROLLER://broker:29093,PLAINTEXT_HOST://0.0.0.0:9092' + KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT' + KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER' + KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs' + KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: "true" + CLUSTER_ID: 'MkU3OEVBNTcwNTJENDM2Qk' + healthcheck: + test: kafka-topics --bootstrap-server broker:29092 --list + interval: 1s + timeout: 60s + retries: 60 + schema-registry: + image: confluentinc/cp-schema-registry:8.0.0 + environment: + SCHEMA_REGISTRY_HOST_NAME: schema-registry + SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: 'broker:29092' + SCHEMA_REGISTRY_LISTENERS: http://0.0.0.0:8081 + healthcheck: + test: curl --output /dev/null --silent --head --fail http://schema-registry:8081/subjects + interval: 5s + timeout: 10s + retries: 3 + depends_on: + broker-init: + condition: service_completed_successfully + +snippet dockerComposePostgres + services: + postgres: + image: postgres:17 + environment: + POSTGRES_PASSWORD: postgres + +snippet dockerComposeDotnetWeb + services: + consumer: + build: + context: . + dockerfile: ./Dockerfiles/consumer.Dockerfile + +snippet dockerComposeAvroSchemas + services: + avsc-generator: + network_mode: none + build: + context: ./Dockerfiles + dockerfile: AvscGenerator.Dockerfile + volumes: + - ./kafka.contracts/Definitions:/home/avro-gen/:r + - ./kafka.contracts/Definitions/Generated:/home/avro-gen/Generated:rw + avrogen: + network_mode: none + build: + context: ./Dockerfiles + dockerfile: Avrogen.Dockerfile + volumes: + - ./kafka.contracts/Definitions/Generated/:/Generated/:rw + depends_on: + avsc-generator: + condition: service_completed_successfully + +snippet acIacTopic + apiVersion: eda.atlascopco.com/v1 + kind: Topic + metadata: + environment: ${1:Environment} + name: ${2:Prefix}.${3:AppName}.${4:Visibility}.${5:Subject} + visibility: ${4:Visibility} + owner: test@atlascopco.com + applicationDeploymentRef: ${2:Prefix}.${3:AppName} + spec: + partitions: 2 + config: + retention.ms: 604800000 + +snippet acIacAcl + apiVersion: eda.atlascopco.com/v1 + kind: TopicPermission + spec: + topic: ${1:AppName}.${2:Visibility}.${3:Subject} + grantedApplicationDeploymentRef: ${4:Prefix}.${5:TargetApp} + permissionType: READ + +snippet acIacServiceAccount + apiVersion: eda.atlascopco.com/v1 + kind: ServiceAccount + metadata: + environment: ${1:Environment} + applicationDeploymentRef: ${2:Prefix}.${3:AppName} + spec: + displayName: ${2:Prefix}.${4:AppName}-${1:Environment}-${5:Suffix} + + diff --git a/tmux/start-dev.sh b/tmux/start-dev.sh deleted file mode 100755 index 834cfb0..0000000 --- a/tmux/start-dev.sh +++ /dev/null @@ -1,7 +0,0 @@ -tmux new-session -d -s backend -n backend "cd ~/repos/api-v3/ && nvim ." -tmux new-window -n sgrebackend "cd ~/repos/sgre-as-backend-services/ && nvim ." -tmux new-window -n rustbackend "cd ~/repos/sgre-checklist-backend/ && nvim ." -tmux new-window -n portal "cd ~/repos/service-admin-portal/ && nvim ." -tmux new-window -n sgreportal "cd ~/repos/sgre-portal/ && nvim ." -tmux new-window -n sgreapp "cd ~/repos/sgre-app/ && nvim ." -tmux -2 attach-session -d diff --git a/tmux/tmux.conf b/tmux/tmux.conf deleted file mode 100644 index 9f3d07b..0000000 --- a/tmux/tmux.conf +++ /dev/null @@ -1,41 +0,0 @@ -set -ga terminal-overrides ",xterm-256color:Tc" - -# loud or quiet? -set -g visual-activity off -set -g visual-bell off -set -g visual-silence off -setw -g monitor-activity off -set -g bell-action none - -# modes -setw -g clock-mode-colour colour5 -setw -g mode-style 'fg=colour1 bg=colour18 bold' - -# panes -set -g pane-border-style 'fg=colour19 bg=colour0' -set -g pane-active-border-style 'bg=colour0 fg=colour9' - -# statusbar -set -g status-position bottom -set -g status-justify left -set -g status-style 'bg=colour18 fg=colour137 dim' -set -g status-left '' -set -g status-right '#[fg=colour233,bg=colour19] %d/%m #[fg=colour233,bg=colour8] %H:%M:%S ' -set -g status-right-length 50 -set -g status-left-length 20 - -setw -g window-status-current-style 'fg=colour1 bg=colour19 bold' -setw -g window-status-current-format ' #I#[fg=colour249]:#[fg=colour255]#W#[fg=colour249]#F ' - -setw -g window-status-style 'fg=colour9 bg=colour18' -setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F ' - -set -g status-bg black -set -g status-fg white - -setw -g window-status-bell-style 'fg=colour255 bg=colour1 bold' - -# messages -set -g message-style 'fg=colour232 bg=colour16 bold' - -set -sg escape-time 0 diff --git a/zellij/base-layout.kdl b/zellij/base-layout.kdl new file mode 100644 index 0000000..c96ea96 --- /dev/null +++ b/zellij/base-layout.kdl @@ -0,0 +1,17 @@ +layout { + pane size=1 borderless=true { + plugin location="tab-bar" + } + pane + pane size=1 borderless=true { + plugin location="status-bar" + } + pane split_direction="vertical" size=3 { + pane { + borderless true + name "zentime" + command "zentime" + args "-i" "minimal" + } + } +} diff --git a/zellij/config.kdl b/zellij/config.kdl new file mode 100644 index 0000000..7800c54 --- /dev/null +++ b/zellij/config.kdl @@ -0,0 +1,544 @@ +// If you'd like to override the default keybindings completely, be sure to change "keybinds" to "keybinds clear-defaults=true" +keybinds clear-defaults=true { + normal { + // uncomment this and adjust key if using copy_on_select=false + // bind "Alt c" { Copy; } + } + locked { + bind "Alt Shift g" { SwitchToMode "Normal"; } + } + resize { + bind "Alt Shift n" { SwitchToMode "Normal"; } + bind "h" "Left" { Resize "Increase Left"; } + bind "j" "Down" { Resize "Increase Down"; } + bind "k" "Up" { Resize "Increase Up"; } + bind "l" "Right" { Resize "Increase Right"; } + bind "H" { Resize "Decrease Left"; } + bind "J" { Resize "Decrease Down"; } + bind "K" { Resize "Decrease Up"; } + bind "L" { Resize "Decrease Right"; } + bind "=" "+" { Resize "Increase"; } + bind "-" { Resize "Decrease"; } + } + pane { + bind "Alt Shift p" { SwitchToMode "Normal"; } + bind "h" "Left" { MoveFocus "Left"; } + bind "l" "Right" { MoveFocus "Right"; } + bind "j" "Down" { MoveFocus "Down"; } + bind "k" "Up" { MoveFocus "Up"; } + bind "p" { SwitchFocus; } + bind "n" { NewPane; SwitchToMode "Normal"; } + bind "d" { NewPane "Down"; SwitchToMode "Normal"; } + bind "r" { NewPane "Right"; SwitchToMode "Normal"; } + bind "s" { NewPane "stacked"; SwitchToMode "Normal"; } + bind "x" { CloseFocus; SwitchToMode "Normal"; } + bind "f" { ToggleFocusFullscreen; SwitchToMode "Normal"; } + bind "z" { TogglePaneFrames; SwitchToMode "Normal"; } + bind "w" { ToggleFloatingPanes; SwitchToMode "Normal"; } + bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "Normal"; } + bind "c" { SwitchToMode "RenamePane"; PaneNameInput 0;} + bind "i" { TogglePanePinned; SwitchToMode "Normal"; } + } + move { + bind "Alt Shift h" { SwitchToMode "Normal"; } + bind "n" "Tab" { MovePane; } + bind "p" { MovePaneBackwards; } + bind "h" "Left" { MovePane "Left"; } + bind "j" "Down" { MovePane "Down"; } + bind "k" "Up" { MovePane "Up"; } + bind "l" "Right" { MovePane "Right"; } + } + tab { + bind "Alt Shift t" { SwitchToMode "Normal"; } + bind "r" { SwitchToMode "RenameTab"; TabNameInput 0; } + bind "h" "Left" "Up" "k" { GoToPreviousTab; } + bind "l" "Right" "Down" "j" { GoToNextTab; } + bind "n" { NewTab; SwitchToMode "Normal"; } + bind "x" { CloseTab; SwitchToMode "Normal"; } + bind "s" { ToggleActiveSyncTab; SwitchToMode "Normal"; } + bind "b" { BreakPane; SwitchToMode "Normal"; } + bind "]" { BreakPaneRight; SwitchToMode "Normal"; } + bind "[" { BreakPaneLeft; SwitchToMode "Normal"; } + bind "1" { GoToTab 1; SwitchToMode "Normal"; } + bind "2" { GoToTab 2; SwitchToMode "Normal"; } + bind "3" { GoToTab 3; SwitchToMode "Normal"; } + bind "4" { GoToTab 4; SwitchToMode "Normal"; } + bind "5" { GoToTab 5; SwitchToMode "Normal"; } + bind "6" { GoToTab 6; SwitchToMode "Normal"; } + bind "7" { GoToTab 7; SwitchToMode "Normal"; } + bind "8" { GoToTab 8; SwitchToMode "Normal"; } + bind "9" { GoToTab 9; SwitchToMode "Normal"; } + bind "Tab" { ToggleTab; } + } + scroll { + bind "Alt Shift s" { SwitchToMode "Normal"; } + bind "e" { EditScrollback; SwitchToMode "Normal"; } + bind "s" { SwitchToMode "EnterSearch"; SearchInput 0; } + bind "Alt Shift c" { ScrollToBottom; SwitchToMode "Normal"; } + bind "j" "Down" { ScrollDown; } + bind "k" "Up" { ScrollUp; } + bind "Alt Shift f" "PageDown" "Right" "l" { PageScrollDown; } + bind "Alt Shift b" "PageUp" "Left" "h" { PageScrollUp; } + bind "d" { HalfPageScrollDown; } + bind "u" { HalfPageScrollUp; } + // uncomment this and adjust key if using copy_on_select=false + // bind "Alt c" { Copy; } + } + search { + bind "Alt Shift s" { SwitchToMode "Normal"; } + bind "Alt Shift c" { ScrollToBottom; SwitchToMode "Normal"; } + bind "j" "Down" { ScrollDown; } + bind "k" "Up" { ScrollUp; } + bind "Alt Shift f" "PageDown" "Right" "l" { PageScrollDown; } + bind "Alt Shift b" "PageUp" "Left" "h" { PageScrollUp; } + bind "d" { HalfPageScrollDown; } + bind "u" { HalfPageScrollUp; } + bind "n" { Search "down"; } + bind "p" { Search "up"; } + bind "c" { SearchToggleOption "CaseSensitivity"; } + bind "w" { SearchToggleOption "Wrap"; } + bind "o" { SearchToggleOption "WholeWord"; } + } + entersearch { + bind "Alt Shift c" "Esc" { SwitchToMode "Scroll"; } + bind "Enter" { SwitchToMode "Search"; } + } + renametab { + bind "Alt Shift c" { SwitchToMode "Normal"; } + bind "Esc" { UndoRenameTab; SwitchToMode "Tab"; } + } + renamepane { + bind "Alt Shift c" { SwitchToMode "Normal"; } + bind "Esc" { UndoRenamePane; SwitchToMode "Pane"; } + } + session { + bind "Alt Shift o" { SwitchToMode "Normal"; } + bind "Alt Shift s" { SwitchToMode "Scroll"; } + bind "d" { Detach; } + bind "w" { + LaunchOrFocusPlugin "session-manager" { + floating true + move_to_focused_tab true + }; + SwitchToMode "Normal" + } + bind "c" { + LaunchOrFocusPlugin "configuration" { + floating true + move_to_focused_tab true + }; + SwitchToMode "Normal" + } + bind "p" { + LaunchOrFocusPlugin "plugin-manager" { + floating true + move_to_focused_tab true + }; + SwitchToMode "Normal" + } + bind "a" { + LaunchOrFocusPlugin "zellij:about" { + floating true + move_to_focused_tab true + }; + SwitchToMode "Normal" + } + bind "s" { + LaunchOrFocusPlugin "zellij:share" { + floating true + move_to_focused_tab true + }; + SwitchToMode "Normal" + } + bind "q" { + LaunchPlugin "zellij:sequence" { + floating true + }; + SwitchToMode "Normal" + } + bind "l" { + LaunchOrFocusPlugin "zellij:layout-manager" { + floating true + move_to_focused_tab true + }; + SwitchToMode "Normal" + } + } + tmux { + bind "[" { SwitchToMode "Scroll"; } + bind "Alt Shift b" { Write 2; SwitchToMode "Normal"; } + bind "\"" { NewPane "Down"; SwitchToMode "Normal"; } + bind "%" { NewPane "Right"; SwitchToMode "Normal"; } + bind "z" { ToggleFocusFullscreen; SwitchToMode "Normal"; } + bind "c" { NewTab; SwitchToMode "Normal"; } + bind "," { SwitchToMode "RenameTab"; } + bind "p" { GoToPreviousTab; SwitchToMode "Normal"; } + bind "n" { GoToNextTab; SwitchToMode "Normal"; } + bind "Left" { MoveFocus "Left"; SwitchToMode "Normal"; } + bind "Right" { MoveFocus "Right"; SwitchToMode "Normal"; } + bind "Down" { MoveFocus "Down"; SwitchToMode "Normal"; } + bind "Up" { MoveFocus "Up"; SwitchToMode "Normal"; } + bind "h" { MoveFocus "Left"; SwitchToMode "Normal"; } + bind "l" { MoveFocus "Right"; SwitchToMode "Normal"; } + bind "j" { MoveFocus "Down"; SwitchToMode "Normal"; } + bind "k" { MoveFocus "Up"; SwitchToMode "Normal"; } + bind "o" { FocusNextPane; } + bind "d" { Detach; } + bind "Space" { NextSwapLayout; } + bind "x" { CloseFocus; SwitchToMode "Normal"; } + } + shared_except "locked" { + bind "Alt Shift g" { SwitchToMode "Locked"; } + bind "Alt Shift q" { Quit; } + bind "Alt f" { ToggleFloatingPanes; } + bind "Alt n" { NewPane; } + bind "Alt i" { MoveTab "Left"; } + bind "Alt o" { MoveTab "Right"; } + bind "Alt h" "Alt Left" { MoveFocusOrTab "Left"; } + bind "Alt l" "Alt Right" { MoveFocusOrTab "Right"; } + bind "Alt j" "Alt Down" { MoveFocus "Down"; } + bind "Alt k" "Alt Up" { MoveFocus "Up"; } + bind "Alt =" "Alt +" { Resize "Increase"; } + bind "Alt -" { Resize "Decrease"; } + bind "Alt [" { PreviousSwapLayout; } + bind "Alt ]" { NextSwapLayout; } + bind "Alt p" { TogglePaneInGroup; } + bind "Alt Shift p" { ToggleGroupMarking; } + } + shared_except "normal" "locked" { + bind "Enter" "Esc" { SwitchToMode "Normal"; } + } + shared_except "pane" "locked" { + bind "Alt Shift p" { SwitchToMode "Pane"; } + } + shared_except "resize" "locked" { + bind "Alt Shift n" { SwitchToMode "Resize"; } + } + shared_except "scroll" "locked" { + bind "Alt Shift s" { SwitchToMode "Scroll"; } + } + shared_except "session" "locked" { + bind "Alt Shift o" { SwitchToMode "Session"; } + } + shared_except "tab" "locked" { + bind "Alt Shift t" { SwitchToMode "Tab"; } + } + shared_except "move" "locked" { + bind "Alt Shift h" { SwitchToMode "Move"; } + } + shared_except "tmux" "locked" { + bind "Alt Shift b" { SwitchToMode "Tmux"; } + } +} + +// Plugin aliases - can be used to change the implementation of Zellij +// changing these requires a restart to take effect +plugins { + tab-bar location="zellij:tab-bar" + status-bar location="zellij:status-bar" + strider location="zellij:strider" + compact-bar location="zellij:compact-bar" + session-manager location="zellij:session-manager" + welcome-screen location="zellij:session-manager" { + welcome_screen true + } + filepicker location="zellij:strider" { + cwd "/" + } + configuration location="zellij:configuration" + plugin-manager location="zellij:plugin-manager" + about location="zellij:about" + sequence location="zellij:sequence" +} + +// Plugins to load in the background when a new session starts +load_plugins { + // "file:/path/to/my-plugin.wasm" + // "https://example.com/my-plugin.wasm" +} + +// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP +// eg. when terminal window with an active zellij session is closed +// (Requires restart) +// Options: +// - detach (Default) +// - quit +// +// on_force_close "quit" + +// Send a request for a simplified ui (without arrow fonts) to plugins +// Options: +// - true +// - false (Default) +// +// simplified_ui true + +// Choose the path to the default shell that zellij will use for opening new panes +// Default: $SHELL +// +// default_shell "fish" + +// Choose the path to override cwd that zellij will use for opening new panes +// +// default_cwd "" + +// Toggle between having pane frames around the panes +// Options: +// - true (default) +// - false +// +// pane_frames true + +// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible +// Options: +// - true (default) +// - false +// +// auto_layout true + +// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected +// (Requires restart) +// Options: +// - true (default) +// - false +// +// session_serialization false + +// Whether pane viewports are serialized along with the session, default is false +// (Requires restart) +// Options: +// - true +// - false (default) +// +// serialize_pane_viewport true + +// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0 +// defaults to the scrollback size. If this number is higher than the scrollback size, it will +// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true. +// (Requires restart) +// +// scrollback_lines_to_serialize 10000 + +// Define color themes for Zellij +// For more examples, see: https://github.com/zellij-org/zellij/tree/main/example/themes +// Once these themes are defined, one of them should to be selected in the "theme" section of this file +// +themes { + custom { + fg 255 255 255 + bg 30 30 46 + red 255 69 58 + green 255 140 0 + yellow 255 214 10 + blue 50 140 255 + magenta 255 55 190 + orange 255 140 0 + cyan 0 230 255 + black 0 0 0 + white 255 255 255 + } +} + +// Choose the theme that is specified in the themes section. +// Default: default +// +theme "custom" + +// The name of the default layout to load on startup +// Default: "default" +// (Requires restart) +// +// default_layout "compact" + +// Choose the mode that zellij uses when starting up. +// Default: normal +// +// default_mode "locked" + +// Toggle enabling the mouse mode. +// On certain configurations, or terminals this could +// potentially interfere with copying text. +// (Requires restart) +// Options: +// - true (default) +// - false +// +// mouse_mode false + +// Configure the scroll back buffer size +// This is the number of lines zellij stores for each pane in the scroll back +// buffer. Excess number of lines are discarded in a FIFO fashion. +// (Requires restart) +// Valid values: positive integers +// Default value: 10000 +// +// scroll_buffer_size 10000 + +// Provide a command to execute when copying text. The text will be piped to +// the stdin of the program to perform the copy. This can be used with +// terminal emulators which do not support the OSC 52 ANSI control sequence +// that will be used by default if this option is not set. +// Examples: +// +// copy_command "xclip -selection clipboard" // x11 +// copy_command "wl-copy" // wayland +// copy_command "pbcopy" // osx + +// Choose the destination for copied text +// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard. +// Does not apply when using copy_command. +// Options: +// - system (default) +// - primary +// +// copy_clipboard "primary" + +// Enable or disable automatic copy (and clear) of selection when releasing mouse +// Default: true +// +// copy_on_select false + +// Path to the default editor to use to edit pane scrollbuffer +// Default: $EDITOR or $VISUAL +// +// scrollback_editor "/usr/bin/vim" + +// When attaching to an existing session with other users, +// should the session be mirrored (true) +// or should each user have their own cursor (false) +// (Requires restart) +// Default: false +// +// mirror_session true + +// The folder in which Zellij will look for layouts +// (Requires restart) +// +// layout_dir "/path/to/my/layout_dir" + +// The folder in which Zellij will look for themes +// (Requires restart) +// +// theme_dir "/path/to/my/theme_dir" + +// Enable or disable the rendering of styled and colored underlines (undercurl). +// May need to be disabled for certain unsupported terminals +// (Requires restart) +// Default: true +// +// styled_underlines false + +// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know +// metadata info on this session) +// (Requires restart) +// Default: false +// +// disable_session_metadata true + +// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it) +// (Requires restart) +// Default: true (if the host terminal supports it) +// +// support_kitty_keyboard_protocol false + +// Whether to make sure a local web server is running when a new Zellij session starts. +// This web server will allow creating new sessions and attaching to existing ones that have +// opted in to being shared in the browser. +// When enabled, navigate to http://127.0.0.1:8082 +// (Requires restart) +// +// Note: a local web server can still be manually started from within a Zellij session or from the CLI. +// If this is not desired, one can use a version of Zellij compiled without +// `web_server_capability` +// +// Possible values: +// - true +// - false +// Default: false +// +// web_server true + +// Whether to allow sessions started in the terminal to be shared through a local web server, assuming one is +// running (see the `web_server` option for more details). +// (Requires restart) +// +// Note: This is an administrative separation and not intended as a security measure. +// +// Possible values: +// - "on" (allow web sharing through the local web server if it +// is online) +// - "off" (do not allow web sharing unless sessions explicitly opt-in to it) +// - "disabled" (do not allow web sharing and do not permit sessions started in the terminal to opt-in to it) +// Default: "off" +// +// web_sharing "on" + +// The ip address the web server should listen on when it starts +// Default: "127.0.0.1" +// (Requires restart) +// +// web_server_ip "127.0.0.1" + + +// A path to a certificate file to be used when setting up the web client to serve the +// connection over HTTPs +// +// web_server_cert "/path/to/my/cert.pem" + +// A path to a key file to be used when setting up the web client to serve the +// connection over HTTPs +// +// web_server_key "/path/to/my/key.pem" + +// Whether to enforce https connections to the web server when it is bound to localhost +// (127.0.0.0/8) +// +// Note: https is ALWAYS enforced when bound to non-local interfaces +// +// Default: false +// +// enforce_https_for_localhost true + +// The port the web server should listen on when it starts +// Default: 8082 +// (Requires restart) +// +// web_server_port 8082 + +// Whether to stack panes when resizing beyond a certain size +// Default: true +// +// stacked_resize false + +// Whether to show release notes on first version run +// Default: true +// +// show_release_notes false + +// Whether to enable mouse hover effects and pane grouping functionality +// Default: true +// +// advanced_mouse_actions false + +// Whether to enable mouse hover visual effects (frame highlight and help text) +// Default: true +// +// mouse_hover_effects false + +// Whether to output OSC8 hyperlink sequences +// Default: true +// +// osc8_hyperlinks false + +// A command to run (will be wrapped with sh -c and provided the RESURRECT_COMMAND env variable) +// after Zellij attempts to discover a command inside a pane when resurrecting sessions, the STDOUT +// of this command will be used instead of the discovered RESURRECT_COMMAND +// can be useful for removing wrappers around commands +// Note: be sure to escape backslashes and similar characters properly +// +// post_command_discovery_hook "echo $RESURRECT_COMMAND | sed " + + +web_client { + font "monospace" +} diff --git a/zshell/.zshrc b/zshell/.zshrc deleted file mode 100644 index 773caae..0000000 --- a/zshell/.zshrc +++ /dev/null @@ -1,63 +0,0 @@ -# Path to your oh-my-zsh installation. -export ZSH="$HOME/.oh-my-zsh" - -# Set name of the theme to load --- if set to "random", it will -# load a random theme each time oh-my-zsh is loaded, in which case, -# to know which specific one was loaded, run: echo $RANDOM_THEME -# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes -ZSH_THEME="junkfood" - -# Uncomment the following line if you want to change the command execution time -# stamp shown in the history command output. -# You can set one of the optional three formats: -# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" -# or set a custom format using the strftime function format specifications, -# see 'man strftime' for details. -HIST_STAMPS="mm/dd/yyyy" - -# Would you like to use another custom folder than $ZSH/custom? -# ZSH_CUSTOM=/path/to/new-custom-folder - -# Which plugins would you like to load? -# Standard plugins can be found in $ZSH/plugins/ -# Custom plugins may be added to $ZSH_CUSTOM/plugins/ -# Example format: plugins=(rails git textmate ruby lighthouse) -# Add wisely, as too many plugins slow down shell startup. -plugins=(git nvm zsh-interactive-cd zsh-autosuggestions docker colorize colored-man-pages) - -source $ZSH/oh-my-zsh.sh - -export VISUAL=nvim - -# General aliases -alias vim=nvim -alias vi=nvim -alias k="kubectl" - - -alias docs="cd ~/repos/documentation && vim ." - -alias term="nvim --cmd :terminal" - -# Proceedix specific aliases -# alias wiki="cd ~/repos/Proceedix%20General.wiki/ && vim ." -# -# alias dots="cd ~/repos/dotfiles && vim ." -# -# alias devops="cd ~/repos/devops-notes && vim ." -# alias proceedix="cd ~/repos/proceedix && vim ." -# -# alias portal="cd ~/repos/service-admin-portal && vim ." -# alias backend="cd ~/repos/api-v3 && vim ." - -# alias sgreportal="cd ~/repos/sgre-portal && vim ." -# alias sgrebackend="cd ~/repos/sgre-as-backend-services && vim ." - -# export DOTNET_ROOT=$HOME/dotnet -# export DOCKER_CONFIG=$HOME/.docker -# -[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh - -export PYENV_ROOT="$HOME/.pyenv" -[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" -eval "$(pyenv init -)"