📄 textsw_caret.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)textsw_caret.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986, 1987 by Sun Microsystems, Inc. *//* * Routines for moving textsw caret. */ #include <suntool/primal.h>#include <suntool/textsw_impl.h>#include <suntool/ev_impl.h>extern void textsw_record_caret_motion();static voidmake_insert_visible(view, visible_status, old_insert, new_insert) Textsw_view view; unsigned visible_status; /* For old_insert */ Es_index old_insert, new_insert;{ Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_chain chain = folio->views; register Ev_handle ev_handle = view->e_view; register unsigned normalize_flag = (TXTSW_NI_NOT_IF_IN_VIEW | TXTSW_NI_MARK); int lower_context, upper_context, scroll_lines; /* * This procedure will only do display if the new_insert * position is not in view. * It will scroll, if the old_insert position is in view, but not * new_insert. * It will repaint the entire view, if the old_insert and new_insert * position are not in view. */ lower_context = (int)LINT_CAST(ev_get(chain, EV_CHAIN_LOWER_CONTEXT)); upper_context = (int)LINT_CAST(ev_get(chain, EV_CHAIN_UPPER_CONTEXT)); if (visible_status == EV_XY_VISIBLE) { int lines_in_view = textsw_screen_line_count(VIEW_REP_TO_ABS(view)); if (old_insert > new_insert) /* scroll backward */ scroll_lines = ((upper_context > 0) && (lines_in_view >= upper_context)) ? -upper_context : -1; else scroll_lines = ((lower_context > 0) && (lines_in_view >= lower_context)) ? lower_context : 1; while (!ev_insert_visible_in_view(ev_handle)) { ev_scroll_lines(ev_handle, scroll_lines, FALSE); } textsw_update_scrollbars(folio, view); } else { if (old_insert <= new_insert) { normalize_flag |= TXTSW_NI_AT_BOTTOM; upper_context = 0; } lower_context = 0; textsw_normalize_internal(view, new_insert, new_insert, upper_context, lower_context, normalize_flag); }} pkg_private Es_indextextsw_move_backward_a_word(view, pos) register Textsw_view view; Es_index pos;{ register Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_chain chain = folio->views; unsigned span_flag = (EI_SPAN_WORD | EI_SPAN_LEFT_ONLY); Es_index first, last_plus_one; unsigned span_result = EI_SPAN_NOT_IN_CLASS; if (pos == 0) /* This is already at the beginning of the file */ return (ES_CANNOT_SET); while ((pos != 0) && (pos != ES_CANNOT_SET) && (span_result & EI_SPAN_NOT_IN_CLASS)) { span_result = ev_span(chain, pos, &first, &last_plus_one, span_flag); pos = ((pos == first) ? pos-- : first); } return(pos);}pkg_private Es_indextextsw_move_down_a_line(view, pos, file_length, lt_index, rect) register Textsw_view view; Es_index pos, file_length; int lt_index; struct rect rect; { register Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_handle ev_handle = view->e_view; int line_height = ei_line_height (ev_handle->view_chain->eih); int new_x, new_y; Es_index new_pos; int lower_context, scroll_lines; Ev_impl_line_seq line_seq = (Ev_impl_line_seq) ev_handle->line_table.seq; pkg_private int textsw_get_recorded_x(); if ((pos >= file_length) || (line_seq[lt_index+1].pos == ES_INFINITY) || (line_seq[lt_index+1].pos == file_length)) return(ES_CANNOT_SET); if (pos >= line_seq[ev_handle->line_table.last_plus_one-2].pos) { int lines_in_view = textsw_screen_line_count(VIEW_REP_TO_ABS(view)); lower_context = (int)LINT_CAST(ev_get(folio->views, EV_CHAIN_LOWER_CONTEXT)); scroll_lines = ((lower_context > 0) && (lines_in_view > lower_context)) ? lower_context + 1 : 1; ev_scroll_lines(ev_handle, scroll_lines, FALSE); new_y = rect.r_top - (line_height * (scroll_lines - 1)); textsw_update_scrollbars(folio, view); } else new_y = rect.r_top + line_height; new_x = textsw_get_recorded_x(view); if (new_x < rect.r_left) new_x = rect.r_left; (void) textsw_record_caret_motion(folio, TXTSW_NEXT_LINE, new_x); new_pos = ev_resolve_xy(ev_handle, new_x, new_y); return ((new_pos >= 0 && new_pos <= file_length) ? new_pos : ES_CANNOT_SET); } pkg_private Es_indextextsw_move_forward_a_word(view, pos, file_length) Textsw_view view; Es_index pos; Es_index file_length;{ Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_chain chain = folio->views; unsigned span_flag = (EI_SPAN_WORD | EI_SPAN_RIGHT_ONLY); Es_index first, last_plus_one; unsigned span_result = EI_SPAN_NOT_IN_CLASS; if (pos >= file_length) return(ES_CANNOT_SET); /* Get to the end of current word, and use that as start pos */ (void) ev_span(chain, pos, &first, &last_plus_one, span_flag); pos = ((last_plus_one == file_length) ? ES_CANNOT_SET : last_plus_one); while ((pos != ES_CANNOT_SET) && (span_result & EI_SPAN_NOT_IN_CLASS)) { span_result = ev_span(chain, pos, &first, &last_plus_one, span_flag); if (pos == last_plus_one) pos = ((pos == file_length) ? ES_CANNOT_SET : pos++); else pos = last_plus_one; } return ((pos == ES_CANNOT_SET) ? ES_CANNOT_SET : first); } pkg_private Es_indextextsw_move_to_word_end(view, pos, file_length) Textsw_view view; Es_index pos; Es_index file_length;{ Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_chain chain = folio->views; unsigned span_flag = (EI_SPAN_WORD | EI_SPAN_RIGHT_ONLY); Es_index first, last_plus_one; unsigned span_result = EI_SPAN_NOT_IN_CLASS; if (pos >= file_length) return(ES_CANNOT_SET); while ((pos != ES_CANNOT_SET) && (span_result & EI_SPAN_NOT_IN_CLASS)) { span_result = ev_span(chain, pos, &first, &last_plus_one, span_flag); if (pos == last_plus_one) pos = ((pos == file_length) ? ES_CANNOT_SET : pos++); else pos = last_plus_one; } return(pos); }pkg_private Es_indextextsw_move_left_a_character(view, pos) Textsw_view view; Es_index pos;{ return((pos == 0) ? ES_CANNOT_SET : --pos);}pkg_private Es_indextextsw_move_right_a_character(view, pos, file_length) Textsw_view view; Es_index pos; Es_index file_length;{ return((pos >= file_length) ? ES_CANNOT_SET : ++pos);}pkg_private Es_indextextsw_move_to_line_start(view, pos) Textsw_view view; Es_index pos;{ Textsw_folio folio = FOLIO_FOR_VIEW(view); unsigned span_flag = (EI_SPAN_LINE | EI_SPAN_LEFT_ONLY); Es_index first, last_plus_one; if (pos == 0) return(ES_CANNOT_SET); (void)ev_span(folio->views, pos, &first, &last_plus_one, span_flag); if (pos == first) (void)ev_span(folio->views, --pos, &first, &last_plus_one, span_flag); return(first);}pkg_private Es_indextextsw_move_next_line_end(view, pos, file_length) Textsw_view view; Es_index pos; Es_index file_length;{ Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_chain chain = folio->views; unsigned span_flag = (EI_SPAN_LINE | EI_SPAN_RIGHT_ONLY); Es_index first, last_plus_one; if (pos >= file_length) return(ES_CANNOT_SET); (void)ev_span(chain, pos, &first, &last_plus_one, span_flag); if (pos == (last_plus_one - 1)) (void)ev_span(chain, ++pos, &first, &last_plus_one, span_flag); if (last_plus_one < file_length) return(--last_plus_one); else { char buf[1]; (void) textsw_get_contents(folio, --last_plus_one, buf, 1); return((buf[0] == '\n') ? last_plus_one : file_length); } }pkg_private Es_indextextsw_move_next_line_start(view, pos, file_length) Textsw_view view; Es_index pos; Es_index file_length;{ Textsw_folio folio = FOLIO_FOR_VIEW(view); unsigned span_flag = (EI_SPAN_LINE | EI_SPAN_RIGHT_ONLY); Es_index first, last_plus_one; if (pos >= file_length) return(ES_CANNOT_SET); (void)ev_span(folio->views, pos, &first, &last_plus_one, span_flag); return((last_plus_one == file_length) ? ES_CANNOT_SET : last_plus_one);}pkg_private Es_indextextsw_move_up_a_line(view, pos, file_length, lt_index, rect) register Textsw_view view; Es_index pos; Es_index file_length; int lt_index; struct rect rect;{ register Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_chain chain = folio->views; register Ev_handle ev_handle = view->e_view; int line_height = ei_line_height( ev_handle->view_chain->eih); int new_x, new_y; Es_index new_pos; int upper_context, scroll_lines; Ev_impl_line_seq line_seq = (Ev_impl_line_seq) ev_handle->line_table.seq; pkg_private int textsw_get_recorded_x(); if ((pos == 0) || (line_seq[lt_index].pos == 0)) return(ES_CANNOT_SET); if (pos < line_seq[1].pos) { int lines_in_view = textsw_screen_line_count(VIEW_REP_TO_ABS(view)); upper_context = (int)LINT_CAST(ev_get(chain, EV_CHAIN_UPPER_CONTEXT)); scroll_lines = ((upper_context > 0) && (lines_in_view > upper_context)) ? upper_context + 1 : 1; ev_scroll_lines(ev_handle, -scroll_lines, FALSE); textsw_update_scrollbars(folio, view); new_y = rect.r_top + (line_height * (scroll_lines - 1)); } else new_y = rect.r_top - line_height; new_x = textsw_get_recorded_x(view); if (new_x < rect.r_left) new_x = rect.r_left; (void) textsw_record_caret_motion(folio, TXTSW_PREVIOUS_LINE, new_x); new_pos = ev_resolve_xy(ev_handle, new_x, new_y); return ((new_pos >= 0 && new_pos <= file_length) ? new_pos : ES_CANNOT_SET); }pkg_private voidtextsw_move_caret(view, direction) Textsw_view view; Textsw_Caret_Direction direction; { int ok = TRUE; Textsw_folio folio = FOLIO_FOR_VIEW(view); register Ev_chain chain = folio->views; Es_index old_pos, pos; unsigned visible_status; Es_index file_length = es_get_length(chain->esh); int lt_index; struct rect rect; Es_index first, last_plus_one; if (TXTSW_IS_READ_ONLY(folio) || (file_length == 0)) { (void) window_bell(WINDOW_FROM_VIEW(view)); return; } textsw_flush_caches(view, TFC_STD); textsw_checkpoint_undo(VIEW_REP_TO_ABS(view), (caddr_t)TEXTSW_INFINITY-1); pos = ES_CANNOT_SET; old_pos = ev_get_insert(chain); visible_status = ev_xy_in_view(view->e_view, old_pos, <_index, &rect); switch (direction) { case TXTSW_CHAR_BACKWARD: pos = textsw_move_left_a_character(view, old_pos); break; case TXTSW_CHAR_FORWARD: pos = textsw_move_right_a_character(view, old_pos, file_length); break; case TXTSW_DOCUMENT_END: if ((old_pos < file_length) || (visible_status != EV_XY_VISIBLE)) { pos = file_length; visible_status = EV_XY_BELOW; } else pos = ES_CANNOT_SET; break; case TXTSW_DOCUMENT_START: if ((old_pos > 0) || (visible_status != EV_XY_VISIBLE)) { pos = 0; visible_status = EV_XY_ABOVE; } else pos = ES_CANNOT_SET; break; case TXTSW_LINE_END: pos = textsw_move_next_line_end(view, old_pos, file_length); break; case TXTSW_LINE_START: pos = textsw_move_to_line_start(view, old_pos); break; case TXTSW_NEXT_LINE_START: pos = textsw_move_next_line_start(view, old_pos, file_length); break; case TXTSW_NEXT_LINE: { int lower_context = (int)LINT_CAST( ev_get(chain, EV_CHAIN_LOWER_CONTEXT)); if (visible_status != EV_XY_VISIBLE) { textsw_normalize_internal(view, old_pos, old_pos, 0, lower_context + 1, (TXTSW_NI_NOT_IF_IN_VIEW | TXTSW_NI_MARK | TXTSW_NI_AT_BOTTOM)); visible_status = ev_xy_in_view(view->e_view, old_pos, <_index, &rect); } if (visible_status == EV_XY_VISIBLE) pos = textsw_move_down_a_line(view, old_pos, file_length, lt_index, rect); break; } case TXTSW_PREVIOUS_LINE: { int upper_context = (int)LINT_CAST( ev_get(chain, EV_CHAIN_UPPER_CONTEXT)); if (visible_status != EV_XY_VISIBLE) { textsw_normalize_internal(view, old_pos, old_pos, upper_context + 1, 0, (TXTSW_NI_NOT_IF_IN_VIEW | TXTSW_NI_MARK)); visible_status = ev_xy_in_view(view->e_view, old_pos, <_index, &rect); } if (visible_status == EV_XY_VISIBLE) pos = textsw_move_up_a_line(view, old_pos, file_length, lt_index, rect); break; } case TXTSW_WORD_BACKWARD: pos = textsw_move_backward_a_word(view, old_pos); break; case TXTSW_WORD_FORWARD: pos = textsw_move_forward_a_word(view, old_pos, file_length); break; case TXTSW_WORD_END: pos = textsw_move_to_word_end(view, old_pos, file_length); break; default: ok = FALSE; break; } if (ok) { if ((pos == ES_CANNOT_SET) && (visible_status != EV_XY_VISIBLE)) pos = old_pos; /* Put insertion point in view anyway */ if (pos == ES_CANNOT_SET) (void) window_bell(WINDOW_FROM_VIEW(view)); else { textsw_set_insert(folio, pos); make_insert_visible(view, visible_status, old_pos, pos); /* Replace pending delete with primary selection */ if (EV_SEL_PENDING_DELETE & ev_get_selection( chain, &first, &last_plus_one, EV_SEL_PRIMARY)) (void) textsw_set_selection( VIEW_REP_TO_ABS(view), first, last_plus_one, EV_SEL_PRIMARY); } textsw_checkpoint_undo(VIEW_REP_TO_ABS(view), (caddr_t)TEXTSW_INFINITY-1); if ((direction != TXTSW_NEXT_LINE) && (direction != TXTSW_PREVIOUS_LINE)) (void) textsw_record_caret_motion(folio, direction, -1); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -