diff --git a/README.md b/README.md index f4c46bb..dbbf7ca 100644 --- a/README.md +++ b/README.md @@ -165,23 +165,6 @@ These are the main parts of every task file script. Now see [usage](/usage) on how to use the task file. -## Naming +## Development -The naming of functions is important. There are basically two styles: - -1. Action + Object -2. Object + Action - -The task file functions use the first style. The name of the function starts with an action followed by an object. The object name can be singular or plural. - -**Examples for actions**: activate, install, dev, develop, init, build, start, update, remove, delete, enable, disable, template, convert, create, edit, change, get, set, patch, fetch, generate, push, pull, import, export, list, publish, release, test, setup, prepare, restart, stop, store, restore, translate, upgrade, zip, visualize, sync, switch, run, reset, load, dump, checkout, commit, drop, deploy, handle, trigger, render, lint, uninstall, split, parse, fix, refactor, transform, cat, ls, rm, serve, help, show, filter, login, logout, encrypt, decrypt, upload, download, analyse, transpile, compile, minify, copy - -**Examples for objects**: env, venv, submodule, container, database, snippet, model, module, repo, mail, doc, dependency, view, user, vault, file, host, node, log, password, hash, script, requirement, part, component, system, workspace, image, process, state, platform, dir, folder, readme, overview, lang, level, request, response, result, worker, server, proxy, workflow, volume, network, package, field, value, secret, chart, node, edge, function, method, firewall, html, css, image, svg, style, query, native, group, notebook - -**Objects can be tools**: odoo, vupress, nodejs, zsh, bash, fish, podman, kind, minikube, helm, nvim, docker, podman, rust, python, tmux, vim, helix, system, git, pass, llm, sql, dotenv, javascript, vue, vite, astro, typescript, turbo, pnpm, eslint, jenkins, k8s, nextcloud, postgres, metabase, ansible, prometheus, grafana, hugo, deno, bun, babel, panda, gulp, grunt, electron, react, express, mongodb, angular, ionic, meteor, webpack, bower, jupyter - - - -## Style - -The bash scripts follow the [Bash Style Guide | ysap.sh](https://style.ysap.sh/). Have a look at the [AGENTS.md](/AGENTS) for details on the applied styling. +Checkout the [development](/development) page for details. diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index a515010..9f25b56 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -28,11 +28,11 @@
  • taskfile.build
  • diff --git a/development.md b/development.md new file mode 100644 index 0000000..e319f48 --- /dev/null +++ b/development.md @@ -0,0 +1,40 @@ +--- +layout: layouts/base.njk +--- + +# Development + +The devleopment environment requires these tools: + +- [shellcheck](https://www.shellcheck.net/) +- [pnpm](https://pnpm.io/) + +Clone this repo and enter the folder. + +```bash +git clone https://git.taskfile.build "$HOME/taskfile.build" +cd "$HOME/taskfile.build" +``` + +Run `task help` to list the commands of this project. + +## Style + +The bash scripts follow the [Bash Style Guide | ysap.sh](https://style.ysap.sh/). Have a look at the [AGENTS.md](/AGENTS) for details on the applied styling. + +## Naming + +The naming of functions is important. There are basically two styles: + +1. Action + Object +2. Object + Action + +The task file functions use the first style. The name of the function starts with an action followed by an object. The object name can be singular or plural. + +**Examples for actions**: activate, install, dev, develop, init, build, start, update, remove, delete, enable, disable, template, convert, create, edit, change, get, set, patch, fetch, generate, push, pull, import, export, list, publish, release, test, setup, prepare, restart, stop, store, restore, translate, upgrade, zip, visualize, sync, switch, run, reset, load, dump, checkout, commit, drop, deploy, handle, trigger, render, lint, uninstall, split, parse, fix, refactor, transform, cat, ls, rm, serve, help, show, filter, login, logout, encrypt, decrypt, upload, download, analyse, transpile, compile, minify, copy + +**Examples for objects**: env, venv, submodule, container, database, snippet, model, module, repo, mail, doc, dependency, view, user, vault, file, host, node, log, password, hash, script, requirement, part, component, system, workspace, image, process, state, platform, dir, folder, readme, overview, lang, level, request, response, result, worker, server, proxy, workflow, volume, network, package, field, value, secret, chart, node, edge, function, method, firewall, html, css, image, svg, style, query, native, group, notebook + +**Objects can be tools**: odoo, vupress, nodejs, zsh, bash, fish, podman, kind, minikube, helm, nvim, docker, podman, rust, python, tmux, vim, helix, system, git, pass, llm, sql, dotenv, javascript, vue, vite, astro, typescript, turbo, pnpm, eslint, jenkins, k8s, nextcloud, postgres, metabase, ansible, prometheus, grafana, hugo, deno, bun, babel, panda, gulp, grunt, electron, react, express, mongodb, angular, ionic, meteor, webpack, bower, jupyter + + diff --git a/library.md b/library.md index ef9cfb1..87782b5 100644 --- a/library.md +++ b/library.md @@ -219,6 +219,12 @@ The last parameter can be either a direct prompt string or a path to a text file rows+=("update-changelog-with-llm||Update CHANGELOG.md with changes from staged git diff using LLM.") ``` +### setup-completion + +```bash +rows+=("setup-completion|[shell]|Show shell completion instructions.") +``` + ## Logging Colorful logging in task commands. diff --git a/prompts/04_add-command-update-changelog-from-git-diff.md b/prompts/04_add-command-update-changelog-from-git-diff.md index 29ef581..67d70e2 100644 --- a/prompts/04_add-command-update-changelog-from-git-diff.md +++ b/prompts/04_add-command-update-changelog-from-git-diff.md @@ -4,4 +4,4 @@ Add a new command `update-changelog-with-llm`. This command reads the `CHANGELOG.md` and the staged git diff. Then it updates the `CHANGELOG.md` with the changes made and adds the file to the staged changes. -Add the new commands to the `library.md` in the LLM section. Then run `task update-template`. \ No newline at end of file +Add the new commands to the `library.md` in the LLM section. Then run `task update-template`. diff --git a/prompts/05_add-emojies-to-navigation.md b/prompts/05_add-emojies-to-navigation.md new file mode 100644 index 0000000..2524e9d --- /dev/null +++ b/prompts/05_add-emojies-to-navigation.md @@ -0,0 +1,3 @@ +Read the AGENTS.md and README.md to get understanding of the project. + +Add a matching emoji to the navigation entries of the 11ty template `_includes/layouts/base.njk`. diff --git a/prompts/06_completion_script.md b/prompts/06_completion_script.md new file mode 100644 index 0000000..4013ee1 --- /dev/null +++ b/prompts/06_completion_script.md @@ -0,0 +1,43 @@ +Read the AGENTS.md and README.md to get understanding of the project. + +In the `usage.md` file, I have completion section. Instead of showing the completion scripts I want you to add a new command: `setup-completion`. + +The command shows the completion instructions. Here is an example of `opencode`: + +```bash + +[main][~/dotfiles]$ opencode completion +#compdef opencode +###-begin-opencode-completions-### +# +# yargs command completion script +# +# Installation: opencode completion >> ~/.zshrc +# or opencode completion >> ~/.zprofile on OSX. +# +_opencode_yargs_completions() +{ + local reply + local si=$IFS + IFS=$' +' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" opencode --get-yargs-completions "${words[@]}")) + IFS=$si + if [[ ${#reply} -gt 0 ]]; then + _describe 'values' reply + else + _default + fi +} +if [[ "'${zsh_eval_context[-1]}" == "loadautofunc" ]]; then + _opencode_yargs_completions "$@" +else + compdef _opencode_yargs_completions opencode +fi +###-end-opencode-completions-### +``` + +The command detects if bash or zsh is active. + +If should be possible to `task setup-completion >> ~/.zshrc` + +Add the new commands to the `library.md` in the LLM section. diff --git a/task b/task index 77cf2d8..6f42ad5 100755 --- a/task +++ b/task @@ -9,7 +9,6 @@ help-table() { rows+=("all||Run all tasks.") rows+=("build-11ty||Build the 11ty website.") rows+=("build-image|[output]|Build Docker image with buildx.") - rows+=("commit-with-llm||Commit with llm generated commit message.") rows+=("dev-11ty||Run 11ty server.") rows+=("help|[grep]|Show help for commands.") rows+=("install||Install Node packages.") @@ -17,6 +16,7 @@ help-table() { rows+=("run||Run Docker image.") rows+=("run-tests||Test with shellcheck.") rows+=("serve-11ty||Serve the 11ty output folder.") + rows+=("setup-completion|[shell]|Show shell completion instructions.") rows+=("update-template||Update task.template from library.md.") rows+=("version||Show version of required tools.") @@ -118,7 +118,134 @@ serve-11ty() { } version() { + echo "pnpm: $(pnpm --version)" echo "eleventy: $(pnpm dlx @11ty/eleventy --version)" + echo "shellcheck: $(shellcheck --version)" +} + +setup-completion() { + local shell_type="$1" + + # Set default shell type if not provided + if [[ -z "$shell_type" ]]; then + shell_type="bash" # Default to bash + fi + + # Validate shell type + case "$shell_type" in + bash|zsh|fish) + # Valid shell type + ;; + *) + echo "Error: Unsupported shell type '$shell_type'. Use 'bash', 'zsh', or 'fish'." + echo "Usage: task setup-completion [bash|zsh|fish]" + return 1 + ;; + esac + + # Output the actual completion script + output_completion_script "$shell_type" + + # Add instructions as comments at the end + echo "" + echo "# ============================================" + echo "# Taskfile completion setup instructions" + echo "# ============================================" + echo "# To enable completion, add this script to your shell configuration:" + + if [[ "$shell_type" == "fish" ]]; then + echo "# task setup-completion fish >> ~/.config/fish/config.fish" + echo "# source ~/.config/fish/config.fish" + elif [[ "$shell_type" == "zsh" ]]; then + echo "# task setup-completion zsh >> ~/.zshrc" + echo "# source ~/.zshrc" + else + echo "# task setup-completion bash >> ~/.bashrc" + echo "# source ~/.bashrc" + fi + echo "# ============================================" +} + +output_completion_script() { + local shell_type="$1" + + # Default to bash if no shell type provided + if [[ -z "$shell_type" ]]; then + shell_type="bash" + fi + + if [[ "$shell_type" == "fish" ]]; then + # Fish completion script + cat << 'EOF' +# Taskfile completion for fish +function _task_completions + # Get the current word being typed + set cur (commandline -p) + + # Get the previous word + set prev (commandline -oprev) + + # Get the available commands from `task help` + set commands (./task help | grep -A100 -e '---' | awk '{print $2}' | sed 's/^[[:space:]]*//' | grep -v '^$' | tr '\n' ' ') + + if test (count (commandline -opc)) -eq 1 + # Provide completions for the command part (second word) + complete -c task -f -n "__fish_seen_subcommand_from $prev" -a "$commands" + else if test (count (commandline -opc)) -eq 2 + # Provide file path completions for the third parameter + complete -c task -f -n "__fish_seen_subcommand_from $prev" -a (ls) + end +end +EOF + elif [[ "$shell_type" == "zsh" ]]; then + # ZSH completion script + cat << 'EOF' +# Taskfile completion for zsh +_task_completions() { + local reply + local si=$IFS + IFS=$' +' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" ./task help | grep -A999 -e '---' | awk '{print $2}' | sed 's/^[[:space:]]*//' | grep -v '^$' | tr ' +' ' ')) + IFS=$si + if [[ ${#reply} -gt 0 ]]; then + _describe 'values' reply + else + _default + fi +} + +if [[ "${zsh_eval_context[-1]}" == "loadautofunc" ]]; then + _task_completions "$@" +else + compdef _task_completions task + compdef _task_completions t +fi +EOF + else + # Bash completion script + cat << 'EOF' +# Taskfile completion for bash +_task_completions() { + local cur prev commands + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + commands=$(./task help | grep -A999 -e '---' | awk '{print $2}' | sed 's/^[[:space:]]*//' | grep -v '^$' | tr '\n' ' ') + + if [[ ${COMP_CWORD} == 1 ]]; then + COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) + elif [[ ${COMP_CWORD} == 2 ]]; then + COMPREPLY=( $(compgen -f -- "${cur}") ) + else + COMPREPLY=() + fi +} + +complete -F _task_completions task +complete -F _task_completions t +EOF + fi } update-template() { diff --git a/task.template b/task.template index 0e78082..9905048 100755 --- a/task.template +++ b/task.template @@ -55,6 +55,7 @@ help-table() { rows+=("login-docker|[user][token]|Run Docker login and create docker config.") rows+=("build-image|[output]|Build Docker image with buildx.") rows+=("install-ansible-build-scripts|[role]|Install scripts of the specified Ansbile role.") + rows+=("setup-completion||Show shell completion instructions.") for row in "${rows[@]}"; do IFS='|' read -r cmd opt desc <<< "$row" diff --git a/usage.md b/usage.md index 4ea6e22..cad1383 100644 --- a/usage.md +++ b/usage.md @@ -15,11 +15,11 @@ task [options] commands: -| Command | Option | Description | -|----------------------|--------|--------------------------------------| -| all | | Run all tasks. | -| install | | Install build dependencies. | -| lint | | Lint code with prettier. | +| Command | Option | Description | +|-------------|--------|-----------------------------| +| all | | Run all tasks. | +| install | | Install build dependencies. | +| lint | | Lint code with prettier. | ... ``` @@ -33,45 +33,35 @@ And if there is a command group run it with `task all`. With the output of `task help` the task commands can be completed. -Completion for bash: `/etc/bash_completion.d/task_completions` +To set up shell completion, specify your shell type: + +For bash: ```bash -#!/usr/bin/env bash - -_task_completions() { - local cur prev commands - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - - commands=$(./task help | grep -A999 -e '---' | awk '{print $2}' | sed 's/^[[:space:]]*//' | grep -v '^$' | tr '\n' ' ') - - if [[ ${COMP_CWORD} == 1 ]]; then - COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) - elif [[ ${COMP_CWORD} == 2 ]]; then - COMPREPLY=( $(compgen -f -- "${cur}") ) - else - COMPREPLY=() - fi -} - -complete -F _task_completions task -complete -F _task_completions t +task setup-completion bash >> ~/.bashrc +source ~/.bashrc ``` -Completion for zsh: `~/.oh-my-zsh/completions/_task` +For zsh: ```bash -#compdef task t +task setup-completion zsh >> ~/.zshrc +source ~/.zshrc +``` -_arguments '1: :->tasks' '*: :_files' +For fish: -case "$state" in - tasks) - args=$(./task help | grep -A999 -e '---' | awk '{print $2}' | sed 's/^[[:space:]]*//' | grep -v '^$' | tr '\n' ' ') - args="$args help" - _arguments "1:profiles:($args)" - ;; -esac +```bash +task setup-completion fish >> ~/.config/fish/config.fish +source ~/.config/fish/config.fish +``` + +To see the completion script without applying it: + +```bash +task setup-completion bash # Shows bash completion script +task setup-completion zsh # Shows zsh completion script +task setup-completion fish # Shows fish completion script ``` The completion also works for task alias `alias t='./task'`.