diff options
| author | Kim F. Storm | 2006-09-15 21:04:28 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2006-09-15 21:04:28 +0000 |
| commit | b3a1034515cea88b83f569a744ae791b624cb747 (patch) | |
| tree | 5ca51730ff4f78f33f7ed399d669cc9f440fbbcd /src | |
| parent | 74f526f33bfb0deeb9036a7082177f94f4201c20 (diff) | |
| download | emacs-b3a1034515cea88b83f569a744ae791b624cb747.tar.gz emacs-b3a1034515cea88b83f569a744ae791b624cb747.zip | |
(Fwindow_line_visibility): New defun for line-move-partial.
(syms_of_window): Defsubr it.
(Fwindow_end): Use window's buffer rather than current buffer.
Diffstat (limited to 'src')
| -rw-r--r-- | src/window.c | 91 |
1 files changed, 80 insertions, 11 deletions
diff --git a/src/window.c b/src/window.c index ee2faf09ca6..8d6918feff2 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -390,6 +390,72 @@ row, and VPOS is the row number (0-based) containing POS. */) | |||
| 390 | return in_window; | 390 | return in_window; |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | DEFUN ("window-line-visibility", Fwindow_line_visibility, | ||
| 394 | Swindow_line_visibility, 0, 2, 0, | ||
| 395 | doc: /* Return information about visibility of last line in WINDOW. | ||
| 396 | If optional second arg is non-nil, test first text line instead. | ||
| 397 | Return nil if visibility of the line is not known; in that case, | ||
| 398 | caller may use `pos-visible-in-window-p' to know for sure. | ||
| 399 | |||
| 400 | Return t if window line is known to be fully visible. Otherwise, | ||
| 401 | return cons (VIS . INVIS), where VIS and INVIS is pixel height | ||
| 402 | of the visible and invisible part of the line. */) | ||
| 403 | (window, first) | ||
| 404 | Lisp_Object window, first; | ||
| 405 | { | ||
| 406 | register struct window *w; | ||
| 407 | register struct buffer *b; | ||
| 408 | struct glyph_row *row, *end_row; | ||
| 409 | int max_y, crop; | ||
| 410 | |||
| 411 | w = decode_window (window); | ||
| 412 | |||
| 413 | if (noninteractive | ||
| 414 | || !FRAME_WINDOW_P (WINDOW_XFRAME (w)) | ||
| 415 | || w->pseudo_window_p) | ||
| 416 | return Qt; | ||
| 417 | |||
| 418 | CHECK_BUFFER (w->buffer); | ||
| 419 | b = XBUFFER (w->buffer); | ||
| 420 | |||
| 421 | /* Fail if current matrix is not up-to-date. */ | ||
| 422 | if (NILP (w->window_end_valid) | ||
| 423 | || current_buffer->clip_changed | ||
| 424 | || current_buffer->prevent_redisplay_optimizations_p | ||
| 425 | || XFASTINT (w->last_modified) < BUF_MODIFF (b) | ||
| 426 | || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b)) | ||
| 427 | return Qnil; | ||
| 428 | |||
| 429 | row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); | ||
| 430 | if (!NILP (first)) | ||
| 431 | { | ||
| 432 | |||
| 433 | if (!row->enabled_p) | ||
| 434 | return Qnil; | ||
| 435 | |||
| 436 | crop = WINDOW_HEADER_LINE_HEIGHT (w) - row->y; | ||
| 437 | } | ||
| 438 | else | ||
| 439 | { | ||
| 440 | int max_y = window_text_bottom_y (w); | ||
| 441 | struct glyph_row *end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w); | ||
| 442 | |||
| 443 | while (row <= end_row && row->enabled_p | ||
| 444 | && row->y + row->height < max_y) | ||
| 445 | row++; | ||
| 446 | |||
| 447 | if (row > end_row || !row->enabled_p) | ||
| 448 | return Qnil; | ||
| 449 | |||
| 450 | crop = (row->y + row->height) - max_y; | ||
| 451 | } | ||
| 452 | |||
| 453 | if (crop > 0) | ||
| 454 | return Fcons (make_number (row->height - crop), | ||
| 455 | make_number (crop)); | ||
| 456 | return Qt; | ||
| 457 | } | ||
| 458 | |||
| 393 | 459 | ||
| 394 | static struct window * | 460 | static struct window * |
| 395 | decode_window (window) | 461 | decode_window (window) |
| @@ -1051,9 +1117,11 @@ if it isn't already recorded. */) | |||
| 1051 | Lisp_Object value; | 1117 | Lisp_Object value; |
| 1052 | struct window *w = decode_window (window); | 1118 | struct window *w = decode_window (window); |
| 1053 | Lisp_Object buf; | 1119 | Lisp_Object buf; |
| 1120 | struct buffer *b = XBUFFER (buf); | ||
| 1054 | 1121 | ||
| 1055 | buf = w->buffer; | 1122 | buf = w->buffer; |
| 1056 | CHECK_BUFFER (buf); | 1123 | CHECK_BUFFER (buf); |
| 1124 | b = XBUFFER (buf); | ||
| 1057 | 1125 | ||
| 1058 | #if 0 /* This change broke some things. We should make it later. */ | 1126 | #if 0 /* This change broke some things. We should make it later. */ |
| 1059 | /* If we don't know the end position, return nil. | 1127 | /* If we don't know the end position, return nil. |
| @@ -1066,12 +1134,20 @@ if it isn't already recorded. */) | |||
| 1066 | 1134 | ||
| 1067 | if (! NILP (update) | 1135 | if (! NILP (update) |
| 1068 | && ! (! NILP (w->window_end_valid) | 1136 | && ! (! NILP (w->window_end_valid) |
| 1069 | && XFASTINT (w->last_modified) >= MODIFF) | 1137 | && XFASTINT (w->last_modified) >= BUF_MODIFF (b)) |
| 1070 | && !noninteractive) | 1138 | && !noninteractive) |
| 1071 | { | 1139 | { |
| 1072 | struct text_pos startp; | 1140 | struct text_pos startp; |
| 1073 | struct it it; | 1141 | struct it it; |
| 1074 | struct buffer *old_buffer = NULL, *b = XBUFFER (buf); | 1142 | struct buffer *old_buffer = NULL; |
| 1143 | |||
| 1144 | /* Cannot use Fvertical_motion because that function doesn't | ||
| 1145 | cope with variable-height lines. */ | ||
| 1146 | if (b != current_buffer) | ||
| 1147 | { | ||
| 1148 | old_buffer = current_buffer; | ||
| 1149 | set_buffer_internal (b); | ||
| 1150 | } | ||
| 1075 | 1151 | ||
| 1076 | /* In case W->start is out of the range, use something | 1152 | /* In case W->start is out of the range, use something |
| 1077 | reasonable. This situation occurred when loading a file with | 1153 | reasonable. This situation occurred when loading a file with |
| @@ -1085,14 +1161,6 @@ if it isn't already recorded. */) | |||
| 1085 | else | 1161 | else |
| 1086 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | 1162 | SET_TEXT_POS_FROM_MARKER (startp, w->start); |
| 1087 | 1163 | ||
| 1088 | /* Cannot use Fvertical_motion because that function doesn't | ||
| 1089 | cope with variable-height lines. */ | ||
| 1090 | if (b != current_buffer) | ||
| 1091 | { | ||
| 1092 | old_buffer = current_buffer; | ||
| 1093 | set_buffer_internal (b); | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | start_display (&it, w, startp); | 1164 | start_display (&it, w, startp); |
| 1097 | move_it_vertically (&it, window_box_height (w)); | 1165 | move_it_vertically (&it, window_box_height (w)); |
| 1098 | if (it.current_y < it.last_visible_y) | 1166 | if (it.current_y < it.last_visible_y) |
| @@ -1103,7 +1171,7 @@ if it isn't already recorded. */) | |||
| 1103 | set_buffer_internal (old_buffer); | 1171 | set_buffer_internal (old_buffer); |
| 1104 | } | 1172 | } |
| 1105 | else | 1173 | else |
| 1106 | XSETINT (value, BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos)); | 1174 | XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos)); |
| 1107 | 1175 | ||
| 1108 | return value; | 1176 | return value; |
| 1109 | } | 1177 | } |
| @@ -7365,6 +7433,7 @@ The selected frame is the one whose configuration has changed. */); | |||
| 7365 | defsubr (&Swindowp); | 7433 | defsubr (&Swindowp); |
| 7366 | defsubr (&Swindow_live_p); | 7434 | defsubr (&Swindow_live_p); |
| 7367 | defsubr (&Spos_visible_in_window_p); | 7435 | defsubr (&Spos_visible_in_window_p); |
| 7436 | defsubr (&Swindow_line_visibility); | ||
| 7368 | defsubr (&Swindow_buffer); | 7437 | defsubr (&Swindow_buffer); |
| 7369 | defsubr (&Swindow_height); | 7438 | defsubr (&Swindow_height); |
| 7370 | defsubr (&Swindow_width); | 7439 | defsubr (&Swindow_width); |