edit.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,280 行 · 第 1/5 页
C
2,280 行
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);
}
}
int my_type_of (int c)
{
if (c < ' ' && c > 0)
return 1;
if (strchr ("+_-.", c))
if (strchr (option_whole_chars_move, c))
return 3;
if (!strcasechr (option_whole_chars_move, c))
return 2;
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 160)
return 3;
return c;
}
void edit_left_word_move (WEdit * edit)
{
do {
edit_cursor_move (edit, -1);
if (!edit->curs1)
break;
} while (my_type_of (edit_get_byte (edit, edit->curs1))
==
my_type_of (edit_get_byte (edit, edit->curs1 - 1)));
}
static void edit_left_word_move_cmd (WEdit * edit)
{
edit_left_word_move (edit);
if (strchr (option_whole_chars_move, ' '))
if (strchr ("\t ", edit_get_byte (edit, edit->curs1)))
edit_left_word_move (edit);
edit->force |= REDRAW_PAGE;
}
void edit_right_word_move (WEdit * edit)
{
do {
edit_cursor_move (edit, 1);
if (edit->curs1 >= edit->last_byte)
break;
} while (my_type_of (edit_get_byte (edit, edit->curs1 - 1))
==
my_type_of (edit_get_byte (edit, edit->curs1)));
}
static void edit_right_word_move_cmd (WEdit * edit)
{
edit_right_word_move (edit);
if (strchr (option_whole_chars_move, ' '))
if (strchr ("\t ", edit_get_byte (edit, edit->curs1)))
edit_right_word_move (edit);
edit->force |= REDRAW_PAGE;
}
static void edit_right_delete_word (WEdit * edit)
{
int c;
do {
c = edit_delete (edit);
} while (my_type_of (c) == my_type_of (edit_get_byte (edit, edit->curs1)));
}
static void edit_left_delete_word (WEdit * edit)
{
int c;
do {
c = edit_backspace (edit);
} while (my_type_of (c) == my_type_of (edit_get_byte (edit, edit->curs1 - 1)));
}
/*
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;
}
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;
} else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) {
edit->mark2 = ac - MARK_2;
}
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);
}
}
static 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 i = option_tab_spacing;
while (i--)
edit_insert (edit, ' ');
}
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;
}
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--)
edit_insert (edit, ' ');
}
static void edit_auto_indent (WEdit * edit, int always)
{
long p;
int indent;
p = edit->curs1;
while (strchr ("\t\n\r ", 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)
indent = edit->curs_col;
edit_insert_indent (edit, indent);
}
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');
}
static 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 (right_of_four_spaces (edit)) {
for (i = 1; i <= HALF_TAB_SIZE; i++)
edit_backspace (edit);
if (option_fill_tabs_with_spaces) {
insert_spaces_tab (edit);
} else {
edit_insert (edit, '\t');
}
} else {
for (i = 1; i <= HALF_TAB_SIZE; i++)
edit_insert (edit, ' ');
}
return;
}
}
if (option_fill_tabs_with_spaces) {
insert_spaces_tab (edit);
} 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)
#else
if (edit->curs_col < option_word_wrap_line_length * FONT_MEAN_WIDTH)
#endif
return;
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, int char_for_insertion);
#ifdef MIDNIGHT
int edit_translate_key (WEdit * edit, unsigned int x_keycode, long x_key, int x_state, int *cmd, int *ch)
{
int command = -1;
int 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;
}
#endif
void 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 */
void edit_find_bracket (WEdit * edit)
{
if (option_find_bracket) {
const char *b = "{}{[][()(", *p;
static int last_bracket = -1;
int i = 1, a, inc = -1, c, d, n = 0, j = 0;
long q;
edit->bracket = -1;
c = edit_get_byte (edit, edit->curs1);
p = strchr (b, c);
edit_update_curs_row (edit);
if (p) {
d = p[1];
if (strchr ("{[(", c))
inc = 1;
for (q = edit->curs1 + inc;; q += inc) {
if (q >= edit->last_byte || q < edit->start_display || j++ > 10000)
break;
a = edit_get_byte (edit, q);
if (inc > 0 && a == '\n')
n++;
if (n >= edit->num_widget_lines - edit->curs_row) /* out of screen */
break;
i += (a == c) - (a == d);
if (!i) {
edit->bracket = q;
break;
}
}
}
if (last_bracket != edit->bracket)
edit->force |= REDRAW_PAGE;
last_bracket = edit->bracket;
}
}
/* 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, int 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);
return r;
}
#ifdef MIDNIGHT
static const char *shell_cmd[] = SHELL_COMMANDS_i
#else
static void (*user_commamd) (WEdit *, int) = 0;
void edit_set_user_command (void (*func) (WEdit *, int))
{
user_commamd = func;
}
#endif
void 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, int char_for_insertion)
{
int result = 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?