edit.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,280 行 · 第 1/5 页
C
2,280 行
for (;; current--)
#if 0
if (current == 0 || edit_get_byte (edit, current - 1) == '\n')
#else
if (edit_get_byte (edit, current - 1) == '\n')
#endif
break;
} else
return 0;
return current;
}
int edit_count_lines (WEdit * edit, long current, int upto)
{
int lines = 0;
if (upto > edit->last_byte)
upto = edit->last_byte;
if (current < 0)
current = 0;
while (current < upto)
if (edit_get_byte (edit, current++) == '\n')
lines++;
return lines;
}
/* If lines is zero this returns the count of lines from current to upto. */
/* If upto is zero returns index of lines forward current. */
long edit_move_forward (WEdit * edit, long current, int lines, long upto)
{
if (upto) {
return edit_count_lines (edit, current, upto);
} else {
int next;
if (lines < 0)
lines = 0;
while (lines--) {
next = edit_eol (edit, current) + 1;
if (next > edit->last_byte)
break;
else
current = next;
}
return current;
}
}
/* Returns offset of 'lines' lines up from current */
long edit_move_backward (WEdit * edit, long current, int lines)
{
if (lines < 0)
lines = 0;
current = edit_bol (edit, current);
while((lines--) && current != 0)
current = edit_bol (edit, current - 1);
return current;
}
#ifdef MIDNIGHT
/* If cols is zero this returns the count of columns from current to upto. */
/* If upto is zero returns index of cols across from current. */
long edit_move_forward3 (WEdit * edit, long current, int cols, long upto)
{
long p, q;
int col = 0;
if (upto) {
q = upto;
cols = -10;
} else
q = edit->last_byte + 2;
for (col = 0, p = current; p < q; p++) {
int c;
if (cols != -10) {
if (col == cols)
return p;
if (col > cols)
return p - 1;
}
c = edit_get_byte (edit, p);
if (c == '\r')
continue;
else
if (c == '\t')
col += TAB_SIZE - col % TAB_SIZE;
else
col++;
/*if(edit->nroff ... */
if (c == '\n') {
if (upto)
return col;
else
return p;
}
}
return (float) col;
}
#endif
/* returns the current column position of the cursor */
int edit_get_col (WEdit * edit)
{
return edit_move_forward3 (edit, edit_bol (edit, edit->curs1), 0, edit->curs1);
}
/* Scrolling functions */
void edit_update_curs_row (WEdit * edit)
{
edit->curs_row = edit->curs_line - edit->start_line;
}
void edit_update_curs_col (WEdit * edit)
{
edit->curs_col = edit_move_forward3(edit, edit_bol(edit, edit->curs1), 0, edit->curs1);
}
/*moves the display start position up by i lines */
void edit_scroll_upward (WEdit * edit, unsigned long i)
{
int lines_above = edit->start_line;
if (i > lines_above)
i = lines_above;
if (i) {
edit->start_line -= i;
edit->start_display = edit_move_backward (edit, edit->start_display, i);
edit->force |= REDRAW_PAGE;
edit->force &= (0xfff - REDRAW_CHAR_ONLY);
}
edit_update_curs_row(edit);
}
/* returns 1 if could scroll, 0 otherwise */
void edit_scroll_downward (WEdit * edit, int i)
{
int lines_below;
lines_below = edit->total_lines - edit->start_line - (edit->num_widget_lines - 1);
if (lines_below > 0) {
if (i > lines_below)
i = lines_below;
edit->start_line += i;
edit->start_display = edit_move_forward (edit, edit->start_display, i, 0);
edit->force |= REDRAW_PAGE;
edit->force &= (0xfff - REDRAW_CHAR_ONLY);
}
edit_update_curs_row(edit);
}
void edit_scroll_right (WEdit * edit, int i)
{
edit->force |= REDRAW_PAGE;
edit->force &= (0xfff - REDRAW_CHAR_ONLY);
edit->start_col -= i;
}
void edit_scroll_left (WEdit * edit, int i)
{
if (edit->start_col) {
edit->start_col += i;
if (edit->start_col > 0)
edit->start_col = 0;
edit->force |= REDRAW_PAGE;
edit->force &= (0xfff - REDRAW_CHAR_ONLY);
}
}
/* high level cursor movement commands */
static int is_in_indent (WEdit *edit)
{
long p = edit_bol (edit, edit->curs1);
while (p < edit->curs1)
if (!strchr (" \t", edit_get_byte (edit, p++)))
return 0;
return 1;
}
static int left_of_four_spaces (WEdit *edit);
static void edit_move_to_prev_col (WEdit * edit, long p)
{
edit_cursor_move (edit, edit_move_forward3 (edit, p, edit->prev_col, 0) - edit->curs1);
if (is_in_indent (edit) && option_fake_half_tabs) {
edit_update_curs_col (edit);
if (edit->curs_col % (HALF_TAB_SIZE * space_width)) {
int q = edit->curs_col;
edit->curs_col -= (edit->curs_col % (HALF_TAB_SIZE * space_width));
p = edit_bol (edit, edit->curs1);
edit_cursor_move (edit, edit_move_forward3 (edit, p, edit->curs_col, 0) - edit->curs1);
if (!left_of_four_spaces (edit))
edit_cursor_move (edit, edit_move_forward3 (edit, p, q, 0) - edit->curs1);
}
}
}
/* move i lines */
static void edit_move_up (WEdit * edit, unsigned long i, int scroll)
{
long p, l = edit->curs_line;
if (i > l)
i = l;
if (i) {
if (i > 1)
edit->force |= REDRAW_PAGE;
if (scroll)
edit_scroll_upward (edit, i);
p = edit_bol (edit, edit->curs1);
edit_cursor_move (edit, (p = edit_move_backward (edit, p, i)) - edit->curs1);
edit_move_to_prev_col (edit, p);
edit->search_start = edit->curs1;
edit->found_len = 0;
}
}
int is_blank (WEdit * edit, long offset)
{
long s, f;
int c;
s = edit_bol (edit, offset);
f = edit_eol (edit, offset) - 1;
while (s <= f) {
c = edit_get_byte (edit, s++);
if ((c > ' ' && c <= '~') || c >= 160) /* non-printables on a line are considered "blank" */
return 0;
}
return 1;
}
int line_is_blank (WEdit * edit, long line)
{
static long p = -1, l = 0;
if (p == -1 || abs (l - line) > abs (edit->curs_line - line)) {
l = edit->curs_line;
p = edit->curs1;
}
if (line < l)
p = edit_move_backward (edit, p, l - line);
else if (line > l)
p = edit_move_forward (edit, p, line - l, 0);
l = line;
return is_blank (edit, p);
}
/* 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 */
static 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.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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?