aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1998-01-02 21:43:42 +0000
committerRichard M. Stallman1998-01-02 21:43:42 +0000
commitfe0066f50fdafe0d93b523ee34420324f4bead0a (patch)
treeec0db12fe518e1f9428223617dc370528abc3f86 /src
parent4356f22179175917b56f443b8b2c9e084f97c1e5 (diff)
downloademacs-fe0066f50fdafe0d93b523ee34420324f4bead0a.tar.gz
emacs-fe0066f50fdafe0d93b523ee34420324f4bead0a.zip
(current_column_1, Fmove_to_column):
Update call to CHAR_HEAD_P. (indented_beyond_p): Take POS in bytes and chars. Callers changed. (pos_tab_indent): Function moved to xdisp.c. (Fcurrent_indentation): Use scan_newline and SET_PT_BOTH. (indented_beyond_p, current_column_1): Likewise. (vmotion, compute_motion): Set up bytepos value to return it. (current_column): Handle bytepos and charpos. (position_indentation): Take bytepos as arg, and scan with it. Calls changed. (Fmove_to_column): Scan with bytepos and charpos. (pos_tab_offset): Use bytepos to do FETCH_BYTE. (skip_invisible): Don't worry about position in middle of character.
Diffstat (limited to 'src')
-rw-r--r--src/indent.c269
1 files changed, 161 insertions, 108 deletions
diff --git a/src/indent.c b/src/indent.c
index b4592a2dddf..cf8e361a00c 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -53,6 +53,7 @@ int last_known_column_point;
53int last_known_column_modified; 53int last_known_column_modified;
54 54
55static int current_column_1 (); 55static int current_column_1 ();
56static int position_indentation ();
56 57
57/* Cache of beginning of line found by the last call of 58/* Cache of beginning of line found by the last call of
58 current_column. */ 59 current_column. */
@@ -243,6 +244,7 @@ skip_invisible (pos, next_boundary_p, to, window)
243 proplimit = overlay_limit; 244 proplimit = overlay_limit;
244 end = XFASTINT (Fnext_single_property_change (position, Qinvisible, 245 end = XFASTINT (Fnext_single_property_change (position, Qinvisible,
245 buffer, proplimit)); 246 buffer, proplimit));
247#if 0
246 /* Don't put the boundary in the middle of multibyte form if 248 /* Don't put the boundary in the middle of multibyte form if
247 there is no actual property change. */ 249 there is no actual property change. */
248 if (end == pos + 100 250 if (end == pos + 100
@@ -250,6 +252,7 @@ skip_invisible (pos, next_boundary_p, to, window)
250 && end < ZV) 252 && end < ZV)
251 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end))) 253 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
252 end--; 254 end--;
255#endif
253 *next_boundary_p = end; 256 *next_boundary_p = end;
254 } 257 }
255 /* if the `invisible' property is set, we can skip to 258 /* if the `invisible' property is set, we can skip to
@@ -317,7 +320,7 @@ current_column ()
317 counting width. Tab characters are the only complicated case. */ 320 counting width. Tab characters are the only complicated case. */
318 321
319 /* Make a pointer for decrementing through the chars before point. */ 322 /* Make a pointer for decrementing through the chars before point. */
320 ptr = POS_ADDR (PT - 1) + 1; 323 ptr = BYTE_POS_ADDR (PT_BYTE - 1) + 1;
321 /* Make a pointer to where consecutive chars leave off, 324 /* Make a pointer to where consecutive chars leave off,
322 going backwards from point. */ 325 going backwards from point. */
323 if (PT == BEGV) 326 if (PT == BEGV)
@@ -379,7 +382,8 @@ current_column ()
379 if (ptr == BEGV_ADDR) 382 if (ptr == BEGV_ADDR)
380 current_column_bol_cache = BEGV; 383 current_column_bol_cache = BEGV;
381 else 384 else
382 current_column_bol_cache = PTR_CHAR_POS (ptr); 385 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
386
383 last_known_column = col; 387 last_known_column = col;
384 last_known_column_point = PT; 388 last_known_column_point = PT;
385 last_known_column_modified = MODIFF; 389 last_known_column_modified = MODIFF;
@@ -399,12 +403,20 @@ current_column_1 (pos)
399 register int tab_width = XINT (current_buffer->tab_width); 403 register int tab_width = XINT (current_buffer->tab_width);
400 register int ctl_arrow = !NILP (current_buffer->ctl_arrow); 404 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
401 register struct Lisp_Char_Table *dp = buffer_display_table (); 405 register struct Lisp_Char_Table *dp = buffer_display_table ();
406 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
402 407
403 /* Start the scan at the beginning of this line with column number 0. */ 408 /* Start the scan at the beginning of this line with column number 0. */
404 register int col = 0; 409 register int col = 0;
405 int scan = current_column_bol_cache = find_next_newline (pos, -1); 410 int scan, scan_byte;
406 int next_boundary = scan; 411 int next_boundary, next_boundary_byte;
407 int multibyte = !NILP (current_buffer->enable_multibyte_characters); 412 int opoint = PT, opoint_byte = PT_BYTE;
413
414 scan_newline (pos, CHAR_TO_BYTE (pos), BEGV, BEGV_BYTE, -1, 1);
415 current_column_bol_cache = PT;
416 scan = PT, scan_byte = PT_BYTE;
417 SET_PT_BOTH (opoint, opoint_byte);
418 next_boundary = scan;
419 next_boundary_byte = scan_byte;
408 420
409 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; 421 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
410 422
@@ -416,11 +428,15 @@ current_column_1 (pos)
416 /* Occasionally we may need to skip invisible text. */ 428 /* Occasionally we may need to skip invisible text. */
417 while (scan == next_boundary) 429 while (scan == next_boundary)
418 { 430 {
431 int old_scan = scan;
419 /* This updates NEXT_BOUNDARY to the next place 432 /* This updates NEXT_BOUNDARY to the next place
420 where we might need to skip more invisible text. */ 433 where we might need to skip more invisible text. */
421 scan = skip_invisible (scan, &next_boundary, pos, Qnil); 434 scan = skip_invisible (scan, &next_boundary, pos, Qnil);
422 if (scan >= pos) 435 if (scan >= pos)
423 goto endloop; 436 goto endloop;
437 if (scan != old_scan)
438 scan_byte = CHAR_TO_BYTE (scan);
439 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
424 } 440 }
425 441
426 c = FETCH_BYTE (scan); 442 c = FETCH_BYTE (scan);
@@ -428,6 +444,7 @@ current_column_1 (pos)
428 { 444 {
429 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; 445 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
430 scan++; 446 scan++;
447 scan_byte++;
431 continue; 448 continue;
432 } 449 }
433 if (c == '\n') 450 if (c == '\n')
@@ -435,6 +452,7 @@ current_column_1 (pos)
435 if (c == '\r' && EQ (current_buffer->selective_display, Qt)) 452 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
436 break; 453 break;
437 scan++; 454 scan++;
455 scan_byte++;
438 if (c == '\t') 456 if (c == '\t')
439 { 457 {
440 int prev_col = col; 458 int prev_col = col;
@@ -443,21 +461,22 @@ current_column_1 (pos)
443 } 461 }
444 else if (multibyte && BASE_LEADING_CODE_P (c)) 462 else if (multibyte && BASE_LEADING_CODE_P (c))
445 { 463 {
446 scan--; 464 scan_byte--;
447 /* Start of multi-byte form. */ 465 /* Start of multi-byte form. */
448 if (c == LEADING_CODE_COMPOSITION) 466 if (c == LEADING_CODE_COMPOSITION)
449 { 467 {
450 unsigned char *ptr = POS_ADDR (scan); 468 unsigned char *ptr = BYTE_POS_ADDR (scan_byte);
451 469
452 int cmpchar_id = str_cmpchar_id (ptr, next_boundary - scan); 470 int cmpchar_id
471 = str_cmpchar_id (ptr, next_boundary_byte - scan_byte);
453 if (cmpchar_id >= 0) 472 if (cmpchar_id >= 0)
454 { 473 {
455 scan += cmpchar_table[cmpchar_id]->len, 474 scan_byte += cmpchar_table[cmpchar_id]->len;
456 col += cmpchar_table[cmpchar_id]->width; 475 col += cmpchar_table[cmpchar_id]->width;
457 } 476 }
458 else 477 else
459 { /* invalid composite character */ 478 { /* invalid composite character */
460 scan++; 479 scan_byte++;
461 col += 4; 480 col += 4;
462 } 481 }
463 } 482 }
@@ -467,12 +486,14 @@ current_column_1 (pos)
467 constituents of multi-byte form. */ 486 constituents of multi-byte form. */
468 int len = BYTES_BY_CHAR_HEAD (c), i; 487 int len = BYTES_BY_CHAR_HEAD (c), i;
469 488
470 for (i = 1, scan++; i < len; i++, scan++) 489 for (i = 1, scan_byte++; i < len; i++, scan_byte++)
471 /* We don't need range checking for PTR because there 490 /* We don't need range checking for PTR because there
472 are anchors (`\0') at GAP and Z. */ 491 are anchors (`\0') at GAP and Z. */
473 if (CHAR_HEAD_P (POS_ADDR (scan))) break; 492 if (CHAR_HEAD_P (FETCH_BYTE (scan_byte)))
493 break;
494
474 if (i < len) 495 if (i < len)
475 col += 4, scan -= i - 1; 496 col += 4, scan_byte -= i - 1;
476 else 497 else
477 col += WIDTH_BY_CHAR_HEAD (c); 498 col += WIDTH_BY_CHAR_HEAD (c);
478 } 499 }
@@ -628,25 +649,30 @@ following any initial whitespace.")
628 () 649 ()
629{ 650{
630 Lisp_Object val; 651 Lisp_Object val;
652 int opoint = PT, opoint_byte = PT_BYTE;
653
654 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
631 655
632 XSETFASTINT (val, position_indentation (find_next_newline (PT, -1))); 656 XSETFASTINT (val, position_indentation (PT_BYTE));
657 SET_PT_BOTH (opoint, opoint_byte);
633 return val; 658 return val;
634} 659}
635 660
636position_indentation (pos) 661static int
637 register int pos; 662position_indentation (pos_byte)
663 register int pos_byte;
638{ 664{
639 register int column = 0; 665 register int column = 0;
640 register int tab_width = XINT (current_buffer->tab_width); 666 register int tab_width = XINT (current_buffer->tab_width);
641 register unsigned char *p; 667 register unsigned char *p;
642 register unsigned char *stop; 668 register unsigned char *stop;
643 unsigned char *start; 669 unsigned char *start;
644 int next_boundary = pos; 670 int next_boundary_byte = pos_byte;
645 int ceiling = pos; 671 int ceiling = next_boundary_byte;
646 672
647 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; 673 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
648 674
649 p = POS_ADDR (pos); 675 p = BYTE_POS_ADDR (pos_byte);
650 /* STOP records the value of P at which we will need 676 /* STOP records the value of P at which we will need
651 to think about the gap, or about invisible text, 677 to think about the gap, or about invisible text,
652 or about the end of the buffer. */ 678 or about the end of the buffer. */
@@ -657,28 +683,34 @@ position_indentation (pos)
657 { 683 {
658 while (p == stop) 684 while (p == stop)
659 { 685 {
660 int stop_pos; 686 int stop_pos_byte;
661 687
662 /* If we have updated P, set POS to match. 688 /* If we have updated P, set POS_BYTE to match.
663 The first time we enter the loop, POS is already right. */ 689 The first time we enter the loop, POS_BYTE is already right. */
664 if (p != start) 690 if (p != start)
665 pos = PTR_CHAR_POS (p); 691 pos_byte = PTR_BYTE_POS (p);
666 /* Consider the various reasons STOP might have been set here. */ 692 /* Consider the various reasons STOP might have been set here. */
667 if (pos == ZV) 693 if (pos_byte == ZV_BYTE)
668 return column; 694 return column;
669 if (pos == next_boundary) 695 if (pos_byte == next_boundary_byte)
670 pos = skip_invisible (pos, &next_boundary, ZV, Qnil); 696 {
671 if (pos >= ceiling) 697 int next_boundary;
672 ceiling = BUFFER_CEILING_OF (pos) + 1; 698 int pos = BYTE_TO_CHAR (pos_byte);
699 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
700 pos_byte = CHAR_TO_BYTE (pos);
701 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
702 }
703 if (pos_byte >= ceiling)
704 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
673 /* Compute the next place we need to stop and think, 705 /* Compute the next place we need to stop and think,
674 and set STOP accordingly. */ 706 and set STOP accordingly. */
675 stop_pos = min (ceiling, next_boundary); 707 stop_pos_byte = min (ceiling, next_boundary_byte);
676 /* The -1 and +1 arrange to point at the first byte of gap 708 /* The -1 and +1 arrange to point at the first byte of gap
677 (if STOP_POS is the position of the gap) 709 (if STOP_POS_BYTE is the position of the gap)
678 rather than at the data after the gap. */ 710 rather than at the data after the gap. */
679 711
680 stop = POS_ADDR (stop_pos - 1) + 1; 712 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
681 p = POS_ADDR (pos); 713 p = BYTE_POS_ADDR (pos_byte);
682 } 714 }
683 switch (*p++) 715 switch (*p++)
684 { 716 {
@@ -696,13 +728,14 @@ position_indentation (pos)
696 || NILP (current_buffer->enable_multibyte_characters)) 728 || NILP (current_buffer->enable_multibyte_characters))
697 return column; 729 return column;
698 { 730 {
699 int pos = PTR_CHAR_POS (p - 1); 731 int c;
700 int c = FETCH_MULTIBYTE_CHAR (pos); 732 pos_byte = PTR_BYTE_POS (p - 1);
733 c = FETCH_MULTIBYTE_CHAR (pos_byte);
701 if (CHAR_HAS_CATEGORY (c, ' ')) 734 if (CHAR_HAS_CATEGORY (c, ' '))
702 { 735 {
703 column++; 736 column++;
704 INC_POS (pos); 737 INC_POS (pos_byte);
705 p = POS_ADDR (pos); 738 p = BYTE_POS_ADDR (pos_byte);
706 } 739 }
707 else 740 else
708 return column; 741 return column;
@@ -714,13 +747,21 @@ position_indentation (pos)
714/* Test whether the line beginning at POS is indented beyond COLUMN. 747/* Test whether the line beginning at POS is indented beyond COLUMN.
715 Blank lines are treated as if they had the same indentation as the 748 Blank lines are treated as if they had the same indentation as the
716 preceding line. */ 749 preceding line. */
750
717int 751int
718indented_beyond_p (pos, column) 752indented_beyond_p (pos, pos_byte, column)
719 int pos, column; 753 int pos, pos_byte, column;
720{ 754{
721 while (pos > BEGV && FETCH_BYTE (pos) == '\n') 755 Lisp_Object val;
722 pos = find_next_newline_no_quit (pos - 1, -1); 756 int opoint = PT, opoint_byte = PT_BYTE;
723 return (position_indentation (pos) >= column); 757
758 SET_PT_BOTH (pos, pos_byte);
759 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
760 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
761
762 XSETFASTINT (val, position_indentation (PT_BYTE));
763 SET_PT_BOTH (opoint, opoint_byte);
764 return val;
724} 765}
725 766
726DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p", 767DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
@@ -753,16 +794,20 @@ The return value is the current column.")
753 Lisp_Object val; 794 Lisp_Object val;
754 int prev_col; 795 int prev_col;
755 int c; 796 int c;
756
757 int next_boundary; 797 int next_boundary;
758 798
799 int pos_byte, end_byte, next_boundary_byte;
800
759 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; 801 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
760 CHECK_NATNUM (column, 0); 802 CHECK_NATNUM (column, 0);
761 goal = XINT (column); 803 goal = XINT (column);
762 804
763 pos = PT; 805 pos = PT;
806 pos_byte = PT_BYTE;
764 end = ZV; 807 end = ZV;
808 end_byte = ZV_BYTE;
765 next_boundary = pos; 809 next_boundary = pos;
810 next_boundary_byte = PT_BYTE;
766 811
767 /* If we're starting past the desired column, 812 /* If we're starting past the desired column,
768 back up to beginning of line and scan from there. */ 813 back up to beginning of line and scan from there. */
@@ -770,6 +815,7 @@ The return value is the current column.")
770 { 815 {
771 end = pos; 816 end = pos;
772 pos = current_column_bol_cache; 817 pos = current_column_bol_cache;
818 pos_byte = CHAR_TO_BYTE (pos);
773 col = 0; 819 col = 0;
774 } 820 }
775 821
@@ -777,7 +823,11 @@ The return value is the current column.")
777 { 823 {
778 while (pos == next_boundary) 824 while (pos == next_boundary)
779 { 825 {
826 int prev = pos;
780 pos = skip_invisible (pos, &next_boundary, end, Qnil); 827 pos = skip_invisible (pos, &next_boundary, end, Qnil);
828 if (pos != prev)
829 pos_byte = CHAR_TO_BYTE (pos);
830 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
781 if (pos >= end) 831 if (pos >= end)
782 goto endloop; 832 goto endloop;
783 } 833 }
@@ -788,10 +838,11 @@ The return value is the current column.")
788 if (col >= goal) 838 if (col >= goal)
789 break; 839 break;
790 840
791 c = FETCH_BYTE (pos); 841 c = FETCH_BYTE (pos_byte);
792 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) 842 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
793 { 843 {
794 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; 844 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
845 pos_byte++;
795 pos++; 846 pos++;
796 continue; 847 continue;
797 } 848 }
@@ -800,6 +851,7 @@ The return value is the current column.")
800 if (c == '\r' && EQ (current_buffer->selective_display, Qt)) 851 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
801 break; 852 break;
802 pos++; 853 pos++;
854 pos_byte++;
803 if (c == '\t') 855 if (c == '\t')
804 { 856 {
805 prev_col = col; 857 prev_col = col;
@@ -817,21 +869,21 @@ The return value is the current column.")
817 /* Start of multi-byte form. */ 869 /* Start of multi-byte form. */
818 unsigned char *ptr; 870 unsigned char *ptr;
819 871
820 pos--; /* rewind to the character head */ 872 pos_byte--; /* rewind to the character head */
821 ptr = POS_ADDR (pos); 873 ptr = BYTE_POS_ADDR (pos_byte);
822 if (c == LEADING_CODE_COMPOSITION) 874 if (c == LEADING_CODE_COMPOSITION)
823 { 875 {
824 int cmpchar_id = str_cmpchar_id (ptr, end - pos); 876 int cmpchar_id = str_cmpchar_id (ptr, end_byte - pos_byte);
825 877
826 if (cmpchar_id >= 0) 878 if (cmpchar_id >= 0)
827 { 879 {
828 col += cmpchar_table[cmpchar_id]->width; 880 col += cmpchar_table[cmpchar_id]->width;
829 pos += cmpchar_table[cmpchar_id]->len; 881 pos_byte += cmpchar_table[cmpchar_id]->len;
830 } 882 }
831 else 883 else
832 { /* invalid composite character */ 884 { /* invalid composite character */
833 col += 4; 885 col += 4;
834 pos++; 886 pos_byte++;
835 } 887 }
836 } 888 }
837 else 889 else
@@ -843,11 +895,13 @@ The return value is the current column.")
843 for (i = 1, ptr++; i < len; i++, ptr++) 895 for (i = 1, ptr++; i < len; i++, ptr++)
844 /* We don't need range checking for PTR because there 896 /* We don't need range checking for PTR because there
845 are anchors (`\0') both at GPT and Z. */ 897 are anchors (`\0') both at GPT and Z. */
846 if (CHAR_HEAD_P (ptr)) break; 898 if (CHAR_HEAD_P (*ptr))
899 break;
900
847 if (i < len) 901 if (i < len)
848 col += 4, pos++; 902 col += 4, pos_byte++;
849 else 903 else
850 col += WIDTH_BY_CHAR_HEAD (c), pos += i; 904 col += WIDTH_BY_CHAR_HEAD (c), pos_byte += i;
851 } 905 }
852 } 906 }
853 else 907 else
@@ -855,19 +909,20 @@ The return value is the current column.")
855 } 909 }
856 endloop: 910 endloop:
857 911
858 SET_PT (pos); 912 SET_PT_BOTH (pos, pos_byte);
859 913
860 /* If a tab char made us overshoot, change it to spaces 914 /* If a tab char made us overshoot, change it to spaces
861 and scan through it again. */ 915 and scan through it again. */
862 if (!NILP (force) && col > goal && c == '\t' && prev_col < goal) 916 if (!NILP (force) && col > goal && c == '\t' && prev_col < goal)
863 { 917 {
864 int old_point; 918 int old_point, old_point_byte;
865 919
866 del_range (PT - 1, PT); 920 del_range (PT - 1, PT);
867 Findent_to (make_number (goal), Qnil); 921 Findent_to (make_number (goal), Qnil);
868 old_point = PT; 922 old_point = PT;
923 old_point_byte = PT_BYTE;
869 Findent_to (make_number (col), Qnil); 924 Findent_to (make_number (col), Qnil);
870 SET_PT (old_point); 925 SET_PT_BOTH (old_point, old_point_byte);
871 /* Set the last_known... vars consistently. */ 926 /* Set the last_known... vars consistently. */
872 col = goal; 927 col = goal;
873 } 928 }
@@ -960,6 +1015,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
960 register int vpos = fromvpos; 1015 register int vpos = fromvpos;
961 1016
962 register int pos; 1017 register int pos;
1018 int pos_byte;
963 register int c; 1019 register int c;
964 register int tab_width = XFASTINT (current_buffer->tab_width); 1020 register int tab_width = XFASTINT (current_buffer->tab_width);
965 register int ctl_arrow = !NILP (current_buffer->ctl_arrow); 1021 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
@@ -994,6 +1050,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
994 int wide_column = 0; /* Set to 1 when a previous character 1050 int wide_column = 0; /* Set to 1 when a previous character
995 is wide-colomn. */ 1051 is wide-colomn. */
996 int prev_pos; /* Previous buffer position. */ 1052 int prev_pos; /* Previous buffer position. */
1053 int prev_pos_byte; /* Previous buffer position. */
997 int contin_hpos; /* HPOS of last column of continued line. */ 1054 int contin_hpos; /* HPOS of last column of continued line. */
998 int prev_tab_offset; /* Previous tab offset. */ 1055 int prev_tab_offset; /* Previous tab offset. */
999 1056
@@ -1013,12 +1070,14 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1013 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; 1070 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
1014 1071
1015 pos = prev_pos = from; 1072 pos = prev_pos = from;
1073 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1016 contin_hpos = 0; 1074 contin_hpos = 0;
1017 prev_tab_offset = tab_offset; 1075 prev_tab_offset = tab_offset;
1018 while (1) 1076 while (1)
1019 { 1077 {
1020 while (pos == next_boundary) 1078 while (pos == next_boundary)
1021 { 1079 {
1080 int pos_here = pos;
1022 int newpos; 1081 int newpos;
1023 1082
1024 /* If the caller says that the screen position came from an earlier 1083 /* If the caller says that the screen position came from an earlier
@@ -1049,7 +1108,11 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1049 if (newpos >= to) 1108 if (newpos >= to)
1050 goto after_loop; 1109 goto after_loop;
1051 1110
1052 pos = newpos; 1111 if (newpos != pos_here)
1112 {
1113 pos = newpos;
1114 pos_byte = CHAR_TO_BYTE (pos);
1115 }
1053 } 1116 }
1054 1117
1055 /* Handle right margin. */ 1118 /* Handle right margin. */
@@ -1105,7 +1168,10 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1105 { 1168 {
1106 /* Truncating: skip to newline. */ 1169 /* Truncating: skip to newline. */
1107 if (pos <= to) /* This IF is needed because we may past TO */ 1170 if (pos <= to) /* This IF is needed because we may past TO */
1108 pos = find_before_next_newline (pos, to, 1); 1171 {
1172 pos = find_before_next_newline (pos, to, 1);
1173 pos_byte = CHAR_TO_BYTE (pos);
1174 }
1109 hpos = width; 1175 hpos = width;
1110 /* If we just skipped next_boundary, 1176 /* If we just skipped next_boundary,
1111 loop around in the main while 1177 loop around in the main while
@@ -1142,6 +1208,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1142 { 1208 {
1143 /* Go back to the previous position. */ 1209 /* Go back to the previous position. */
1144 pos = prev_pos; 1210 pos = prev_pos;
1211 pos_byte = prev_pos_byte;
1145 hpos = prev_hpos; 1212 hpos = prev_hpos;
1146 tab_offset = prev_tab_offset; 1213 tab_offset = prev_tab_offset;
1147 1214
@@ -1181,6 +1248,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1181 to previous value. It's the beginning of the 1248 to previous value. It's the beginning of the
1182 line. */ 1249 line. */
1183 pos = prev_pos; 1250 pos = prev_pos;
1251 pos_byte = prev_pos_byte;
1184 hpos = prev_hpos; 1252 hpos = prev_hpos;
1185 tab_offset = prev_tab_offset; 1253 tab_offset = prev_tab_offset;
1186 } 1254 }
@@ -1191,6 +1259,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1191 1259
1192 prev_hpos = hpos; 1260 prev_hpos = hpos;
1193 prev_pos = pos; 1261 prev_pos = pos;
1262 prev_pos_byte = pos_byte;
1194 wide_column = 0; 1263 wide_column = 0;
1195 1264
1196 /* Consult the width run cache to see if we can avoid inspecting 1265 /* Consult the width run cache to see if we can avoid inspecting
@@ -1235,7 +1304,11 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1235 hpos = run_end_hpos; 1304 hpos = run_end_hpos;
1236 if (run_end > pos) 1305 if (run_end > pos)
1237 prev_hpos = hpos - common_width; 1306 prev_hpos = hpos - common_width;
1238 pos = run_end; 1307 if (pos != run_end)
1308 {
1309 pos = run_end;
1310 pos_byte = CHAR_TO_BYTE (pos);
1311 }
1239 } 1312 }
1240 1313
1241 next_width_run = run_end + 1; 1314 next_width_run = run_end + 1;
@@ -1244,8 +1317,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1244 /* We have to scan the text character-by-character. */ 1317 /* We have to scan the text character-by-character. */
1245 else 1318 else
1246 { 1319 {
1247 c = FETCH_BYTE (pos); 1320 c = FETCH_BYTE (pos_byte);
1248 pos++; 1321 pos++, pos_byte++;
1249 1322
1250 /* Perhaps add some info to the width_run_cache. */ 1323 /* Perhaps add some info to the width_run_cache. */
1251 if (current_buffer->width_run_cache) 1324 if (current_buffer->width_run_cache)
@@ -1289,7 +1362,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1289 } 1362 }
1290 else if (c == '\n') 1363 else if (c == '\n')
1291 { 1364 {
1292 if (selective > 0 && indented_beyond_p (pos, selective)) 1365 if (selective > 0
1366 && indented_beyond_p (pos, pos_byte, selective))
1293 { 1367 {
1294 /* If (pos == to), we don't have to take care of 1368 /* If (pos == to), we don't have to take care of
1295 selective display. */ 1369 selective display. */
@@ -1297,9 +1371,12 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1297 { 1371 {
1298 /* Skip any number of invisible lines all at once */ 1372 /* Skip any number of invisible lines all at once */
1299 do 1373 do
1300 pos = find_before_next_newline (pos, to, 1) + 1; 1374 {
1375 pos = find_before_next_newline (pos, to, 1) + 1;
1376 pos_byte = CHAR_TO_BYTE (pos);
1377 }
1301 while (pos < to 1378 while (pos < to
1302 && indented_beyond_p (pos, selective)); 1379 && indented_beyond_p (pos, pos_byte, selective));
1303 /* Allow for the " ..." that is displayed for them. */ 1380 /* Allow for the " ..." that is displayed for them. */
1304 if (selective_rlen) 1381 if (selective_rlen)
1305 { 1382 {
@@ -1307,7 +1384,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1307 if (hpos >= width) 1384 if (hpos >= width)
1308 hpos = width; 1385 hpos = width;
1309 } 1386 }
1310 --pos; 1387 DEC_BOTH (pos, pos_byte);
1311 /* We have skipped the invis text, but not the 1388 /* We have skipped the invis text, but not the
1312 newline after. */ 1389 newline after. */
1313 } 1390 }
@@ -1331,7 +1408,10 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1331 everything from a ^M to the end of the line is invisible. 1408 everything from a ^M to the end of the line is invisible.
1332 Stop *before* the real newline. */ 1409 Stop *before* the real newline. */
1333 if (pos < to) 1410 if (pos < to)
1334 pos = find_before_next_newline (pos, to, 1); 1411 {
1412 pos = find_before_next_newline (pos, to, 1);
1413 pos_byte = CHAR_TO_BYTE (pos);
1414 }
1335 /* If we just skipped next_boundary, 1415 /* If we just skipped next_boundary,
1336 loop around in the main while 1416 loop around in the main while
1337 and handle it. */ 1417 and handle it. */
@@ -1351,10 +1431,10 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1351 unsigned char *ptr; 1431 unsigned char *ptr;
1352 int len, actual_len; 1432 int len, actual_len;
1353 1433
1354 pos--; /* rewind POS */ 1434 pos--, pos_byte--; /* rewind POS */
1355 1435
1356 ptr = (((pos) >= GPT ? GAP_SIZE : 0) + (pos) + BEG_ADDR - 1); 1436 ptr = BYTE_POS_ADDR (pos_byte);
1357 len = ((pos) >= GPT ? ZV : GPT) - (pos); 1437 len = BUFFER_CEILING_OF (pos_byte) - pos_byte + 1;
1358 1438
1359 c = STRING_CHAR_AND_LENGTH (ptr, len, actual_len); 1439 c = STRING_CHAR_AND_LENGTH (ptr, len, actual_len);
1360 1440
@@ -1378,7 +1458,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1378 wide_column = 1; 1458 wide_column = 1;
1379 } 1459 }
1380 1460
1381 pos += actual_len; 1461 pos++;
1462 pos_byte += actual_len;
1382 } 1463 }
1383 else 1464 else
1384 hpos += (ctl_arrow && c < 0200) ? 2 : 4; 1465 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
@@ -1395,6 +1476,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
1395 width_run_start, width_run_end); 1476 width_run_start, width_run_end);
1396 1477
1397 val_compute_motion.bufpos = pos; 1478 val_compute_motion.bufpos = pos;
1479 val_compute_motion.bytepos = pos_byte;
1398 val_compute_motion.hpos = hpos; 1480 val_compute_motion.hpos = hpos;
1399 val_compute_motion.vpos = vpos; 1481 val_compute_motion.vpos = vpos;
1400 val_compute_motion.prevhpos = prev_hpos; 1482 val_compute_motion.prevhpos = prev_hpos;
@@ -1507,42 +1589,6 @@ DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1507 1589
1508} 1590}
1509 1591
1510/* Return the column of position POS in window W's buffer.
1511 The result is rounded down to a multiple of the internal width of W.
1512 This is the amount of indentation of position POS
1513 that is not visible in its horizontal position in the window. */
1514
1515int
1516pos_tab_offset (w, pos)
1517 struct window *w;
1518 register int pos;
1519{
1520 int opoint = PT;
1521 int col;
1522 int width = window_internal_width (w) - 1;
1523
1524 if (pos == BEGV)
1525 return MINI_WINDOW_P (w) ? -minibuf_prompt_width : 0;
1526 if (FETCH_BYTE (pos - 1) == '\n')
1527 return 0;
1528 TEMP_SET_PT (pos);
1529 col = current_column ();
1530 TEMP_SET_PT (opoint);
1531 /* Modulo is no longer valid, as a line may get shorter than WIDTH
1532 columns by continuation of a wide-column character. Just return
1533 COL here. */
1534#if 0
1535 /* In the continuation of the first line in a minibuffer we must
1536 take the width of the prompt into account. */
1537 if (MINI_WINDOW_P (w) && col >= width - minibuf_prompt_width
1538 && find_next_newline_no_quit (pos, -1) == BEGV)
1539 return col - (col + minibuf_prompt_width) % width;
1540 return col - (col % width);
1541#endif
1542 return col;
1543}
1544
1545
1546/* Fvertical_motion and vmotion */ 1592/* Fvertical_motion and vmotion */
1547struct position val_vmotion; 1593struct position val_vmotion;
1548 1594
@@ -1558,6 +1604,7 @@ vmotion (from, vtarget, w)
1558 register int vpos = 0; 1604 register int vpos = 0;
1559 Lisp_Object prevline; 1605 Lisp_Object prevline;
1560 register int first; 1606 register int first;
1607 int from_byte;
1561 int lmargin = hscroll > 0 ? 1 - hscroll : 0; 1608 int lmargin = hscroll > 0 ? 1 - hscroll : 0;
1562 int selective 1609 int selective
1563 = (INTEGERP (current_buffer->selective_display) 1610 = (INTEGERP (current_buffer->selective_display)
@@ -1585,7 +1632,7 @@ vmotion (from, vtarget, w)
1585 if (vpos >= vtarget) 1632 if (vpos >= vtarget)
1586 { 1633 {
1587 /* To move upward, go a line at a time until 1634 /* To move upward, go a line at a time until
1588 we have gone at least far enough */ 1635 we have gone at least far enough. */
1589 1636
1590 first = 1; 1637 first = 1;
1591 1638
@@ -1596,7 +1643,9 @@ vmotion (from, vtarget, w)
1596 XSETFASTINT (prevline, find_next_newline_no_quit (from - 1, -1)); 1643 XSETFASTINT (prevline, find_next_newline_no_quit (from - 1, -1));
1597 while (XFASTINT (prevline) > BEGV 1644 while (XFASTINT (prevline) > BEGV
1598 && ((selective > 0 1645 && ((selective > 0
1599 && indented_beyond_p (XFASTINT (prevline), selective)) 1646 && indented_beyond_p (XFASTINT (prevline),
1647 CHAR_TO_BYTE (XFASTINT (prevline)),
1648 selective))
1600#ifdef USE_TEXT_PROPERTIES 1649#ifdef USE_TEXT_PROPERTIES
1601 /* watch out for newlines with `invisible' property */ 1650 /* watch out for newlines with `invisible' property */
1602 || (propval = Fget_char_property (prevline, 1651 || (propval = Fget_char_property (prevline,
@@ -1635,6 +1684,7 @@ vmotion (from, vtarget, w)
1635 if (vpos >= vtarget) 1684 if (vpos >= vtarget)
1636 { 1685 {
1637 val_vmotion.bufpos = from; 1686 val_vmotion.bufpos = from;
1687 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1638 val_vmotion.vpos = vpos; 1688 val_vmotion.vpos = vpos;
1639 val_vmotion.hpos = lmargin; 1689 val_vmotion.hpos = lmargin;
1640 val_vmotion.contin = 0; 1690 val_vmotion.contin = 0;
@@ -1648,14 +1698,17 @@ vmotion (from, vtarget, w)
1648 } 1698 }
1649 /* Moving downward is simple, but must calculate from beg of line 1699 /* Moving downward is simple, but must calculate from beg of line
1650 to determine hpos of starting point */ 1700 to determine hpos of starting point */
1651 if (from > BEGV && FETCH_BYTE (from - 1) != '\n') 1701 from_byte = CHAR_TO_BYTE (from);
1702 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1652 { 1703 {
1653 Lisp_Object propval; 1704 Lisp_Object propval;
1654 1705
1655 XSETFASTINT (prevline, find_next_newline_no_quit (from, -1)); 1706 XSETFASTINT (prevline, find_next_newline_no_quit (from, -1));
1656 while (XFASTINT (prevline) > BEGV 1707 while (XFASTINT (prevline) > BEGV
1657 && ((selective > 0 1708 && ((selective > 0
1658 && indented_beyond_p (XFASTINT (prevline), selective)) 1709 && indented_beyond_p (XFASTINT (prevline),
1710 CHAR_TO_BYTE (XFASTINT (prevline)),
1711 selective))
1659#ifdef USE_TEXT_PROPERTIES 1712#ifdef USE_TEXT_PROPERTIES
1660 /* watch out for newlines with `invisible' property */ 1713 /* watch out for newlines with `invisible' property */
1661 || (propval = Fget_char_property (prevline, Qinvisible, 1714 || (propval = Fget_char_property (prevline, Qinvisible,