[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[5926] more support of multi-byte characters in echo area
From: |
Gavin D. Smith |
Subject: |
[5926] more support of multi-byte characters in echo area |
Date: |
Thu, 13 Nov 2014 17:47:24 +0000 |
Revision: 5926
http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5926
Author: gavin
Date: 2014-11-13 17:47:21 +0000 (Thu, 13 Nov 2014)
Log Message:
-----------
more support of multi-byte characters in echo area
Modified Paths:
--------------
trunk/ChangeLog
trunk/info/echo-area.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2014-11-13 14:28:13 UTC (rev 5925)
+++ trunk/ChangeLog 2014-11-13 17:47:21 UTC (rev 5926)
@@ -1,3 +1,13 @@
+2014-11-13 Gavin Smith <address@hidden>
+
+ * info/echo-area.c (ea_delete, ea_transpose_chars): Handle
+ multi-byte characters.
+ (ea_swap_chars, ea_remove_text): New static functions.
+
+ (read_and_dispatch_in_echo_area)
+ (echo_area_prep_read): Line invalidating echo area line map
+ moved between functions.
+
2014-11-12 Gavin Smith <address@hidden>
* info/t/window-split-dir.sh: New test.
Modified: trunk/info/echo-area.c
===================================================================
--- trunk/info/echo-area.c 2014-11-13 14:28:13 UTC (rev 5925)
+++ trunk/info/echo-area.c 2014-11-13 17:47:21 UTC (rev 5926)
@@ -58,6 +58,7 @@
static int echo_area_stack_contains_completions_p (void);
static void ea_kill_text (int from, int to);
+static void ea_remove_text (int from, int to);
/* Non-zero means we force the user to complete. */
static int echo_area_must_complete_p = 0;
@@ -175,12 +176,6 @@
if (!info_any_buffered_input_p ())
display_update_display ();
- /* Mark the line map as invalid. This causes window_compute_line_map to
- recalculate it when it is called via display_cursor_at_point below.
- Otherwise adding or removing multi-column characters (like tabs) lead
- to incorrect cursor positioning. */
- the_echo_area->line_map.used = 0;
-
display_cursor_at_point (active_window);
/* Do the selected command. */
@@ -283,6 +278,13 @@
the_echo_area->point = input_line_point;
input_line[input_line_end] = '\n';
+
+ /* Mark the line map as invalid. This causes window_compute_line_map to
+ recalculate it when it is called via display_cursor_at_point below.
+ Otherwise adding or removing multi-column characters (like tabs) lead
+ to incorrect cursor positioning. */
+ the_echo_area->line_map.used = 0;
+
display_update_one_window (the_echo_area);
display_cursor_at_point (active_window);
}
@@ -434,31 +436,21 @@
DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor"))
{
- register int i;
-
if (count < 0)
ea_rubout (window, -count);
else
{
+ int orig_point;
if (input_line_point == input_line_end)
return;
+ orig_point = input_line_point;
+ ea_forward (window, count);
if (ea_explicit_arg || count > 1)
- {
- int orig_point;
-
- orig_point = input_line_point;
- ea_forward (window, count);
- ea_kill_text (orig_point, input_line_point);
- input_line_point = orig_point;
- }
+ ea_kill_text (orig_point, input_line_point);
else
- {
- for (i = input_line_point; i < input_line_end; i++)
- input_line[i] = input_line[i + 1];
-
- input_line_end--;
- }
+ ea_remove_text (orig_point, input_line_point);
+ input_line_point = orig_point;
}
}
@@ -540,36 +532,99 @@
ea_insert (window, count, '\t');
}
+/* Swap characters in INPUT_LINE. The first starts at C1 and ends at C1E, the
+ second starts at C2 and ends at C2E, with C1 < C1E <= C2 < C2E. */
+static void
+ea_swap_chars (int c1, int c1e, int c2, int c2e)
+{
+ int len1, len2;
+ char *tmp;
+
+ len1 = c1e - c1;
+ len2 = c2e - c2;
+
+ if (len1 >= len2)
+ {
+ /* Save first character. */
+ tmp = xmalloc (len1);
+ memcpy (tmp, input_line + c1, len1);
+
+ /* Move the second character to where the first was. */
+ memcpy (input_line + c1, input_line + c2, len2);
+
+ /* Shift the part in between the characters backwards. */
+ memmove (input_line + c1 + len2, input_line + c1e, c2 - c1e);
+
+ /* Restore the first character at the end. */
+ memcpy (input_line + c2 - (len1 - len2), tmp, len1);
+ free (tmp);
+ }
+ else /* len2 > len1 */
+ {
+ /* Save second character. */
+ tmp = xmalloc (len2);
+ memcpy (tmp, input_line + c2, len2);
+
+ /* Move first character to end of second character. */
+ memcpy (input_line + c2e - len1, input_line + c1, len1);
+
+ /* Shift the part in between the characters forwards. */
+ memmove (input_line + c1e + (len2 - len1), input_line + c1e, c2 - c1e);
+
+ /* Place the second character at the beginning. */
+ memcpy (input_line + c1, tmp, len2);
+ free (tmp);
+ }
+}
+
/* Transpose the characters at point. If point is at the end of the line,
then transpose the characters before point. */
DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point"))
{
- /* Handle conditions that would make it impossible to transpose
- characters. */
- if (!count || !input_line_point || (input_line_end - input_line_beg) < 2)
- return;
-
while (count)
{
- int t;
- if (input_line_point == input_line_end)
+ if (input_line_point == input_line_end || count < 0)
{
- t = input_line[input_line_point - 1];
+ /* Swap two characters before point. */
+ int c1, c2, c2e;
+ c2e = input_line_point;
- input_line[input_line_point - 1] = input_line[input_line_point - 2];
- input_line[input_line_point - 2] = t;
+ ea_backward (window, 1);
+ c2 = input_line_point;
+
+ ea_backward (window, 1);
+ c1 = input_line_point;
+
+ if (c1 != c2) /* There are two characters in this line. */
+ ea_swap_chars (c1, c2, c2, c2e);
+
+ if (count > 0)
+ /* Restore point. */
+ input_line_point = c2e;
+ else
+ input_line_point = c1 + c2e - c2;
}
else
{
- t = input_line[input_line_point];
+ int c1, c2, c2e;
- input_line[input_line_point] = input_line[input_line_point - 1];
- input_line[input_line_point - 1] = t;
+ c2 = input_line_point;
- if (count < 0 && input_line_point != input_line_beg)
- input_line_point--;
- else
- input_line_point++;
+ ea_forward (window, 1);
+ c2e = input_line_point;
+ if (c2e == c2)
+ return; /* Shouldn't happen. */
+
+ input_line_point = c2;
+ ea_backward (window, 1);
+ c1 = input_line_point;
+ if (c1 == c2e)
+ return; /* Can't go earlier in line. */
+
+ ea_swap_chars (c1, c2, c2, c2e);
+
+ /* Set point is after swapped pair. */
+ input_line_point = c2e;
}
if (count < 0)
@@ -707,6 +762,20 @@
window_line_map_init (window);
}
+/* Remove text from offsets FROM to TO. Unlike 'ea_kill_text' nothing is
+ saved in the kill ring. */
+static void
+ea_remove_text (int from, int to)
+{
+ int distance, i, counter;
+ counter = input_line_end - to;
+ distance = to - from;
+
+ for (i = from; counter; i++, counter--)
+ input_line[i] = input_line[i + distance];
+ input_line_end -= distance;
+}
+
/* The way to kill something. This appends or prepends to the last
kill, if the last command was a kill command. If FROM is less
than TO, then the killed text is appended to the most recent kill,
@@ -715,7 +784,7 @@
static void
ea_kill_text (int from, int to)
{
- register int i, counter, distance;
+ register int distance;
int killing_backwards, slot;
char *killed_text;
@@ -736,13 +805,8 @@
killed_text[distance] = '\0';
/* Actually delete the text from the line. */
- counter = input_line_end - to;
+ ea_remove_text (from, to);
- for (i = from; counter; i++, counter--)
- input_line[i] = input_line[i + distance];
-
- input_line_end -= distance;
-
/* If the last command was a kill, append or prepend the killed text to
the last command's killed text. */
if (echo_area_last_command_was_kill)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [5926] more support of multi-byte characters in echo area,
Gavin D. Smith <=