diff options
| author | Chong Yidong | 2008-07-10 23:47:00 +0000 |
|---|---|---|
| committer | Chong Yidong | 2008-07-10 23:47:00 +0000 |
| commit | 3873a30f7f059d7f4a37eeb68d9123c5a1eb578a (patch) | |
| tree | 473ceb030d003076affc08ab6dd9d9023d5013f8 /src | |
| parent | e0f47a6850bb4abd4103b05ee323d82a1dca92f5 (diff) | |
| download | emacs-3873a30f7f059d7f4a37eeb68d9123c5a1eb578a.tar.gz emacs-3873a30f7f059d7f4a37eeb68d9123c5a1eb578a.zip | |
(move_it_to): Backtrack if past the edge of a wrapped line.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 87 |
1 files changed, 51 insertions, 36 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 00bedccd9f8..f5dfd547705 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -7117,6 +7117,9 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op) | |||
| 7117 | { | 7117 | { |
| 7118 | struct it it_backup; | 7118 | struct it it_backup; |
| 7119 | 7119 | ||
| 7120 | if (it->line_wrap == WORD_WRAP) | ||
| 7121 | it_backup = *it; | ||
| 7122 | |||
| 7120 | /* TO_Y specified means stop at TO_X in the line containing | 7123 | /* TO_Y specified means stop at TO_X in the line containing |
| 7121 | TO_Y---or at TO_CHARPOS if this is reached first. The | 7124 | TO_Y---or at TO_CHARPOS if this is reached first. The |
| 7122 | problem is that we can't really tell whether the line | 7125 | problem is that we can't really tell whether the line |
| @@ -7129,28 +7132,19 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op) | |||
| 7129 | If we didn't use TO_X == 0, we would stop at the end of | 7132 | If we didn't use TO_X == 0, we would stop at the end of |
| 7130 | the line which is probably not what a caller would expect | 7133 | the line which is probably not what a caller would expect |
| 7131 | to happen. */ | 7134 | to happen. */ |
| 7132 | skip = move_it_in_display_line_to (it, to_charpos, | 7135 | skip = move_it_in_display_line_to |
| 7133 | ((op & MOVE_TO_X) | 7136 | (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0), |
| 7134 | ? to_x : 0), | 7137 | (MOVE_TO_X | (op & MOVE_TO_POS))); |
| 7135 | (MOVE_TO_X | ||
| 7136 | | (op & MOVE_TO_POS))); | ||
| 7137 | 7138 | ||
| 7138 | /* If TO_CHARPOS is reached or ZV, we don't have to do more. */ | 7139 | /* If TO_CHARPOS is reached or ZV, we don't have to do more. */ |
| 7139 | if (skip == MOVE_POS_MATCH_OR_ZV) | 7140 | if (skip == MOVE_POS_MATCH_OR_ZV) |
| 7141 | reached = 5; | ||
| 7142 | else if (skip == MOVE_X_REACHED) | ||
| 7140 | { | 7143 | { |
| 7141 | reached = 5; | 7144 | /* If TO_X was reached, we want to know whether TO_Y is |
| 7142 | break; | 7145 | in the line. We know this is the case if the already |
| 7143 | } | 7146 | scanned glyphs make the line tall enough. Otherwise, |
| 7144 | 7147 | we must check by scanning the rest of the line. */ | |
| 7145 | /* If TO_X was reached, we would like to know whether TO_Y | ||
| 7146 | is in the line. This can only be said if we know the | ||
| 7147 | total line height which requires us to scan the rest of | ||
| 7148 | the line. */ | ||
| 7149 | if (skip == MOVE_X_REACHED) | ||
| 7150 | { | ||
| 7151 | /* Wait! We can conclude that TO_Y is in the line if | ||
| 7152 | the already scanned glyphs make the line tall enough | ||
| 7153 | because further scanning doesn't make it shorter. */ | ||
| 7154 | line_height = it->max_ascent + it->max_descent; | 7148 | line_height = it->max_ascent + it->max_descent; |
| 7155 | if (to_y >= it->current_y | 7149 | if (to_y >= it->current_y |
| 7156 | && to_y < it->current_y + line_height) | 7150 | && to_y < it->current_y + line_height) |
| @@ -7163,27 +7157,48 @@ move_it_to (it, to_charpos, to_x, to_y, to_vpos, op) | |||
| 7163 | skip2 = move_it_in_display_line_to (it, to_charpos, -1, | 7157 | skip2 = move_it_in_display_line_to (it, to_charpos, -1, |
| 7164 | op & MOVE_TO_POS); | 7158 | op & MOVE_TO_POS); |
| 7165 | TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it))); | 7159 | TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it))); |
| 7166 | } | 7160 | line_height = it->max_ascent + it->max_descent; |
| 7167 | 7161 | TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height)); | |
| 7168 | /* Now, decide whether TO_Y is in this line. */ | ||
| 7169 | line_height = it->max_ascent + it->max_descent; | ||
| 7170 | TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height)); | ||
| 7171 | 7162 | ||
| 7172 | if (to_y >= it->current_y | 7163 | if (to_y >= it->current_y |
| 7173 | && to_y < it->current_y + line_height) | 7164 | && to_y < it->current_y + line_height) |
| 7174 | { | 7165 | { |
| 7175 | if (skip == MOVE_X_REACHED) | 7166 | /* If TO_Y is in this line and TO_X was reached |
| 7176 | /* If TO_Y is in this line and TO_X was reached above, | 7167 | above, we scanned too far. We have to restore |
| 7177 | we scanned too far. We have to restore IT's settings | 7168 | IT's settings to the ones before skipping. */ |
| 7178 | to the ones before skipping. */ | 7169 | *it = it_backup; |
| 7179 | *it = it_backup; | 7170 | reached = 6; |
| 7180 | reached = 6; | 7171 | } |
| 7172 | else | ||
| 7173 | { | ||
| 7174 | skip = skip2; | ||
| 7175 | if (skip == MOVE_POS_MATCH_OR_ZV) | ||
| 7176 | reached = 7; | ||
| 7177 | } | ||
| 7181 | } | 7178 | } |
| 7182 | else if (skip == MOVE_X_REACHED) | 7179 | else |
| 7183 | { | 7180 | { |
| 7184 | skip = skip2; | 7181 | /* Check whether TO_Y is in this line. */ |
| 7185 | if (skip == MOVE_POS_MATCH_OR_ZV) | 7182 | line_height = it->max_ascent + it->max_descent; |
| 7186 | reached = 7; | 7183 | TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height)); |
| 7184 | |||
| 7185 | if (to_y >= it->current_y | ||
| 7186 | && to_y < it->current_y + line_height) | ||
| 7187 | { | ||
| 7188 | /* When word-wrap is on, TO_X may lie past the end | ||
| 7189 | of a wrapped line. Then it->current is the | ||
| 7190 | character on the next line, so backtrack to the | ||
| 7191 | space before the wrap point. */ | ||
| 7192 | if (skip == MOVE_LINE_CONTINUED | ||
| 7193 | && it->line_wrap == WORD_WRAP) | ||
| 7194 | { | ||
| 7195 | int prev_x = max (it->current_x - 1, 0); | ||
| 7196 | *it = it_backup; | ||
| 7197 | skip = move_it_in_display_line_to | ||
| 7198 | (it, -1, prev_x, MOVE_TO_X); | ||
| 7199 | } | ||
| 7200 | reached = 6; | ||
| 7201 | } | ||
| 7187 | } | 7202 | } |
| 7188 | 7203 | ||
| 7189 | if (reached) | 7204 | if (reached) |