Sunday, August 03, 2025

When bash Doesn't Have the Command You Need, Then There's chatGPT

Back to list

🔧 Bash Tip: Delete from Cursor to Next Whitespace (Opposite of Ctrl+w)

By default, Bash (via readline) does not include a shortcut to delete from the cursor up to the next whitespace — only backward with Ctrl+w.

To fix that, you can create your own shortcut using bind -x and a bit of shell scripting. Here's how to do it, using Ctrl+o as the keybinding:

# ~/.bashrc or ~/.inputrc-compatible shell

# delete forward to next whitespace
delete_to_next_whitespace() {
  local line="${READLINE_LINE}"
  local pt=${READLINE_POINT}
  local rest="${line:pt}"
  local idx
  idx=$(expr index "$rest" ' ')
  if (( idx > 0 )); then
    READLINE_LINE="${line:0:pt}${rest:idx}"
  else
    READLINE_LINE="${line:0:pt}"
  fi
  READLINE_POINT=$pt
}

# Bind it to Ctrl+o (you can change this to any available combo)
bind -x '"\C-o": delete_to_next_whitespace'

🧠 How It Works

  • READLINE_LINE: the entire current input line
  • READLINE_POINT: the current cursor position
  • expr index: finds the position of the first space
  • The function trims out everything from the cursor up to (and including) that space

✅ Result

Once added to your ~/.bashrc and reloaded (source ~/.bashrc), hitting Ctrl+o will delete from the cursor to the next space.

⚠️ Why Not Use Alt+d?

The default Alt+d (kill-word) honors underscores, dashes, and slashes as part of a "word" — which makes it incompatible with the goal of trimming up to the next whitespace.

💡 Bonus Tip

If you want to treat tabs or multiple space types as separators, replace this line:

idx=$(expr index "$rest" ' ')

...with this one:

idx=$(expr match "$rest" '[^[:space:]]* *')

Tested on GNU Bash 5.2 with Emacs-style line editing (default). For vi mode users, this approach won't apply.

⚠️ What if You Want to Keep that Whitespace?

# ~/.bashrc or ~/.inputrc-compatible shell

# delete forward to next whitespace (keeping the space)
delete_to_next_whitespace() {
  local line="${READLINE_LINE}"
  local pt=${READLINE_POINT}
  local rest="${line:pt}"
  local idx
  idx=$(expr index "$rest" ' ')
  if (( idx > 0 )); then
    local keep="${rest:idx-1}"  # start *at* the whitespace
    READLINE_LINE="${line:0:pt}${keep}"
  else
    READLINE_LINE="${line:0:pt}"
  fi
  READLINE_POINT=$pt
}

# Bind it to Ctrl+o (you can change this to any available combo)
bind -x '"\C-o": delete_to_next_whitespace'

No comments: