aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/indent.c350
1 files changed, 310 insertions, 40 deletions
diff --git a/src/indent.c b/src/indent.c
index 9cdfb3cf046..ea0de2a10d6 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA. */
22#include <config.h> 22#include <config.h>
23#include "lisp.h" 23#include "lisp.h"
24#include "buffer.h" 24#include "buffer.h"
25#include "charset.h"
25#include "indent.h" 26#include "indent.h"
26#include "frame.h" 27#include "frame.h"
27#include "window.h" 28#include "window.h"
@@ -52,6 +53,10 @@ int last_known_column_modified;
52 53
53static int current_column_1 (); 54static int current_column_1 ();
54 55
56/* Cache of beginning of line found by the last call of
57 current_column. */
58int current_column_bol_cache;
59
55/* Get the display table to use for the current buffer. */ 60/* Get the display table to use for the current buffer. */
56 61
57struct Lisp_Char_Table * 62struct Lisp_Char_Table *
@@ -148,7 +153,10 @@ recompute_width_table (buf, disptab)
148static void 153static void
149width_run_cache_on_off () 154width_run_cache_on_off ()
150{ 155{
151 if (NILP (current_buffer->cache_long_line_scans)) 156 if (NILP (current_buffer->cache_long_line_scans)
157 /* And, for the moment, this feature doesn't work on multibyte
158 characters. */
159 || !NILP (current_buffer->enable_multibyte_characters))
152 { 160 {
153 /* It should be off. */ 161 /* It should be off. */
154 if (current_buffer->width_run_cache) 162 if (current_buffer->width_run_cache)
@@ -233,6 +241,13 @@ skip_invisible (pos, next_boundary_p, to, window)
233 proplimit = overlay_limit; 241 proplimit = overlay_limit;
234 end = Fnext_single_property_change (position, Qinvisible, 242 end = Fnext_single_property_change (position, Qinvisible,
235 buffer, proplimit); 243 buffer, proplimit);
244 /* Don't put the boundary in the middle of multibyte form if
245 there is no actual property change. */
246 if (end == pos + 100
247 && !NILP (current_buffer->enable_multibyte_characters)
248 && end < ZV)
249 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
250 end--;
236 *next_boundary_p = XFASTINT (end); 251 *next_boundary_p = XFASTINT (end);
237 } 252 }
238 /* if the `invisible' property is set, we can skip to 253 /* if the `invisible' property is set, we can skip to
@@ -287,18 +302,19 @@ current_column ()
287 && MODIFF == last_known_column_modified) 302 && MODIFF == last_known_column_modified)
288 return last_known_column; 303 return last_known_column;
289 304
290 /* If the buffer has overlays or text properties, 305 /* If the buffer has overlays, text properties, or multibyte,
291 use a more general algorithm. */ 306 use a more general algorithm. */
292 if (BUF_INTERVALS (current_buffer) 307 if (BUF_INTERVALS (current_buffer)
293 || !NILP (current_buffer->overlays_before) 308 || !NILP (current_buffer->overlays_before)
294 || !NILP (current_buffer->overlays_after)) 309 || !NILP (current_buffer->overlays_after)
310 || !NILP (current_buffer->enable_multibyte_characters))
295 return current_column_1 (PT); 311 return current_column_1 (PT);
296 312
297 /* Scan backwards from point to the previous newline, 313 /* Scan backwards from point to the previous newline,
298 counting width. Tab characters are the only complicated case. */ 314 counting width. Tab characters are the only complicated case. */
299 315
300 /* Make a pointer for decrementing through the chars before point. */ 316 /* Make a pointer for decrementing through the chars before point. */
301 ptr = &FETCH_CHAR (PT - 1) + 1; 317 ptr = POS_ADDR (PT - 1) + 1;
302 /* Make a pointer to where consecutive chars leave off, 318 /* Make a pointer to where consecutive chars leave off,
303 going backwards from point. */ 319 going backwards from point. */
304 if (PT == BEGV) 320 if (PT == BEGV)
@@ -355,6 +371,10 @@ current_column ()
355 col += post_tab; 371 col += post_tab;
356 } 372 }
357 373
374 if (ptr == BEGV_ADDR)
375 current_column_bol_cache = BEGV;
376 else
377 current_column_bol_cache = PTR_CHAR_POS ((ptr+1));
358 last_known_column = col; 378 last_known_column = col;
359 last_known_column_point = PT; 379 last_known_column_point = PT;
360 last_known_column_modified = MODIFF; 380 last_known_column_modified = MODIFF;
@@ -377,8 +397,9 @@ current_column_1 (pos)
377 397
378 /* Start the scan at the beginning of this line with column number 0. */ 398 /* Start the scan at the beginning of this line with column number 0. */
379 register int col = 0; 399 register int col = 0;
380 int scan = find_next_newline (pos, -1); 400 int scan = current_column_bol_cache = find_next_newline (pos, -1);
381 int next_boundary = scan; 401 int next_boundary = scan;
402 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
382 403
383 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; 404 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
384 405
@@ -397,7 +418,7 @@ current_column_1 (pos)
397 goto endloop; 418 goto endloop;
398 } 419 }
399 420
400 c = FETCH_CHAR (scan); 421 c = FETCH_BYTE (scan);
401 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) 422 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
402 { 423 {
403 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; 424 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
@@ -415,6 +436,42 @@ current_column_1 (pos)
415 col += tab_width; 436 col += tab_width;
416 col = col / tab_width * tab_width; 437 col = col / tab_width * tab_width;
417 } 438 }
439 else if (multibyte && BASE_LEADING_CODE_P (c))
440 {
441 scan--;
442 /* Start of multi-byte form. */
443 if (c == LEADING_CODE_COMPOSITION)
444 {
445 unsigned char *ptr = POS_ADDR (scan);
446
447 int cmpchar_id = str_cmpchar_id (ptr, next_boundary - scan);
448 if (cmpchar_id >= 0)
449 {
450 scan += cmpchar_table[cmpchar_id]->len,
451 col += cmpchar_table[cmpchar_id]->width;
452 }
453 else
454 { /* invalid composite character */
455 scan++;
456 col += 4;
457 }
458 }
459 else
460 {
461 /* Here, we check that the following bytes are valid
462 constituents of multi-byte form. */
463 int len = BYTES_BY_CHAR_HEAD (c), i;
464
465 for (i = 1, scan++; i < len; i++, scan++)
466 /* We don't need range checking for PTR because there
467 are anchors (`\0') at GAP and Z. */
468 if (CHAR_HEAD_P (POS_ADDR (scan))) break;
469 if (i < len)
470 col += 4, scan -= i - 1;
471 else
472 col += WIDTH_BY_CHAR_HEAD (c);
473 }
474 }
418 else if (ctl_arrow && (c < 040 || c == 0177)) 475 else if (ctl_arrow && (c < 040 || c == 0177))
419 col += 2; 476 col += 2;
420 else if (c < 040 || c >= 0177) 477 else if (c < 040 || c >= 0177)
@@ -584,7 +641,7 @@ position_indentation (pos)
584 641
585 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; 642 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
586 643
587 p = &FETCH_CHAR (pos); 644 p = POS_ADDR (pos);
588 /* STOP records the value of P at which we will need 645 /* STOP records the value of P at which we will need
589 to think about the gap, or about invisible text, 646 to think about the gap, or about invisible text,
590 or about the end of the buffer. */ 647 or about the end of the buffer. */
@@ -615,8 +672,8 @@ position_indentation (pos)
615 (if STOP_POS is the position of the gap) 672 (if STOP_POS is the position of the gap)
616 rather than at the data after the gap. */ 673 rather than at the data after the gap. */
617 674
618 stop = &FETCH_CHAR (stop_pos - 1) + 1; 675 stop = POS_ADDR (stop_pos - 1) + 1;
619 p = &FETCH_CHAR (pos); 676 p = POS_ADDR (pos);
620 } 677 }
621 switch (*p++) 678 switch (*p++)
622 { 679 {
@@ -639,7 +696,7 @@ int
639indented_beyond_p (pos, column) 696indented_beyond_p (pos, column)
640 int pos, column; 697 int pos, column;
641{ 698{
642 while (pos > BEGV && FETCH_CHAR (pos) == '\n') 699 while (pos > BEGV && FETCH_BYTE (pos) == '\n')
643 pos = find_next_newline_no_quit (pos - 1, -1); 700 pos = find_next_newline_no_quit (pos - 1, -1);
644 return (position_indentation (pos) >= column); 701 return (position_indentation (pos) >= column);
645} 702}
@@ -669,6 +726,7 @@ The return value is the current column.")
669 register int tab_width = XINT (current_buffer->tab_width); 726 register int tab_width = XINT (current_buffer->tab_width);
670 register int ctl_arrow = !NILP (current_buffer->ctl_arrow); 727 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
671 register struct Lisp_Char_Table *dp = buffer_display_table (); 728 register struct Lisp_Char_Table *dp = buffer_display_table ();
729 register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
672 730
673 Lisp_Object val; 731 Lisp_Object val;
674 int prev_col; 732 int prev_col;
@@ -689,7 +747,7 @@ The return value is the current column.")
689 if (col > goal) 747 if (col > goal)
690 { 748 {
691 end = pos; 749 end = pos;
692 pos = find_next_newline (pos, -1); 750 pos = current_column_bol_cache;
693 col = 0; 751 col = 0;
694 } 752 }
695 753
@@ -708,7 +766,7 @@ The return value is the current column.")
708 if (col >= goal) 766 if (col >= goal)
709 break; 767 break;
710 768
711 c = FETCH_CHAR (pos); 769 c = FETCH_BYTE (pos);
712 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) 770 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
713 { 771 {
714 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; 772 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
@@ -728,10 +786,50 @@ The return value is the current column.")
728 } 786 }
729 else if (ctl_arrow && (c < 040 || c == 0177)) 787 else if (ctl_arrow && (c < 040 || c == 0177))
730 col += 2; 788 col += 2;
731 else if (c < 040 || c >= 0177) 789 else if (c < 040 || c == 0177)
732 col += 4; 790 col += 4;
733 else 791 else if (c < 0177)
734 col++; 792 col++;
793 else if (multibyte && BASE_LEADING_CODE_P (c))
794 {
795 /* Start of multi-byte form. */
796 unsigned char *ptr;
797
798 pos--; /* rewind to the character head */
799 ptr = POS_ADDR (pos);
800 if (c == LEADING_CODE_COMPOSITION)
801 {
802 int cmpchar_id = str_cmpchar_id (ptr, end - pos);
803
804 if (cmpchar_id >= 0)
805 {
806 col += cmpchar_table[cmpchar_id]->width;
807 pos += cmpchar_table[cmpchar_id]->len;
808 }
809 else
810 { /* invalid composite character */
811 col += 4;
812 pos++;
813 }
814 }
815 else
816 {
817 /* Here, we check that the following bytes are valid
818 constituents of multi-byte form. */
819 int len = BYTES_BY_CHAR_HEAD (c), i;
820
821 for (i = 1, ptr++; i < len; i++, ptr++)
822 /* We don't need range checking for PTR because there
823 are anchors (`\0') both at GPT and Z. */
824 if (CHAR_HEAD_P (ptr)) break;
825 if (i < len)
826 col += 4, pos++;
827 else
828 col += WIDTH_BY_CHAR_HEAD (c), pos += i;
829 }
830 }
831 else
832 col += 4;
735 } 833 }
736 endloop: 834 endloop:
737 835
@@ -848,7 +946,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
848 = (INTEGERP (current_buffer->selective_display) 946 = (INTEGERP (current_buffer->selective_display)
849 ? XINT (current_buffer->selective_display) 947 ? XINT (current_buffer->selective_display)
850 : !NILP (current_buffer->selective_display) ? -1 : 0); 948 : !NILP (current_buffer->selective_display) ? -1 : 0);
851 int prev_vpos = vpos, prev_hpos = 0; 949 int prev_hpos = 0;
852 int selective_rlen 950 int selective_rlen
853 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp)) 951 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
854 ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0); 952 ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
@@ -870,6 +968,13 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
870 int next_width_run = from; 968 int next_width_run = from;
871 Lisp_Object window; 969 Lisp_Object window;
872 970
971 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
972 int wide_column = 0; /* Set to 1 when a previous character
973 is wide-colomn. */
974 int prev_pos; /* Previous buffer position. */
975 int contin_hpos; /* HPOS of last column of continued line. */
976 int prev_tab_offset; /* Previous tab offset. */
977
873 XSETBUFFER (buffer, current_buffer); 978 XSETBUFFER (buffer, current_buffer);
874 XSETWINDOW (window, win); 979 XSETWINDOW (window, win);
875 980
@@ -885,7 +990,9 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
885 990
886 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; 991 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
887 992
888 pos = from; 993 pos = prev_pos = from;
994 contin_hpos = 0;
995 prev_tab_offset = tab_offset;
889 while (1) 996 while (1)
890 { 997 {
891 while (pos == next_boundary) 998 while (pos == next_boundary)
@@ -896,10 +1003,14 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
896 through, so clear the flag after testing it. */ 1003 through, so clear the flag after testing it. */
897 if (!did_motion) 1004 if (!did_motion)
898 /* We need to skip past the overlay strings. Currently those 1005 /* We need to skip past the overlay strings. Currently those
899 strings must contain single-column printing characters; 1006 strings must not contain TAB;
900 if we want to relax that restriction, something will have 1007 if we want to relax that restriction, something will have
901 to be changed here. */ 1008 to be changed here. */
902 hpos += overlay_strings (pos, win, (char **)0); 1009 {
1010 unsigned char *ovstr;
1011 int ovlen = overlay_strings (pos, win, &ovstr);
1012 hpos += (multibyte ? strwidth (ovstr, ovlen) : ovlen);
1013 }
903 did_motion = 0; 1014 did_motion = 0;
904 1015
905 if (pos >= to) 1016 if (pos >= to)
@@ -913,9 +1024,50 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
913 } 1024 }
914 1025
915 /* Handle right margin. */ 1026 /* Handle right margin. */
916 if (hpos >= width 1027 /* Note on a wide-column character.
917 && (hpos > width 1028
918 || (pos < ZV && FETCH_CHAR (pos) != '\n'))) 1029 Characters are classified into the following three categories
1030 according to the width (columns occupied on screen).
1031
1032 (1) single-column character: ex. `a'
1033 (2) multi-column character: ex. `^A', TAB, `\033'
1034 (3) wide-column character: ex. Japanese character, Chinese character
1035 (In the following example, `W_' stands for them.)
1036
1037 Multi-column characters can be divided around the right margin,
1038 but wide-column characters cannot.
1039
1040 NOTE:
1041
1042 (*) The cursor is placed on the next character after the point.
1043
1044 ----------
1045 abcdefghi\
1046 j ^---- next after the point
1047 ^--- next char. after the point.
1048 ----------
1049 In case of sigle-column character
1050
1051 ----------
1052 abcdefgh\\
1053 033 ^---- next after the point, next char. after the point.
1054 ----------
1055 In case of multi-column character
1056
1057 ----------
1058 abcdefgh\\
1059 W_ ^---- next after the point
1060 ^---- next char. after the point.
1061 ----------
1062 In case of wide-column character
1063
1064 The problem here is continuation at a wide-column character.
1065 In this case, the line may shorter less than WIDTH.
1066 And we find the continuation AFTER it occurs.
1067
1068 */
1069
1070 if (hpos > width)
919 { 1071 {
920 if (hscroll 1072 if (hscroll
921 || (truncate_partial_width_windows 1073 || (truncate_partial_width_windows
@@ -923,31 +1075,94 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
923 || !NILP (current_buffer->truncate_lines)) 1075 || !NILP (current_buffer->truncate_lines))
924 { 1076 {
925 /* Truncating: skip to newline. */ 1077 /* Truncating: skip to newline. */
926 pos = find_before_next_newline (pos, to, 1); 1078 if (pos <= to) /* This IF is needed because we may past TO */
1079 pos = find_before_next_newline (pos, to, 1);
927 hpos = width; 1080 hpos = width;
928 /* If we just skipped next_boundary, 1081 /* If we just skipped next_boundary,
929 loop around in the main while 1082 loop around in the main while
930 and handle it. */ 1083 and handle it. */
931 if (pos >= next_boundary) 1084 if (pos >= next_boundary)
932 next_boundary = pos + 1; 1085 next_boundary = pos + 1;
1086 prev_hpos = width;
1087 prev_tab_offset = tab_offset;
933 } 1088 }
934 else 1089 else
935 { 1090 {
936 /* Continuing. */ 1091 /* Continuing. */
937 vpos += hpos / width; 1092 /* Remember the previous value. */
938 tab_offset += hpos - hpos % width; 1093 prev_tab_offset = tab_offset;
939 hpos %= width; 1094
1095 if (wide_column)
1096 {
1097 hpos -= prev_hpos;
1098 tab_offset += prev_hpos;
1099 }
1100 else
1101 {
1102 tab_offset += width;
1103 hpos -= width;
1104 }
1105 vpos++;
1106 contin_hpos = prev_hpos;
1107 prev_hpos = 0;
940 } 1108 }
941 } 1109 }
942 1110
943 /* Stop if past the target buffer position or screen position. */ 1111 /* Stop if past the target buffer position or screen position. */
944 if (pos >= to) 1112 if (pos > to)
945 break; 1113 {
946 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos)) 1114 /* Go back to the previous position. */
1115 pos = prev_pos;
1116 hpos = prev_hpos;
1117 tab_offset = prev_tab_offset;
1118
1119 /* NOTE on contin_hpos, hpos, and prev_hpos.
1120
1121 ----------
1122 abcdefgh\\
1123 W_ ^---- contin_hpos
1124 | ^----- hpos
1125 \---- prev_hpos
1126 ----------
1127 */
1128
1129 if (contin_hpos && prev_hpos == 0
1130 && contin_hpos < width && !wide_column)
1131 {
1132 /* Line breaking occurs in the middle of multi-column
1133 character. Go back to previous line. */
1134 hpos = contin_hpos;
1135 vpos = vpos - 1;
1136 }
1137 else if (c == '\n')
1138 /* If previous character is NEWLINE,
1139 set VPOS back to previous line */
1140 vpos = vpos - 1;
1141 break;
1142 }
1143
1144 if (vpos > tovpos || vpos == tovpos && hpos >= tohpos)
1145 {
1146 if (contin_hpos && prev_hpos == 0
1147 && (contin_hpos == width || wide_column))
1148 { /* Line breaks because we can't put the character at the
1149 previous line any more. It is not the multi-column
1150 character continued in middle. Go back to previous
1151 buffer position, screen position, and set tab offset
1152 to previous value. It's the beginning of the
1153 line. */
1154 pos = prev_pos;
1155 hpos = prev_hpos;
1156 tab_offset = prev_tab_offset;
1157 }
1158 break;
1159 }
1160 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
947 break; 1161 break;
948 1162
949 prev_vpos = vpos;
950 prev_hpos = hpos; 1163 prev_hpos = hpos;
1164 prev_pos = pos;
1165 wide_column = 0;
951 1166
952 /* Consult the width run cache to see if we can avoid inspecting 1167 /* Consult the width run cache to see if we can avoid inspecting
953 the text character-by-character. */ 1168 the text character-by-character. */
@@ -1000,7 +1215,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1000 /* We have to scan the text character-by-character. */ 1215 /* We have to scan the text character-by-character. */
1001 else 1216 else
1002 { 1217 {
1003 c = FETCH_CHAR (pos); 1218 c = FETCH_BYTE (pos);
1004 pos++; 1219 pos++;
1005 1220
1006 /* Perhaps add some info to the width_run_cache. */ 1221 /* Perhaps add some info to the width_run_cache. */
@@ -1073,6 +1288,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1073 hpos++; 1288 hpos++;
1074 tab_offset = 0; 1289 tab_offset = 0;
1075 } 1290 }
1291 contin_hpos = 0;
1076 } 1292 }
1077 else if (c == CR && selective < 0) 1293 else if (c == CR && selective < 0)
1078 { 1294 {
@@ -1093,6 +1309,47 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1093 hpos = width; 1309 hpos = width;
1094 } 1310 }
1095 } 1311 }
1312 else if (multibyte && BASE_LEADING_CODE_P (c))
1313 {
1314 /* Start of multi-byte form. */
1315 unsigned char *ptr;
1316
1317 pos--; /* rewind POS */
1318 ptr = POS_ADDR (pos);
1319
1320 if (c == LEADING_CODE_COMPOSITION)
1321 {
1322 int cmpchar_id = str_cmpchar_id (ptr, next_boundary - pos);
1323
1324 if (cmpchar_id >= 0)
1325 {
1326 if (cmpchar_table[cmpchar_id]->width >= 2)
1327 wide_column = 1;
1328 hpos += cmpchar_table[cmpchar_id]->width;
1329 pos += cmpchar_table[cmpchar_id]->len;
1330 }
1331 else
1332 { /* invalid composite character */
1333 hpos += 4;
1334 pos ++;
1335 }
1336 }
1337 else
1338 {
1339 /* Here, we check that the following bytes are valid
1340 constituents of multi-byte form. */
1341 int len = BYTES_BY_CHAR_HEAD (c), i;
1342
1343 for (i = 1, ptr++; i < len; i++, ptr++)
1344 /* We don't need range checking for PTR because
1345 there are anchors ('\0') both at GPT and Z. */
1346 if (CHAR_HEAD_P (ptr)) break;
1347 if (i < len)
1348 hpos += 4, pos++;
1349 else
1350 hpos += WIDTH_BY_CHAR_HEAD (c), pos += i, wide_column = 1;
1351 }
1352 }
1096 else 1353 else
1097 hpos += (ctl_arrow && c < 0200) ? 2 : 4; 1354 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1098 } 1355 }
@@ -1113,10 +1370,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1113 val_compute_motion.ovstring_chars_done = 0; 1370 val_compute_motion.ovstring_chars_done = 0;
1114 1371
1115 /* Nonzero if have just continued a line */ 1372 /* Nonzero if have just continued a line */
1116 val_compute_motion.contin 1373 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1117 = (pos != from
1118 && (val_compute_motion.vpos != prev_vpos)
1119 && c != '\n');
1120 1374
1121 return &val_compute_motion; 1375 return &val_compute_motion;
1122} 1376}
@@ -1237,17 +1491,23 @@ pos_tab_offset (w, pos)
1237 1491
1238 if (pos == BEGV) 1492 if (pos == BEGV)
1239 return MINI_WINDOW_P (w) ? -minibuf_prompt_width : 0; 1493 return MINI_WINDOW_P (w) ? -minibuf_prompt_width : 0;
1240 if (FETCH_CHAR (pos - 1) == '\n') 1494 if (FETCH_BYTE (pos - 1) == '\n')
1241 return 0; 1495 return 0;
1242 TEMP_SET_PT (pos); 1496 TEMP_SET_PT (pos);
1243 col = current_column (); 1497 col = current_column ();
1244 TEMP_SET_PT (opoint); 1498 TEMP_SET_PT (opoint);
1499 /* Modulo is no longer valid, as a line may get shorter than WIDTH
1500 columns by continuation of a wide-column character. Just return
1501 COL here. */
1502#if 0
1245 /* In the continuation of the first line in a minibuffer we must 1503 /* In the continuation of the first line in a minibuffer we must
1246 take the width of the prompt into account. */ 1504 take the width of the prompt into account. */
1247 if (MINI_WINDOW_P (w) && col >= width - minibuf_prompt_width 1505 if (MINI_WINDOW_P (w) && col >= width - minibuf_prompt_width
1248 && find_next_newline_no_quit (pos, -1) == BEGV) 1506 && find_next_newline_no_quit (pos, -1) == BEGV)
1249 return col - (col + minibuf_prompt_width) % width; 1507 return col - (col + minibuf_prompt_width) % width;
1250 return col - (col % width); 1508 return col - (col % width);
1509#endif
1510 return col;
1251} 1511}
1252 1512
1253 1513
@@ -1320,7 +1580,11 @@ vmotion (from, vtarget, w)
1320 lmargin + (XFASTINT (prevline) == BEG 1580 lmargin + (XFASTINT (prevline) == BEG
1321 ? start_hpos : 0), 1581 ? start_hpos : 0),
1322 0, 1582 0,
1323 from, 1 << (BITS_PER_INT - 2), 0, 1583 from,
1584 /* Don't care for VPOS... */
1585 1 << (BITS_PER_SHORT - 1),
1586 /* ... nor HPOS. */
1587 1 << (BITS_PER_SHORT - 1),
1324 width, hscroll, 1588 width, hscroll,
1325 /* This compensates for start_hpos 1589 /* This compensates for start_hpos
1326 so that a tab as first character 1590 so that a tab as first character
@@ -1344,6 +1608,7 @@ vmotion (from, vtarget, w)
1344 val_vmotion.contin = 0; 1608 val_vmotion.contin = 0;
1345 val_vmotion.prevhpos = 0; 1609 val_vmotion.prevhpos = 0;
1346 val_vmotion.ovstring_chars_done = 0; 1610 val_vmotion.ovstring_chars_done = 0;
1611 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1347 return &val_vmotion; 1612 return &val_vmotion;
1348 } 1613 }
1349 1614
@@ -1351,7 +1616,7 @@ vmotion (from, vtarget, w)
1351 } 1616 }
1352 /* Moving downward is simple, but must calculate from beg of line 1617 /* Moving downward is simple, but must calculate from beg of line
1353 to determine hpos of starting point */ 1618 to determine hpos of starting point */
1354 if (from > BEGV && FETCH_CHAR (from - 1) != '\n') 1619 if (from > BEGV && FETCH_BYTE (from - 1) != '\n')
1355 { 1620 {
1356 Lisp_Object propval; 1621 Lisp_Object propval;
1357 1622
@@ -1373,7 +1638,11 @@ vmotion (from, vtarget, w)
1373 lmargin + (XFASTINT (prevline) == BEG 1638 lmargin + (XFASTINT (prevline) == BEG
1374 ? start_hpos : 0), 1639 ? start_hpos : 0),
1375 0, 1640 0,
1376 from, 1 << (BITS_PER_INT - 2), 0, 1641 from,
1642 /* Don't care for VPOS... */
1643 1 << (BITS_PER_SHORT - 1),
1644 /* ... nor HPOS. */
1645 1 << (BITS_PER_SHORT - 1),
1377 width, hscroll, 1646 width, hscroll,
1378 (XFASTINT (prevline) == BEG ? -start_hpos : 0), 1647 (XFASTINT (prevline) == BEG ? -start_hpos : 0),
1379 w); 1648 w);
@@ -1383,12 +1652,13 @@ vmotion (from, vtarget, w)
1383 { 1652 {
1384 pos.hpos = lmargin + (from == BEG ? start_hpos : 0); 1653 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
1385 pos.vpos = 0; 1654 pos.vpos = 0;
1655 pos.tab_offset = 0;
1386 did_motion = 0; 1656 did_motion = 0;
1387 } 1657 }
1388 return compute_motion (from, vpos, pos.hpos, did_motion, 1658 return compute_motion (from, vpos, pos.hpos, did_motion,
1389 ZV, vtarget, - (1 << (BITS_PER_INT - 2)), 1659 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
1390 width, hscroll, 1660 width, hscroll,
1391 pos.vpos * width - (from == BEG ? start_hpos : 0), 1661 pos.tab_offset - (from == BEG ? start_hpos : 0),
1392 w); 1662 w);
1393} 1663}
1394 1664