diff options
Diffstat (limited to 'src/indent.c')
| -rw-r--r-- | src/indent.c | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/src/indent.c b/src/indent.c index d2dfaee254e..cb368024d97 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -306,8 +306,8 @@ and point (e.g., control characters will have a width of 2 or 4, tabs | |||
| 306 | will have a variable width). | 306 | will have a variable width). |
| 307 | Ignores finite width of frame, which means that this function may return | 307 | Ignores finite width of frame, which means that this function may return |
| 308 | values greater than (frame-width). | 308 | values greater than (frame-width). |
| 309 | In a buffer with very long lines, the value can be zero, because calculating | 309 | In a buffer with very long lines, the value will be an approximation, |
| 310 | the exact number is very expensive. | 310 | because calculating the exact number is very expensive. |
| 311 | Whether the line is visible (if `selective-display' is t) has no effect; | 311 | Whether the line is visible (if `selective-display' is t) has no effect; |
| 312 | however, ^M is treated as end of line when `selective-display' is t. | 312 | however, ^M is treated as end of line when `selective-display' is t. |
| 313 | Text that has an invisible property is considered as having width 0, unless | 313 | Text that has an invisible property is considered as having width 0, unless |
| @@ -316,8 +316,6 @@ Text that has an invisible property is considered as having width 0, unless | |||
| 316 | { | 316 | { |
| 317 | Lisp_Object temp; | 317 | Lisp_Object temp; |
| 318 | 318 | ||
| 319 | if (current_buffer->long_line_optimizations_p) | ||
| 320 | return make_fixnum (0); | ||
| 321 | XSETFASTINT (temp, current_column ()); | 319 | XSETFASTINT (temp, current_column ()); |
| 322 | return temp; | 320 | return temp; |
| 323 | } | 321 | } |
| @@ -346,6 +344,14 @@ current_column (void) | |||
| 346 | && MODIFF == last_known_column_modified) | 344 | && MODIFF == last_known_column_modified) |
| 347 | return last_known_column; | 345 | return last_known_column; |
| 348 | 346 | ||
| 347 | ptrdiff_t line_beg = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, | ||
| 348 | NULL, NULL, 1); | ||
| 349 | |||
| 350 | /* Avoid becoming abysmally slow for very long lines. */ | ||
| 351 | if (current_buffer->long_line_optimizations_p | ||
| 352 | && !NILP (Vlong_line_threshold) | ||
| 353 | && PT - line_beg > XFIXNUM (Vlong_line_threshold)) | ||
| 354 | return PT - line_beg; /* this is an approximation! */ | ||
| 349 | /* If the buffer has overlays, text properties, | 355 | /* If the buffer has overlays, text properties, |
| 350 | or multibyte characters, use a more general algorithm. */ | 356 | or multibyte characters, use a more general algorithm. */ |
| 351 | if (buffer_intervals (current_buffer) | 357 | if (buffer_intervals (current_buffer) |
| @@ -561,13 +567,53 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, | |||
| 561 | ptrdiff_t scan, scan_byte, next_boundary, prev_pos, prev_bpos; | 567 | ptrdiff_t scan, scan_byte, next_boundary, prev_pos, prev_bpos; |
| 562 | 568 | ||
| 563 | scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1); | 569 | scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1); |
| 564 | next_boundary = scan; | ||
| 565 | prev_pos = scan; | ||
| 566 | prev_bpos = scan_byte; | ||
| 567 | 570 | ||
| 568 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); | 571 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); |
| 569 | w = ! NILP (window) ? XWINDOW (window) : NULL; | 572 | w = ! NILP (window) ? XWINDOW (window) : NULL; |
| 570 | 573 | ||
| 574 | if (current_buffer->long_line_optimizations_p) | ||
| 575 | { | ||
| 576 | bool lines_truncated = false; | ||
| 577 | |||
| 578 | if (!NILP (BVAR (current_buffer, truncate_lines))) | ||
| 579 | lines_truncated = true; | ||
| 580 | else if (w && FIXNUMP (Vtruncate_partial_width_windows)) | ||
| 581 | lines_truncated = | ||
| 582 | w->total_cols < XFIXNAT (Vtruncate_partial_width_windows); | ||
| 583 | else if (w && !NILP (Vtruncate_partial_width_windows)) | ||
| 584 | lines_truncated = | ||
| 585 | w->total_cols < FRAME_COLS (XFRAME (WINDOW_FRAME (w))); | ||
| 586 | /* Special optimization for buffers with long and truncated | ||
| 587 | lines: assumes that each character is a single column. */ | ||
| 588 | if (lines_truncated) | ||
| 589 | { | ||
| 590 | ptrdiff_t bolpos = scan; | ||
| 591 | /* The newline which ends this line or ZV. */ | ||
| 592 | ptrdiff_t eolpos = | ||
| 593 | find_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, NULL, NULL, 1); | ||
| 594 | |||
| 595 | scan = bolpos + goal; | ||
| 596 | if (scan > end) | ||
| 597 | scan = end; | ||
| 598 | if (scan > eolpos) | ||
| 599 | scan = (eolpos == ZV ? ZV : eolpos - 1); | ||
| 600 | col = scan - bolpos; | ||
| 601 | if (col > large_hscroll_threshold) | ||
| 602 | { | ||
| 603 | prev_col = col - 1; | ||
| 604 | prev_pos = scan - 1; | ||
| 605 | prev_bpos = CHAR_TO_BYTE (scan); | ||
| 606 | goto endloop; | ||
| 607 | } | ||
| 608 | /* Restore the values we've overwritten above. */ | ||
| 609 | scan = bolpos; | ||
| 610 | col = 0; | ||
| 611 | } | ||
| 612 | } | ||
| 613 | next_boundary = scan; | ||
| 614 | prev_pos = scan; | ||
| 615 | prev_bpos = scan_byte; | ||
| 616 | |||
| 571 | memset (&cmp_it, 0, sizeof cmp_it); | 617 | memset (&cmp_it, 0, sizeof cmp_it); |
| 572 | cmp_it.id = -1; | 618 | cmp_it.id = -1; |
| 573 | composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil); | 619 | composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil); |