513 |
/* Start the scan at the beginning of this line with column number 0. */ |
/* Start the scan at the beginning of this line with column number 0. */ |
514 |
register int col = 0; |
register int col = 0; |
515 |
int scan, scan_byte; |
int scan, scan_byte; |
516 |
int next_boundary, next_boundary_byte; |
int next_boundary; |
517 |
int opoint = PT, opoint_byte = PT_BYTE; |
int opoint = PT, opoint_byte = PT_BYTE; |
518 |
|
|
519 |
scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); |
scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); |
521 |
scan = PT, scan_byte = PT_BYTE; |
scan = PT, scan_byte = PT_BYTE; |
522 |
SET_PT_BOTH (opoint, opoint_byte); |
SET_PT_BOTH (opoint, opoint_byte); |
523 |
next_boundary = scan; |
next_boundary = scan; |
|
next_boundary_byte = scan_byte; |
|
524 |
|
|
525 |
if (tab_width <= 0 || tab_width > 1000) tab_width = 8; |
if (tab_width <= 0 || tab_width > 1000) tab_width = 8; |
526 |
|
|
528 |
while (scan < opoint) |
while (scan < opoint) |
529 |
{ |
{ |
530 |
int c; |
int c; |
|
EMACS_INT i, n; |
|
|
Lisp_Object charvec; |
|
531 |
|
|
532 |
/* Occasionally we may need to skip invisible text. */ |
/* Occasionally we may need to skip invisible text. */ |
533 |
while (scan == next_boundary) |
while (scan == next_boundary) |
540 |
goto endloop; |
goto endloop; |
541 |
if (scan != old_scan) |
if (scan != old_scan) |
542 |
scan_byte = CHAR_TO_BYTE (scan); |
scan_byte = CHAR_TO_BYTE (scan); |
|
next_boundary_byte = CHAR_TO_BYTE (next_boundary); |
|
543 |
} |
} |
544 |
|
|
545 |
/* Check composition sequence. */ |
/* Check composition sequence. */ |
563 |
&& ! (multibyte && BASE_LEADING_CODE_P (c)) |
&& ! (multibyte && BASE_LEADING_CODE_P (c)) |
564 |
&& VECTORP (DISP_CHAR_VECTOR (dp, c))) |
&& VECTORP (DISP_CHAR_VECTOR (dp, c))) |
565 |
{ |
{ |
566 |
|
Lisp_Object charvec; |
567 |
|
EMACS_INT i, n; |
568 |
|
|
569 |
|
/* This character is displayed using a vector of glyphs. |
570 |
|
Update the column based on those glyphs. */ |
571 |
|
|
572 |
charvec = DISP_CHAR_VECTOR (dp, c); |
charvec = DISP_CHAR_VECTOR (dp, c); |
573 |
n = ASIZE (charvec); |
n = ASIZE (charvec); |
|
} |
|
|
else |
|
|
{ |
|
|
charvec = Qnil; |
|
|
n = 1; |
|
|
} |
|
574 |
|
|
575 |
for (i = n - 1; i >= 0; --i) |
for (i = 0; i < n; i++) |
|
{ |
|
|
if (VECTORP (charvec)) |
|
576 |
{ |
{ |
577 |
/* This should be handled the same as |
/* This should be handled the same as |
578 |
next_element_from_display_vector does it. */ |
next_element_from_display_vector does it. */ |
579 |
Lisp_Object entry = AREF (charvec, i); |
Lisp_Object entry; |
580 |
|
entry = AREF (charvec, i); |
581 |
|
|
582 |
if (INTEGERP (entry) |
if (INTEGERP (entry) |
583 |
&& GLYPH_CHAR_VALID_P (XFASTINT (entry))) |
&& GLYPH_CHAR_VALID_P (XFASTINT (entry))) |
584 |
c = FAST_GLYPH_CHAR (XFASTINT (entry)); |
c = FAST_GLYPH_CHAR (XFASTINT (entry)); |
585 |
else |
else |
586 |
c = ' '; |
c = ' '; |
587 |
|
|
588 |
|
if (c == '\n') |
589 |
|
goto endloop; |
590 |
|
if (c == '\r' && EQ (current_buffer->selective_display, Qt)) |
591 |
|
goto endloop; |
592 |
|
if (c == '\t') |
593 |
|
{ |
594 |
|
col += tab_width; |
595 |
|
col = col / tab_width * tab_width; |
596 |
|
} |
597 |
|
else |
598 |
|
++col; |
599 |
} |
} |
600 |
|
} |
601 |
|
else |
602 |
|
{ |
603 |
|
/* The display table says nothing for this character. |
604 |
|
Display it as itself. */ |
605 |
|
|
606 |
if (c == '\n') |
if (c == '\n') |
607 |
goto endloop; |
goto endloop; |
608 |
if (c == '\r' && EQ (current_buffer->selective_display, Qt)) |
if (c == '\r' && EQ (current_buffer->selective_display, Qt)) |
609 |
goto endloop; |
goto endloop; |
|
scan++; |
|
|
scan_byte++; |
|
610 |
if (c == '\t') |
if (c == '\t') |
611 |
{ |
{ |
|
int prev_col = col; |
|
612 |
col += tab_width; |
col += tab_width; |
613 |
col = col / tab_width * tab_width; |
col = col / tab_width * tab_width; |
614 |
} |
} |
616 |
{ |
{ |
617 |
unsigned char *ptr; |
unsigned char *ptr; |
618 |
int bytes, width, wide_column; |
int bytes, width, wide_column; |
619 |
|
|
|
scan_byte--; |
|
620 |
ptr = BYTE_POS_ADDR (scan_byte); |
ptr = BYTE_POS_ADDR (scan_byte); |
621 |
MULTIBYTE_BYTES_WIDTH (ptr, dp); |
MULTIBYTE_BYTES_WIDTH (ptr, dp); |
622 |
scan_byte += bytes; |
scan_byte += bytes; |
623 |
|
/* Subtract one to compensate for the increment |
624 |
|
that is going to happen below. */ |
625 |
|
scan_byte--; |
626 |
col += width; |
col += width; |
627 |
} |
} |
|
else if (VECTORP (charvec)) |
|
|
++col; |
|
628 |
else if (ctl_arrow && (c < 040 || c == 0177)) |
else if (ctl_arrow && (c < 040 || c == 0177)) |
629 |
col += 2; |
col += 2; |
630 |
else if (c < 040 || c >= 0177) |
else if (c < 040 || c >= 0177) |
632 |
else |
else |
633 |
col++; |
col++; |
634 |
} |
} |
635 |
|
scan++; |
636 |
|
scan_byte++; |
637 |
|
|
638 |
} |
} |
639 |
endloop: |
endloop: |
640 |
|
|
935 |
int prev_col = 0; |
int prev_col = 0; |
936 |
int c = 0; |
int c = 0; |
937 |
int next_boundary; |
int next_boundary; |
938 |
|
int pos_byte; |
|
int pos_byte, end_byte, next_boundary_byte; |
|
939 |
|
|
940 |
if (tab_width <= 0 || tab_width > 1000) tab_width = 8; |
if (tab_width <= 0 || tab_width > 1000) tab_width = 8; |
941 |
CHECK_NATNUM (column, 0); |
CHECK_NATNUM (column, 0); |
944 |
pos = PT; |
pos = PT; |
945 |
pos_byte = PT_BYTE; |
pos_byte = PT_BYTE; |
946 |
end = ZV; |
end = ZV; |
|
end_byte = ZV_BYTE; |
|
947 |
next_boundary = pos; |
next_boundary = pos; |
|
next_boundary_byte = PT_BYTE; |
|
948 |
|
|
949 |
/* If we're starting past the desired column, |
/* If we're starting past the desired column, |
950 |
back up to beginning of line and scan from there. */ |
back up to beginning of line and scan from there. */ |
958 |
|
|
959 |
while (pos < end) |
while (pos < end) |
960 |
{ |
{ |
|
Lisp_Object charvec; |
|
|
EMACS_INT i, n; |
|
|
|
|
961 |
while (pos == next_boundary) |
while (pos == next_boundary) |
962 |
{ |
{ |
963 |
int prev = pos; |
int prev = pos; |
964 |
pos = skip_invisible (pos, &next_boundary, end, Qnil); |
pos = skip_invisible (pos, &next_boundary, end, Qnil); |
965 |
if (pos != prev) |
if (pos != prev) |
966 |
pos_byte = CHAR_TO_BYTE (pos); |
pos_byte = CHAR_TO_BYTE (pos); |
|
next_boundary_byte = CHAR_TO_BYTE (next_boundary); |
|
967 |
if (pos >= end) |
if (pos >= end) |
968 |
goto endloop; |
goto endloop; |
969 |
} |
} |
989 |
|
|
990 |
c = FETCH_BYTE (pos_byte); |
c = FETCH_BYTE (pos_byte); |
991 |
|
|
992 |
|
/* See if there is a display table and it relates |
993 |
|
to this character. */ |
994 |
|
|
995 |
if (dp != 0 |
if (dp != 0 |
996 |
&& ! (multibyte && BASE_LEADING_CODE_P (c)) |
&& ! (multibyte && BASE_LEADING_CODE_P (c)) |
997 |
&& VECTORP (DISP_CHAR_VECTOR (dp, c))) |
&& VECTORP (DISP_CHAR_VECTOR (dp, c))) |
998 |
{ |
{ |
999 |
|
Lisp_Object charvec; |
1000 |
|
EMACS_INT i, n; |
1001 |
|
|
1002 |
charvec = DISP_CHAR_VECTOR (dp, c); |
charvec = DISP_CHAR_VECTOR (dp, c); |
1003 |
n = ASIZE (charvec); |
n = ASIZE (charvec); |
1004 |
} |
for (i = 0; i < n; i++) |
|
else |
|
|
{ |
|
|
charvec = Qnil; |
|
|
n = 1; |
|
|
} |
|
|
|
|
|
for (i = n - 1; i >= 0; --i) |
|
|
{ |
|
|
if (VECTORP (charvec)) |
|
1005 |
{ |
{ |
1006 |
/* This should be handled the same as |
/* This should be handled the same as |
1007 |
next_element_from_display_vector does it. */ |
next_element_from_display_vector does it. */ |
1008 |
Lisp_Object entry = AREF (charvec, i); |
|
1009 |
|
Lisp_Object entry; |
1010 |
|
entry = AREF (charvec, i); |
1011 |
|
|
1012 |
if (INTEGERP (entry) |
if (INTEGERP (entry) |
1013 |
&& GLYPH_CHAR_VALID_P (XFASTINT (entry))) |
&& GLYPH_CHAR_VALID_P (XFASTINT (entry))) |
1014 |
c = FAST_GLYPH_CHAR (XFASTINT (entry)); |
c = FAST_GLYPH_CHAR (XFASTINT (entry)); |
1015 |
else |
else |
1016 |
c = ' '; |
c = ' '; |
1017 |
|
|
1018 |
|
if (c == '\n') |
1019 |
|
goto endloop; |
1020 |
|
if (c == '\r' && EQ (current_buffer->selective_display, Qt)) |
1021 |
|
goto endloop; |
1022 |
|
if (c == '\t') |
1023 |
|
{ |
1024 |
|
prev_col = col; |
1025 |
|
col += tab_width; |
1026 |
|
col = col / tab_width * tab_width; |
1027 |
|
} |
1028 |
|
else |
1029 |
|
++col; |
1030 |
} |
} |
1031 |
|
} |
1032 |
|
else |
1033 |
|
{ |
1034 |
|
/* The display table doesn't affect this character; |
1035 |
|
it displays as itself. */ |
1036 |
|
|
|
|
|
1037 |
if (c == '\n') |
if (c == '\n') |
1038 |
goto endloop; |
goto endloop; |
1039 |
if (c == '\r' && EQ (current_buffer->selective_display, Qt)) |
if (c == '\r' && EQ (current_buffer->selective_display, Qt)) |
1040 |
goto endloop; |
goto endloop; |
|
pos++; |
|
|
pos_byte++; |
|
1041 |
if (c == '\t') |
if (c == '\t') |
1042 |
{ |
{ |
1043 |
prev_col = col; |
prev_col = col; |
1044 |
col += tab_width; |
col += tab_width; |
1045 |
col = col / tab_width * tab_width; |
col = col / tab_width * tab_width; |
1046 |
} |
} |
|
else if (VECTORP (charvec)) |
|
|
++col; |
|
1047 |
else if (ctl_arrow && (c < 040 || c == 0177)) |
else if (ctl_arrow && (c < 040 || c == 0177)) |
1048 |
col += 2; |
col += 2; |
1049 |
else if (c < 040 || c == 0177) |
else if (c < 040 || c == 0177) |
1056 |
unsigned char *ptr; |
unsigned char *ptr; |
1057 |
int bytes, width, wide_column; |
int bytes, width, wide_column; |
1058 |
|
|
|
pos_byte--; |
|
1059 |
ptr = BYTE_POS_ADDR (pos_byte); |
ptr = BYTE_POS_ADDR (pos_byte); |
1060 |
MULTIBYTE_BYTES_WIDTH (ptr, dp); |
MULTIBYTE_BYTES_WIDTH (ptr, dp); |
1061 |
pos_byte += bytes; |
pos_byte += bytes - 1; |
1062 |
col += width; |
col += width; |
1063 |
} |
} |
1064 |
else |
else |
1065 |
col += 4; |
col += 4; |
1066 |
} |
} |
1067 |
|
|
1068 |
|
pos++; |
1069 |
|
pos_byte++; |
1070 |
} |
} |
1071 |
endloop: |
endloop: |
1072 |
|
|
1090 |
goal_pt_byte = PT_BYTE; |
goal_pt_byte = PT_BYTE; |
1091 |
Findent_to (make_number (col), Qnil); |
Findent_to (make_number (col), Qnil); |
1092 |
SET_PT_BOTH (goal_pt, goal_pt_byte); |
SET_PT_BOTH (goal_pt, goal_pt_byte); |
1093 |
|
|
1094 |
/* Set the last_known... vars consistently. */ |
/* Set the last_known... vars consistently. */ |
1095 |
col = goal; |
col = goal; |
1096 |
} |
} |