📄 ev_edit.c
字号:
*/{ register Ev_finger_handle fingers; register int lt_index; ev_update_lt_after_edit(ft, insert, delta); if (delta > 0) { /* Correct entries that move_at_insert in views->fingers */ lt_index = ft_bounding_index(ft, insert); if (lt_index < ft->last_plus_one) { fingers = (Ev_finger_handle)ft->seq; while (fingers[lt_index].pos == insert) { if (EV_MARK_MOVE_AT_INSERT(fingers[lt_index].info)) { fingers[lt_index].pos += delta; if (lt_index-- > 0) continue; } break; } } }}static voidev_update_view_lt_after_edit(line_seq, start, stop_plus_one, minimum, delta) register Ev_impl_line_seq line_seq; int start; register int stop_plus_one; register Es_index minimum; register int delta;/* This routine differs from the similar ev_update_lt_after_edit in that it * can introduce positions of ES_CANNOT_SET (which are transient and not * valid in a normal finger table). */{ register int i; for (i = start; i < stop_plus_one; i++) { if (line_seq[i].pos < minimum) { line_seq[i].pos = ES_CANNOT_SET; } else if (line_seq[i].pos != ES_INFINITY) line_seq[i].pos += delta; }}extern voidev_update_view_display(view, clear_to_bottom) register Ev_handle view; int clear_to_bottom;{ Es_index *line_seq; ev_lt_format(view, &view->tmp_line_table, &view->line_table); ASSERT(allock()); /* * Swap line tables before paint so that old ev_display * utilities may be called during paint phase. */ line_seq = view->line_table.seq; view->line_table.seq = view->tmp_line_table.seq; view->tmp_line_table.seq = line_seq; ev_lt_paint(view, &view->line_table, &view->tmp_line_table, clear_to_bottom); ASSERT(allock());}ev_update_after_edit(views, last_plus_one, delta, old_length, min_insert_pos) register Ev_chain views; Es_index last_plus_one; int delta; Es_index old_length, min_insert_pos;/* last_plus_one: end of inserted/deleted span * delta: if positive, amount inserted; else, amount deleted * old_length: length before change * min_insert_pos: beginning of inserted/deleted span */{ register Ev_handle view; register Ev_pd_handle private; Ev_chain_pd_handle chain = EV_CHAIN_PRIVATE(views); ASSERT(allock()); /* * Update edit number and tables to reflect change to entity stream. * This must be done whenever the entity stream is modified, * regardless of whether the display is updated. */ chain->edit_number++; ev_update_lt_after_edit(&chain->op_bdry, last_plus_one, delta); ev_update_fingers_after_edit(&views->fingers, last_plus_one, delta); FORALLVIEWS(views, view) { if (ev_lt_delta(view, last_plus_one, delta)) { private = EV_PRIVATE(view); if (private->state & EV_VS_DELAY_UPDATE) { private->state |= EV_VS_DAMAGED_LT; continue; } ev_update_view_display(view, FALSE); } }}extern voidev_update_chain_display(views) register Ev_chain views;{ register Ev_handle view; register Ev_pd_handle private; FORALLVIEWS(views, view) { private = EV_PRIVATE(view); if (private->state & EV_VS_DAMAGED_LT) { ev_update_view_display(view, FALSE); private->state &= ~EV_VS_DAMAGED_LT; } }}extern voidev_make_visible(view, position, lower_context, auto_scroll_by, delta) Ev_handle view; Es_index position; int lower_context; int auto_scroll_by; int delta;{ extern int ev_xy_in_view(); Ev_impl_line_seq line_seq; int top_of_lc; int lt_index; struct rect rect; Es_index new_top; line_seq = (Ev_impl_line_seq) view->line_table.seq; top_of_lc = max(1, view->line_table.last_plus_one - 1 - lower_context); /* Following test works even if line_seq[].pos == ES_INFINITY. * The test catches the common cases and saves the expensive * call on ev_xy_in_view(). */ if (position < line_seq[top_of_lc].pos) return; switch (ev_xy_in_view(view, position, <_index, &rect)) { case EV_XY_BELOW: /* BUG ALERT: The following heuristic must be replaced! */ delta = min(delta, position - line_seq[top_of_lc].pos); if (delta < (50 * view->line_table.last_plus_one) && lower_context < view->line_table.last_plus_one - 1 && auto_scroll_by< view->line_table.last_plus_one - 1) { Es_index old_top = line_seq[0].pos; new_top = ev_scroll_lines(view, min(view->line_table.last_plus_one - 1, max(1, max(lower_context, auto_scroll_by) + (delta/50))), FALSE); /* * ev_scroll_lines swaps line tables; cannot continue using * line_seq */ while ((old_top != new_top) && (position >= ev_index_for_line(view, top_of_lc))) { old_top = new_top; new_top = ev_scroll_lines(view, ((position - ev_index_for_line(view, top_of_lc)) > 150 ? 2 : 1), FALSE); } } else { ev_set_start(view, ev_line_start(view, position)); } break; case EV_XY_RIGHT: case EV_XY_VISIBLE: /* only scroll if at least 1 newline was inserted */ if ((EV_PRIVATE(view))->cached_insert_info.lt_index != lt_index) { /* We know lt_index >= top_of_lc */ new_top = ev_scroll_lines(view, min(lt_index, max(lt_index - top_of_lc + 1, auto_scroll_by)), FALSE); ASSUME(new_top >= 0); } break; default: break; }}extern voidev_scroll_if_old_insert_visible(views, insert_pos, delta) register Ev_chain views; register Es_index insert_pos; register int delta;{ register Ev_handle view; register Ev_pd_handle private; Ev_chain_pd_handle chain = EV_CHAIN_PRIVATE(views); if (delta <= 0) /* BUG ALERT! We are not handling upper_context auto_scroll. */ return; /* Scroll views which had old_insert_pos visible, but not new. */ FORALLVIEWS(views, view) { private = EV_PRIVATE(view); if ((private->state & EV_VS_INSERT_WAS_IN_VIEW) == 0) continue /* FORALLVIEWS */; ev_make_visible(view, insert_pos, chain->lower_context, chain->auto_scroll_by, delta); }}extern voidev_input_before(views) register Ev_chain views;{ Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(views); if (private->lower_context != EV_NO_CONTEXT) { ev_check_insert_visibility(views); }}extern intev_input_partial(views, buf, buf_len) register Ev_chain views; char *buf; long int buf_len;{ register Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(views); register Es_index new_insert_pos, old_insert_pos; int used; /* We cannot assume where the esh is positioned, so position first. */ old_insert_pos = es_set_position(views->esh, private->insert_pos); if (old_insert_pos != private->insert_pos) { return(ES_CANNOT_SET); } new_insert_pos = es_replace(views->esh, old_insert_pos, buf_len, buf, &used); if (new_insert_pos == ES_CANNOT_SET || used != buf_len) { return(ES_CANNOT_SET); } private->insert_pos = new_insert_pos; return(0);}extern intev_input_after(views, old_insert_pos, old_length) register Ev_chain views; Es_index old_insert_pos, old_length;{ Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(views); Es_index delta = private->insert_pos - old_insert_pos; /* Update all of the views' data structures */ ev_update_after_edit( views, old_insert_pos, delta, old_length, old_insert_pos); if (private->lower_context != EV_NO_CONTEXT) { ev_scroll_if_old_insert_visible(views, private->insert_pos, delta); } return(delta);}#ifdef EXAMPLEextern intev_process_input(views, buf, buf_len) register Ev_chain views; char *buf; int buf_len;{ Ev_chain_pd_handle private = EV_CHAIN_PRIVATE(views); Es_index old_length = es_get_length(views->esh); Es_index old_insert_pos = private->insert_pos; int delta; ev_input_before(views); delta = ev_input_partial(views, buf, buf_len); if (delta != ES_CANNOT_SET) delta = ev_input_after(views, old_insert_pos, old_length); return(delta);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -