📄 edit.c
字号:
}static int right_of_four_spaces (WEdit *edit){ int i, ch = 0; for (i = 1; i <= HALF_TAB_SIZE; i++) ch |= edit_get_byte (edit, edit->curs1 - i); if (ch == ' ') return is_aligned_on_a_tab (edit); return 0;}static int left_of_four_spaces (WEdit *edit){ int i, ch = 0; for (i = 0; i < HALF_TAB_SIZE; i++) ch |= edit_get_byte (edit, edit->curs1 + i); if (ch == ' ') return is_aligned_on_a_tab (edit); return 0;}int edit_indent_width (WEdit * edit, long p){ long q = p; while (strchr ("\t ", edit_get_byte (edit, q)) && q < edit->last_byte - 1) /* move to the end of the leading whitespace of the line */ q++; return edit_move_forward3 (edit, p, 0, q); /* count the number of columns of indentation */}void edit_insert_indent (WEdit * edit, int indent){#ifndef MIDNIGHT indent /= space_width;#endif if (!option_fill_tabs_with_spaces) { while (indent >= TAB_SIZE) { edit_insert (edit, '\t'); indent -= TAB_SIZE; } } while (indent-- > 0) edit_insert (edit, ' ');}void edit_auto_indent (WEdit * edit, int extra, int no_advance){ long p; int indent; p = edit->curs1; while (isspace (edit_get_byte (edit, p - 1)) && p > 0) /* move back/up to a line with text */ p--; indent = edit_indent_width (edit, edit_bol (edit, p)); if (edit->curs_col < indent && no_advance) indent = edit->curs_col; edit_insert_indent (edit, indent + (option_fake_half_tabs ? HALF_TAB_SIZE : TAB_SIZE) * space_width * extra);}static void edit_double_newline (WEdit * edit){ edit_insert (edit, '\n'); if (edit_get_byte (edit, edit->curs1) == '\n') return; if (edit_get_byte (edit, edit->curs1 - 2) == '\n') return; edit->force |= REDRAW_PAGE; edit_insert (edit, '\n');}void edit_tab_cmd (WEdit * edit){ int i; if (option_fake_half_tabs) { if (is_in_indent (edit)) { /*insert a half tab (usually four spaces) unless there is a half tab already behind, then delete it and insert a full tab. */ if (!option_fill_tabs_with_spaces && right_of_four_spaces (edit)) { for (i = 1; i <= HALF_TAB_SIZE; i++) edit_backspace (edit); edit_insert (edit, '\t'); } else { insert_spaces_tab (edit, 1); } return; } } if (option_fill_tabs_with_spaces) { insert_spaces_tab (edit, 0); } else { edit_insert (edit, '\t'); } return;}void format_paragraph (WEdit * edit, int force);static void check_and_wrap_line (WEdit * edit){ int curs, c; if (!option_typewriter_wrap) return; edit_update_curs_col (edit);#ifdef MIDNIGHT if (edit->curs_col < option_word_wrap_line_length) return;#else CPushFont ("editor", 0); c = FONT_MEAN_WIDTH; CPopFont (); if (edit->curs_col < option_word_wrap_line_length * c) return;#endif curs = edit->curs1; for (;;) { curs--; c = edit_get_byte (edit, curs); if (c == '\n' || curs <= 0) { edit_insert (edit, '\n'); return; } if (c == ' ' || c == '\t') { int current = edit->curs1; edit_cursor_move (edit, curs - edit->curs1 + 1); edit_insert (edit, '\n'); edit_cursor_move (edit, current - edit->curs1 + 1); return; } }}void edit_execute_macro (WEdit * edit, struct macro macro[], int n);/* either command or char_for_insertion must be passed as -1 */int edit_execute_cmd (WEdit * edit, int command, long char_for_insertion);#ifdef MIDNIGHTint edit_translate_key (WEdit * edit, unsigned int x_keycode, long x_key, int x_state, int *cmd, long *ch){ int command = -1; long char_for_insertion = -1;#include "edit_key_translator.c" *cmd = command; *ch = char_for_insertion; if((command == -1 || command == 0) && char_for_insertion == -1) /* unchanged, key has no function here */ return 0; return 1;}#endifvoid edit_push_key_press (WEdit * edit){ edit_push_action (edit, KEY_PRESS + edit->start_display); if (edit->mark2 == -1) edit_push_action (edit, MARK_1 + edit->mark1);}/* this find the matching bracket in either direction, and sets edit->bracket */static long edit_get_bracket (WEdit * edit, int in_screen, unsigned long furthest_bracket_search){ const char *b = "{}{[][()(", *p; int i = 1, a, inc = -1, c, d, n = 0; unsigned long j = 0; long q; edit_update_curs_row (edit); c = edit_get_byte (edit, edit->curs1); p = strchr (b, c);/* no limit */ if (!furthest_bracket_search) furthest_bracket_search--;/* not on a bracket at all */ if (!p) return -1;/* the matching bracket */ d = p[1];/* going left or right? */ if (strchr ("{[(", c)) inc = 1; for (q = edit->curs1 + inc;; q += inc) {/* out of buffer? */ if (q >= edit->last_byte || q < 0) break; a = edit_get_byte (edit, q);/* don't want to eat CPU */ if (j++ > furthest_bracket_search) break;/* out of screen? */ if (in_screen) { if (q < edit->start_display) break;/* count lines if searching downward */ if (inc > 0 && a == '\n') if (n++ >= edit->num_widget_lines - edit->curs_row) /* out of screen */ break; }/* count bracket depth */ i += (a == c) - (a == d);/* return if bracket depth is zero */ if (!i) return q; }/* no match */ return -1;}static long last_bracket = -1;static void edit_find_bracket (WEdit * edit){ if (option_find_bracket) { edit->bracket = edit_get_bracket (edit, 1, 10000); if (last_bracket != edit->bracket) edit->force |= REDRAW_PAGE; last_bracket = edit->bracket; }}static void edit_goto_matching_bracket (WEdit *edit){ long q; q = edit_get_bracket (edit, 0, 0); if (q < 0) return; edit->bracket = edit->curs1; edit->force |= REDRAW_PAGE; edit_cursor_move (edit, q - edit->curs1);}/* this executes a command as though the user initiated it through a key press. *//* callback with WIDGET_KEY as a message calls this after translating the key press *//* this can be used to pass any command to the editor. Same as sendevent with msg = WIDGET_COMMAND and par = command except the screen wouldn't update *//* one of command or char_for_insertion must be passed as -1 *//* commands are executed, and char_for_insertion is inserted at the cursor *//* returns 0 if the command is a macro that was not found, 1 otherwise */int edit_execute_key_command (WEdit * edit, int command, long char_for_insertion){ int r; if (command == CK_Begin_Record_Macro) { edit->macro_i = 0; edit->force |= REDRAW_CHAR_ONLY | REDRAW_LINE; return command; } if (command == CK_End_Record_Macro && edit->macro_i != -1) { edit->force |= REDRAW_COMPLETELY; edit_save_macro_cmd (edit, edit->macro, edit->macro_i); edit->macro_i = -1; return command; } if (edit->macro_i >= 0 && edit->macro_i < MAX_MACRO_LENGTH - 1) { edit->macro[edit->macro_i].command = command; edit->macro[edit->macro_i++].ch = char_for_insertion; }/* record the beginning of a set of editing actions initiated by a key press */ if (command != CK_Undo) edit_push_key_press (edit); r = edit_execute_cmd (edit, command, char_for_insertion);#ifdef GTK if (edit->stopped && edit->widget->destroy_me) { (*edit->widget->destroy_me) (edit->widget->destroy_me_user_data); return 0; }#endif if (column_highlighting) edit->force |= REDRAW_PAGE; return r;}#ifdef MIDNIGHTstatic const char *shell_cmd[] = SHELL_COMMANDS_i#elsestatic void (*user_commamd) (WEdit *, int) = 0;void edit_set_user_command (void (*func) (WEdit *, int)){ user_commamd = func;}#endifvoid edit_mail_dialog (WEdit * edit);/* This executes a command at a lower level than macro recording. It also does not push a key_press onto the undo stack. This means that if it is called many times, a single undo command will undo all of them. It also does not check for the Undo command. Returns 0 if the command is a macro that was not found, 1 otherwise. */int edit_execute_cmd (WEdit * edit, int command, long char_for_insertion){ int result = 1; edit->force |= REDRAW_LINE; if (edit->found_len || column_highlighting)/* the next key press will unhighlight the found string, so update whole page */ edit->force |= REDRAW_PAGE; if (command / 100 == 6) { /* a highlight command like shift-arrow */ column_highlighting = 0; if (!edit->highlight || (edit->mark2 != -1 && edit->mark1 != edit->mark2)) { edit_mark_cmd (edit, 1); /* clear */ edit_mark_cmd (edit, 0); /* marking on */ } edit->highlight = 1; } else { /* any other command */ if (edit->highlight) edit_mark_cmd (edit, 0); /* clear */ edit->highlight = 0; }/* first check for undo */ if (command == CK_Undo) { edit_do_undo (edit); edit->found_len = 0; edit->prev_col = edit_get_col (edit); edit->search_start = edit->curs1; return 1; }/* An ordinary key press */ if (char_for_insertion >= 0) { long start_mark, end_mark; if (option_typing_replaces_selection && !eval_marks (edit, &start_mark, &end_mark)) { edit_block_delete (edit); } else if (edit->overwrite) { if (edit_get_byte (edit, edit->curs1) != '\n') edit_delete_wide (edit); } edit_insert_wide (edit, char_for_insertion); if (option_auto_para_formatting) { format_paragraph (edit, 0); edit->force |= REDRAW_PAGE; } else check_and_wrap_line (edit); edit->found_len = 0; edit->prev_col = edit_get_col (edit); edit->search_start = edit->curs1; edit_find_bracket (edit); edit_check_spelling (edit); return 1; } switch (command) { case CK_Begin_Page: case CK_End_Page: case CK_Begin_Page_Highlight: case CK_End_Page_Highlight: case CK_Word_Left: case CK_Word_Right: case CK_Up: case CK_Down: case CK_Word_Left_Highlight: case CK_Word_Right_Highlight: case CK_Up_Highlight: case CK_Down_Highlight: if (edit->mark2 == -1) break; /*marking is following the cursor: may need to highlight a whole line */ case CK_Left: case CK_Right: case CK_Left_Highlight: case CK_Right_Highlight: edit->force |= REDRAW_CHAR_ONLY; }/* basic cursor key commands */ switch (command) { long start_mark, end_mark; case CK_BackSpace: if (option_typing_replaces_selection && !eval_marks (edit, &start_mark, &end_mark)) { edit_block_delete (edit); break; } if (option_backspace_through_tabs && is_in_indent (edit)) { while (edit_get_byte (edit, edit->curs1 - 1) != '\n' && edit->curs1 > 0) edit_backspace (edit); break; } else { if (is_in_indent (edit)) { edit_backspace_tab (edit, 0); break; } } edit_backspace_wide (edit); break; case CK_Delete: if (option_typing_replaces_selection && !eval_marks (edit, &start_mark, &end_mark)) { edit_block_delete (edit); break; } if (option_fake_half_tabs) { int i; if (is_in_indent (edit) && left_of_four_spaces (edit)) { for (i = 1; i <= HALF_TAB_SIZE; i++) edit_delete (edit); break; } } edit_delete_wide (edit); break; case CK_Delete_Word_Left: edit_left_delete_word (edit); break; case CK_Delete_Word_Right: edit_right_delete_word (edit); break; case CK_Delete_Line: edit_delete_line (edit); break; case CK_Delete_To_Line_End: edit_delete_to_line_end (edit); break; case CK_Delete_To_Line_Begin: edit_delete_to_line_begin (edit); break; case CK_Enter: if (option_auto_para_formatting) { edit_double_newline (edit); if (option_return_does_auto_indent) edit_auto_indent (edit, 0, 1); format_paragraph (edit, 0); } else if (option_return_does_auto_indent) { edit_insert (edit, '\n'); edit_auto_indent (edit, 0, 1); } else { edit_insert (edit, '\n'); } break; case CK_Return: edit_insert (edit, '\n'); break; case CK_Page_Up: case CK_Page_Up_Highlight: edit_move_up (edit, edit->num_widget_lines - 1, 1); break; case CK_Page_Down: case CK_Page_Down_Highlight: edit_move_down (edit, edit->num_widget_lines - 1, 1); break; case CK_Left: case CK_Left_Highlight: if (option_fake_half_tabs) { if (is_in_indent (edit) && right_of_four_spaces (edit)) { edit_cursor_move (edit, -HALF_TAB_SIZE); edit->force &= (0xFFF - REDRAW_CHAR_ONLY); break; } } edit_cursor_move (edit, -1); edit_wide_char_align_left (edit); break; case CK_Right: case CK_Right_Highlight: if (option_fake_half_tabs) { if (is_in_indent (edit) && left_of_four_spaces (edit)) { edit_cursor_move (edit, HALF_TAB_SIZE); edit->force &= (0xFFF - REDRAW_CHAR_ONLY); break; } } edit_cursor_move (edit, 1); break; case CK_Begin_Page: case CK_Begin_Page_Highlight: edit_begin_page (edit); break; case CK_End_Page: case CK_End_Page_Highlight: edit_end_page (edit); break; case CK_Word_Left: case CK_Word_Left_Highlight: edit_left_word_move_cmd (edit); break; case CK_Word_Right: case CK_Word_Right_Highlight: edit_right_word_move_cmd (edit); break; case CK_Up: case CK_Up_Highlight: edit_move_up (edit, 1, 0); break; case CK_Down: case CK_Down_Highlight: edit_move_down
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -