From 7558d5f05ec9cda11f9269266789b343606a40ad Mon Sep 17 00:00:00 2001
From: Daniel Braunwarth <oss@braunwarth.dev>
Date: Sat, 14 Dec 2024 10:09:35 +0100
Subject: [PATCH] feat(run0): add run0 plugin

---
 plugins/run0/README.md       | 61 ++++++++++++++++++++++++++++++++++++
 plugins/run0/run0.plugin.zsh | 44 ++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)
 create mode 100644 plugins/run0/README.md
 create mode 100644 plugins/run0/run0.plugin.zsh

diff --git a/plugins/run0/README.md b/plugins/run0/README.md
new file mode 100644
index 000000000..983e74ba3
--- /dev/null
+++ b/plugins/run0/README.md
@@ -0,0 +1,61 @@
+# run0
+
+Easily prefix your current or previous commands with `run0` by pressing <kbd>esc</kbd> twice.
+
+To use it, add `run0` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... run0)
+```
+
+## Usage
+
+### Current typed commands
+
+Say you have typed a long command and forgot to add `run0` in front:
+
+```console
+$ apt-get install build-essential
+```
+
+By pressing the <kbd>esc</kbd> key twice, you will have the same command with `run0` prefixed without typing:
+
+```console
+$ run0 apt-get install build-essential
+```
+
+### Previous executed commands
+
+Say you want to delete a system file and denied:
+
+```console
+$ rm some-system-file.txt
+-su: some-system-file.txt: Permission denied
+$
+```
+
+By pressing the <kbd>esc</kbd> key twice, you will have the same command with `run0` prefixed without typing:
+
+```console
+$ rm some-system-file.txt
+-su: some-system-file.txt: Permission denied
+$ run0 rm some-system-file.txt
+Password:
+$
+```
+
+The same happens for file editing, as told before.
+
+## Key binding
+
+By default, the `run0` plugin uses <kbd>Esc</kbd><kbd>Esc</kbd> as the trigger.
+If you want to change it, you can use the `bindkey` command to bind it to a different key:
+
+```sh
+bindkey -M emacs '<seq>' run0-command-line
+bindkey -M vicmd '<seq>' run0-command-line
+bindkey -M viins '<seq>' run0-command-line
+```
+
+where `<seq>` is the sequence you want to use. You can find the keyboard sequence
+by running `cat` and pressing the keyboard combination you want to use.
diff --git a/plugins/run0/run0.plugin.zsh b/plugins/run0/run0.plugin.zsh
new file mode 100644
index 000000000..81f2207a2
--- /dev/null
+++ b/plugins/run0/run0.plugin.zsh
@@ -0,0 +1,44 @@
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+# run0 will be inserted before the command
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+# * Daniel Braunwarth <oss@braunwarth.dev>
+#
+# ------------------------------------------------------------------------------
+
+__run0-replace-buffer() {
+  local old=$1 new=$2 space=${2:+ }
+
+  # if the cursor is positioned in the $old part of the text, make
+  # the substitution and leave the cursor after the $new text
+  if [[ $CURSOR -le ${#old} ]]; then
+    BUFFER="${new}${space}${BUFFER#$old }"
+    CURSOR=${#new}
+  # otherwise just replace $old with $new in the text before the cursor
+  else
+    LBUFFER="${new}${space}${LBUFFER#$old }"
+  fi
+}
+
+run0-command-line() {
+  # If line is empty, get the last run command from history
+  [[ -z $BUFFER ]] && LBUFFER="$(fc -ln -1)"
+
+  case "$BUFFER" in
+    run0\ *) __run0-replace-buffer "run0" "" ;;
+    *) LBUFFER="run0 $LBUFFER" ;;
+  esac
+}
+
+zle -N run0-command-line
+
+# Defined shortcut keys: [Esc] [Esc]
+bindkey -M emacs '\e\e' run0-command-line
+bindkey -M vicmd '\e\e' run0-command-line
+bindkey -M viins '\e\e' run0-command-line