📄 edit.c
字号:
edit->line_offsets[1] = edit_bol (edit, edit->curs1); edit->line_numbers[2] = edit->total_lines; edit->line_offsets[2] = edit_bol (edit, edit->last_byte); edit->caches_valid = 1; } if (line >= edit->total_lines) return edit->line_offsets[2]; if (line <= 0) return 0;/* find the closest known point */ for (i = 0; i < N_LINE_CACHES; i++) { int n; n = abs (edit->line_numbers[i] - line); if (n < m) { m = n; j = i; } } if (m == 0) return edit->line_offsets[j]; /* know the offset exactly */ if (m == 1 && j >= 3) i = j; /* one line different - caller might be looping, so stay in this cache */ else i = 3 + (rand () % (N_LINE_CACHES - 3)); if (line > edit->line_numbers[j]) edit->line_offsets[i] = edit_move_forward (edit, edit->line_offsets[j], line - edit->line_numbers[j], 0); else edit->line_offsets[i] = edit_move_backward (edit, edit->line_offsets[j], edit->line_numbers[j] - line); edit->line_numbers[i] = line; return edit->line_offsets[i];}int line_is_blank (WEdit * edit, long line){ return is_blank (edit, edit_find_line (edit, line));}/* moves up until a blank line is reached, or until just before a non-blank line is reached */static void edit_move_up_paragraph (WEdit * edit, int scroll){ int i; if (edit->curs_line <= 1) { i = 0; } else { if (line_is_blank (edit, edit->curs_line)) { if (line_is_blank (edit, edit->curs_line - 1)) { for (i = edit->curs_line - 1; i; i--) if (!line_is_blank (edit, i)) { i++; break; } } else { for (i = edit->curs_line - 1; i; i--) if (line_is_blank (edit, i)) break; } } else { for (i = edit->curs_line - 1; i; i--) if (line_is_blank (edit, i)) break; } } edit_move_up (edit, edit->curs_line - i, scroll);}/* move i lines */void edit_move_down (WEdit * edit, int i, int scroll){ long p, l = edit->total_lines - edit->curs_line; if (i > l) i = l; if (i) { if (i > 1) edit->force |= REDRAW_PAGE; if (scroll) edit_scroll_downward (edit, i); p = edit_bol (edit, edit->curs1); edit_cursor_move (edit, (p = edit_move_forward (edit, p, i, 0)) - edit->curs1); edit_move_to_prev_col (edit, p); edit->search_start = edit->curs1; edit->found_len = 0; }}/* moves down until a blank line is reached, or until just before a non-blank line is reached */static void edit_move_down_paragraph (WEdit * edit, int scroll){ int i; if (edit->curs_line >= edit->total_lines - 1) { i = edit->total_lines; } else { if (line_is_blank (edit, edit->curs_line)) { if (line_is_blank (edit, edit->curs_line + 1)) { for (i = edit->curs_line + 1; i; i++) if (!line_is_blank (edit, i) || i > edit->total_lines) { i--; break; } } else { for (i = edit->curs_line + 1; i; i++) if (line_is_blank (edit, i) || i >= edit->total_lines) break; } } else { for (i = edit->curs_line + 1; i; i++) if (line_is_blank (edit, i) || i >= edit->total_lines) break; } } edit_move_down (edit, i - edit->curs_line, scroll);}static void edit_begin_page (WEdit *edit){ edit_update_curs_row (edit); edit_move_up (edit, edit->curs_row, 0);}static void edit_end_page (WEdit *edit){ edit_update_curs_row (edit); edit_move_down (edit, edit->num_widget_lines - edit->curs_row - 1, 0);}/* goto beginning of text */static void edit_move_to_top (WEdit * edit){ if (edit->curs_line) { edit_cursor_move (edit, -edit->curs1); edit_move_to_prev_col (edit, 0); edit->force |= REDRAW_PAGE; edit->search_start = 0; edit_update_curs_row(edit); }}/* goto end of text */static void edit_move_to_bottom (WEdit * edit){ if (edit->curs_line < edit->total_lines) { edit_cursor_move (edit, edit->curs2); edit->start_display = edit->last_byte; edit->start_line = edit->total_lines; edit_update_curs_row(edit); edit_scroll_upward (edit, edit->num_widget_lines - 1); edit->force |= REDRAW_PAGE; }}/* goto beginning of line */static void edit_cursor_to_bol (WEdit * edit){ edit_cursor_move (edit, edit_bol (edit, edit->curs1) - edit->curs1); edit->search_start = edit->curs1; edit->prev_col = edit_get_col (edit);}/* goto end of line */static void edit_cursor_to_eol (WEdit * edit){ edit_cursor_move (edit, edit_eol (edit, edit->curs1) - edit->curs1); edit->search_start = edit->curs1; edit->prev_col = edit_get_col (edit);}/* move cursor to line 'line' */void edit_move_to_line (WEdit * e, long line){ if(line < e->curs_line) edit_move_up (e, e->curs_line - line, 0); else edit_move_down (e, line - e->curs_line, 0); edit_scroll_screen_over_cursor (e);}/* scroll window so that first visible line is 'line' */void edit_move_display (WEdit * e, long line){ if(line < e->start_line) edit_scroll_upward (e, e->start_line - line); else edit_scroll_downward (e, line - e->start_line);}/* save markers onto undo stack */void edit_push_markers (WEdit * edit){ edit_push_action (edit, MARK_1 + edit->mark1); edit_push_action (edit, MARK_2 + edit->mark2);}void free_selections (void){ int i; for (i = 0; i < NUM_SELECTION_HISTORY; i++) if (selection_history[i].text) { free (selection_history[i].text); selection_history[i].text = 0; selection_history[i].len = 0; } current_selection = 0;}/* return -1 on nothing to store or error, zero otherwise */void edit_get_selection (WEdit * edit){ long start_mark, end_mark; if (eval_marks (edit, &start_mark, &end_mark)) return; if (selection_history[current_selection].len < 4096) /* large selections should not be held -- to save memory */ current_selection = (current_selection + 1) % NUM_SELECTION_HISTORY; selection_history[current_selection].len = end_mark - start_mark; if (selection_history[current_selection].text) free (selection_history[current_selection].text); selection_history[current_selection].text = malloc (selection_history[current_selection].len + 1); if (!selection_history[current_selection].text) { selection_history[current_selection].text = malloc (1); *selection_history[current_selection].text = 0; selection_history[current_selection].len = 0; } else { unsigned char *p = selection_history[current_selection].text; for (; start_mark < end_mark; start_mark++) *p++ = edit_get_byte (edit, start_mark); *p = 0; } selection_clear (); selection.text = selection_history[current_selection].text; selection.len = selection_history[current_selection].len;}void edit_set_markers (WEdit * edit, long m1, long m2, int c1, int c2){ edit->mark1 = m1; edit->mark2 = m2; edit->column1 = c1; edit->column2 = c2;}/* highlight marker toggle */void edit_mark_cmd (WEdit * edit, int unmark){ edit_push_markers (edit); if (unmark) { edit_set_markers (edit, 0, 0, 0, 0); edit->force |= REDRAW_PAGE; } else { if (edit->mark2 >= 0) { edit_set_markers (edit, edit->curs1, -1, edit->curs_col, edit->curs_col); edit->force |= REDRAW_PAGE; } else edit_set_markers (edit, edit->mark1, edit->curs1, edit->column1, edit->curs_col); }}static unsigned long my_type_of (int c){ int x, r = 0; char *p, *q; if (!c) return 0; c &= 0xFF; if (c == '!') { if (*option_chars_move_whole_word == '!') return 2; return 0x80000000UL; } if (isupper (c)) c = 'A'; else if (islower (c)) c = 'a'; else if (isalpha (c)) c = 'a'; else if (isdigit (c)) c = '0'; else if (isspace (c)) c = ' '; q = strchr (option_chars_move_whole_word, c); if (!q) return 0xFFFFFFFFUL; do { for (x = 1, p = option_chars_move_whole_word; (unsigned long) p < (unsigned long) q; p++) if (*p == '!') x <<= 1; r |= x; } while ((q = strchr (q + 1, c))); return r;}void edit_left_word_move (WEdit * edit, int s){ for (;;) { int c1, c2; edit_cursor_move (edit, -1); if (!edit->curs1) break; c1 = edit_get_byte (edit, edit->curs1 - 1); c2 = edit_get_byte (edit, edit->curs1); if (!(my_type_of (c1) & my_type_of (c2))) break; if (isspace (c1) && !isspace (c2)) break; if (s) if (!isspace (c1) && isspace (c2)) break; }}static void edit_left_word_move_cmd (WEdit * edit){ edit_left_word_move (edit, 0); edit->force |= REDRAW_PAGE;}void edit_right_word_move (WEdit * edit, int s){ for (;;) { int c1, c2; edit_cursor_move (edit, 1); if (edit->curs1 >= edit->last_byte) break; c1 = edit_get_byte (edit, edit->curs1 - 1); c2 = edit_get_byte (edit, edit->curs1); if (!(my_type_of (c1) & my_type_of (c2))) break; if (isspace (c1) && !isspace (c2)) break; if (s) if (!isspace (c1) && isspace (c2)) break; }}static void edit_right_word_move_cmd (WEdit * edit){ edit_right_word_move (edit, 0); edit->force |= REDRAW_PAGE;}static void edit_right_delete_word (WEdit * edit){ int c1, c2; for (;;) { if (edit->curs1 >= edit->last_byte) break; c1 = edit_delete_wide (edit); c2 = edit_get_byte (edit, edit->curs1); if ((wc_isspace (c1) == 0) != (isspace (c2) == 0)) break; if (!(my_type_of (c1) & my_type_of (c2))) break; }}static void edit_left_delete_word (WEdit * edit){ int c1, c2; for (;;) { if (edit->curs1 <= 0) break; c1 = edit_backspace_wide (edit); c2 = edit_get_byte (edit, edit->curs1 - 1); if ((wc_isspace (c1) == 0) != (isspace (c2) == 0)) break; if (!(my_type_of (c1) & my_type_of (c2))) break; }}extern int column_highlighting;/* the start column position is not recorded, and hence does not undo as it happed. But who would notice. */void edit_do_undo (WEdit * edit){ long ac; long count = 0; push_action_disabled = 1; /* don't record undo's onto undo stack! */ while ((ac = pop_action (edit)) < KEY_PRESS) { switch ((int) ac) { case STACK_BOTTOM: goto done_undo; case CURS_RIGHT: edit_cursor_move (edit, 1); break; case CURS_LEFT: edit_cursor_move (edit, -1); break; case BACKSPACE: edit_backspace (edit); break; case DELETE: edit_delete (edit); break; case COLUMN_ON: column_highlighting = 1; break; case COLUMN_OFF: column_highlighting = 0; break; } if (ac >= 256 && ac < 512) edit_insert_ahead (edit, ac - 256); if (ac >= 0 && ac < 256) edit_insert (edit, ac); if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) { edit->mark1 = ac - MARK_1; edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1); } else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) { edit->mark2 = ac - MARK_2; edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2); } if (count++) edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ } if (edit->start_display > ac - KEY_PRESS) { edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display); edit->force |= REDRAW_PAGE; } else if (edit->start_display < ac - KEY_PRESS) { edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS); edit->force |= REDRAW_PAGE; } edit->start_display = ac - KEY_PRESS; /* see push and pop above */ edit_update_curs_row (edit); done_undo:; push_action_disabled = 0;}static void edit_delete_to_line_end (WEdit * edit){ for (;;) { if (edit_get_byte (edit, edit->curs1) == '\n') break; if (!edit->curs2) break; edit_delete (edit); }}static void edit_delete_to_line_begin (WEdit * edit){ for (;;) { if (edit_get_byte (edit, edit->curs1 - 1) == '\n') break; if (!edit->curs1) break; edit_backspace (edit); }}void edit_delete_line (WEdit * edit){ int c; do { c = edit_delete (edit); } while (c != '\n' && c); do { c = edit_backspace (edit); } while (c != '\n' && c); if (c) edit_insert (edit, '\n');}static void insert_spaces_tab (WEdit * edit, int half){ int i; edit_update_curs_col (edit); i = ((edit->curs_col / (option_tab_spacing * space_width / (half + 1))) + 1) * (option_tab_spacing * space_width / (half + 1)) - edit->curs_col; while (i > 0) { edit_insert (edit, ' '); i -= space_width; }}static int is_aligned_on_a_tab (WEdit * edit){ edit_update_curs_col (edit); if ((edit->curs_col % (TAB_SIZE * space_width)) && edit->curs_col % (TAB_SIZE * space_width) != (HALF_TAB_SIZE * space_width)) return 0; /* not alligned on a tab */ return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -