Bash – readline – yank resets set-mark

bashkeyboard shortcutsreadline

I want to implement this binding

"\C-xk": kill-region

# turn previous word into HTML/XML
# opening and closing tag pair
"\C-xh": "\e \eb\C-xk<\C-y>\e </\C-y>\C-x\C-x"

but it returns to the position were text was yanked for the second time after </ instead of to the position between the tags, e.g. <tag>|</|tag>.

I tried both functions at the command line with various texts and it seems that set-mark value is reset by yank.

Is it a bug or by design? For now I just added \C-b\C-b at the end of the sequence.

Best Answer

This is not a bug but an explicitly programmed behavior.

If you look at kill.c -> rl_yank():512

/* Yank back the last killed text.  This ignores arguments. */
int
rl_yank (count, ignore)
     int count, ignore;
{
  if (rl_kill_ring == 0)
    {
      _rl_abort_internal ();
      return 1;
    }

  _rl_set_mark_at_pos (rl_point);
  rl_insert_text (rl_kill_ring[rl_kill_index]);
  return 0;
}

You can see that it explicitly resets the mark to the current point, before inserting the text from the kill ring.

The same applies to the other yank* methods.

This is not really documented well, but I assume this is so that you can return to the original point, after inserting a text of a potentially unknown length.

Related Question