+ /* In overwrite-mode, we substitute a character at point (C2,
+ hereafter) by C. For that, we delete C2 in advance. But,
+ just substituting C2 by C may move a remaining text in the
+ line to the right or to the left, which is not preferable.
+ So we insert more spaces or delete more characters in the
+ following cases: if C is narrower than C2, after deleting C2,
+ we fill columns with spaces, if C is wider than C2, we delete
+ C2 and several characters following C2. */
+
+ /* This is the character after point. */
+ int c2 = FETCH_CHAR (PT_BYTE);
+
+ /* Column the cursor should be placed at after this insertion.
+ The correct value should be calculated only when necessary. */
+ int target_clm = 0;
+
+ /* Overwriting in binary-mode always replaces C2 by C.
+ Overwriting in textual-mode doesn't always do that.
+ It inserts newlines in the usual way,
+ and inserts any character at end of line
+ or before a tab if it doesn't use the whole width of the tab. */
+ if (EQ (overwrite, Qoverwrite_mode_binary)
+ || (c != '\n'
+ && c2 != '\n'
+ && ! (c2 == '\t'
+ && XINT (current_buffer->tab_width) > 0
+ && XFASTINT (current_buffer->tab_width) < 20
+ && (target_clm = (current_column ()
+ + XINT (Fchar_width (make_number (c)))),
+ target_clm % XFASTINT (current_buffer->tab_width)))))
+ {
+ int pos = PT;
+ int pos_byte = PT_BYTE;
+
+ if (target_clm == 0)
+ chars_to_delete = 1;
+ else
+ {
+ /* The actual cursor position after the trial of moving
+ to column TARGET_CLM. It is greater than TARGET_CLM
+ if the TARGET_CLM is middle of multi-column
+ character. In that case, the new point is set after
+ that character. */
+ int actual_clm
+ = XFASTINT (Fmove_to_column (make_number (target_clm), Qnil));
+
+ chars_to_delete = PT - pos;
+
+ if (actual_clm > target_clm)
+ {
+ /* We will delete too many columns. Let's fill columns
+ by spaces so that the remaining text won't move. */
+ spaces_to_insert = actual_clm - target_clm;
+ }
+ }
+ SET_PT_BOTH (pos, pos_byte);
+ hairy = 2;
+ }
+ hairy = 2;