Delete a single char instead of the whole Grapheme Cluster in Emacs

1. Introduction

In Emacs, while writing text in devanāgarī, I often need to delete some character from a pre-composed cluster. This works well, when the character I need to delete is at the end of the cluster, cause <backspace> which is bound by default to delete-backward-char does exactly that: deletes only a single char. BUT when the char is at the start of the cluster say in ङ्क्ष्णुcomposed of +++++++ (I have chosen a ridiculously long conjunct to make a point) I will either have to:

  1. Press <backspace> 8 times and also lose the characters which I do not need to be deleted. or
  2. Move the cursor to the start of the cluster, press <delete> and be done.

2. delete-forward-char

Except <delete> does not do that! It will instead delete the whole cluster.

Poof, just like that

Looks like <delete> is bound to delete-forward-char whose documentation states that:

(delete-forward-char N &optional KILLFLAG)

Inferred type: (function (t &optional t) t)

Delete the following N characters (previous if N is negative).
If Transient Mark mode is enabled, the mark is active, and N is 1,
delete the text in the region and deactivate the mark instead.
To disable this, set variable delete-active-region to nil.

If N is positive, characters composed into a single grapheme cluster
count as a single character and are deleted together.  Thus,
"C-u 2 <deletechar>" when two grapheme clusters follow point will
delete the characters composed into both of the grapheme clusters.

Optional second arg KILLFLAG non-nil means to kill (save in kill
ring) instead of delete.  If called interactively, a numeric
prefix argument specifies N, and KILLFLAG is also set if a prefix
argument is used.

When killing, the killed text is filtered by
filter-buffer-substring before it is saved in the kill ring, so
the actual saved text might be different from what was killed.

  This function is for interactive use only;
  in Lisp code use delete-char instead.
  Probably introduced at or before Emacs version 24.1.

That means delete-forward-char is designed to delete a grapheme cluster, but we do not want that in our case, so what should we do (╹ -╹)?

3. delete-char to the rescue

The good ol’ delete-char does not perform any fancy checks to detect whether the text at point is a composition or not. It only has one purpose and that is to delete a char. The function is bound to C-d and with that we can finally get what we wanted.

Nice…