⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edit.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
    edit->stat.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;    edit->stat.st_uid = getuid ();    edit->stat.st_gid = getgid ();    edit->bracket = -1;    edit->last_get_mb_rule = -2;    if (!dir)	dir = "";    f = (char *) filename;    if (filename) {	f = catstrs (dir, filename, 0);	if (edit_file_is_open)	    if ((*edit_file_is_open) (f)) {		if (to_free)		    free (edit);		return 0;	    }    }    if (edit_find_filter (f) < 0) {#ifdef CR_LF_TRANSLATION	use_filter = 1;#endif	if (edit_open_file (edit, f, text, text_size)) {/* edit_load_file already gives an error message */	    if (to_free)		free (edit);	    return 0;	}    } else {	use_filter = 1;	if (edit_open_file (edit, 0, "", 0)) {	    if (to_free)		free (edit);	    return 0;	}    }    edit->force |= REDRAW_PAGE;    if (filename) {	filename = catstrs (dir, filename, 0);	edit_split_filename (edit, (char *) filename);    } else {	edit->filename = (char *) strdup ("");	edit->dir = (char *) strdup (dir);    }    edit->stack_size = START_STACK_SIZE;    edit->stack_size_mask = START_STACK_SIZE - 1;    edit->undo_stack = malloc ((edit->stack_size + 10) * sizeof (long));    edit->total_lines = edit_count_lines (edit, 0, edit->last_byte);    if (use_filter) {	struct stat st;	push_action_disabled = 1;	if (check_file_access (edit, filename, &st)) {	    edit_clean (edit);	    if (to_free)		free (edit);	    return 0;	}	edit->stat = st;	if (!edit_insert_file (edit, f)) {	    edit_clean (edit);	    if (to_free)		free (edit);	    return 0;	}/* FIXME: this should be an unmodification() function */	push_action_disabled = 0;    }    edit->modified = 0;    edit_load_syntax (edit, 0, 0);    {	int fg, bg;	edit_get_syntax_color (edit, -1, &fg, &bg);    }    return edit;}/* clear the edit struct, freeing everything in it. returns 1 on success */int edit_clean (WEdit * edit){    if (edit) {	int j = 0;	edit_free_syntax_rules (edit);	edit_get_wide_byte (edit, -1);	book_mark_flush (edit, -1);	for (; j <= MAXBUFF; j++) {	    if (edit->buffers1[j] != NULL)		free (edit->buffers1[j]);	    if (edit->buffers2[j] != NULL)		free (edit->buffers2[j]);	}	if (edit->undo_stack)	    free (edit->undo_stack);	if (edit->filename)	    free (edit->filename);	if (edit->dir)	    free (edit->dir);/* we don't want to clear the widget */	memset (&(edit->from_here), 0, (unsigned long) &(edit->to_here) - (unsigned long) &(edit->from_here));	return 1;    }    return 0;}/* returns 1 on success */int edit_renew (WEdit * edit){    int lines = edit->num_widget_lines;    int columns = edit->num_widget_columns;    char *dir;    if (edit->dir)	dir = (char *) strdup (edit->dir);    else	dir = 0;        edit_clean (edit);    if (!edit_init (edit, lines, columns, 0, "", dir, 0))	return 0;    return 1;}/* returns 1 on success, if returns 0, the edit struct would have been free'd */int edit_reload (WEdit * edit, const char *filename, const char *text, const char *dir, unsigned long text_size){    WEdit *e;    int lines = edit->num_widget_lines;    int columns = edit->num_widget_columns;    e = malloc (sizeof (WEdit));    memset (e, 0, sizeof (WEdit));    e->widget = edit->widget;    e->macro_i = -1;    if (!edit_init (e, lines, columns, filename, text, dir, text_size)) {	free (e);	return 0;    }    edit_clean (edit);    memcpy (edit, e, sizeof (WEdit));    free (e);    return 1;}/*   Recording stack for undo:   The following is an implementation of a compressed stack. Identical   pushes are recorded by a negative prefix indicating the number of times the   same char was pushed. This saves space for repeated curs-left or curs-right   delete etc.   eg:  pushed:       stored:   a   b             a   b            -3   b             b   c  -->       -4   c             c   c             d   c   d   If the stack long int is 0-255 it represents a normal insert (from a backspace),   256-512 is an insert ahead (from a delete), If it is betwen 600 and 700 it is one   of the cursor functions #define'd in edit.h. 1000 through 700'000'000 is to   set edit->mark1 position. 700'000'000 through 1400'000'000 is to set edit->mark2   position.   The only way the cursor moves or the buffer is changed is through the routines:   insert, backspace, insert_ahead, delete, and cursor_move.   These record the reverse undo movements onto the stack each time they are   called.   Each key press results in a set of actions (insert; delete ...). So each time   a key is pressed the current position of start_display is pushed as   KEY_PRESS + start_display. Then for undoing, we pop until we get to a number   over KEY_PRESS. We then assign this number less KEY_PRESS to start_display. So undo   tracks scrolling and key actions exactly. (KEY_PRESS is about (2^31) * (2/3) = 1400'000'000)*/void edit_push_action (WEdit * edit, long c,...){    unsigned long sp = edit->stack_pointer;    unsigned long spm1;    long *t;/* first enlarge the stack if necessary */    if (sp > edit->stack_size - 10) {	/* say */	if (option_max_undo < 256)	    option_max_undo = 256;	if (edit->stack_size < option_max_undo) {	    t = malloc ((edit->stack_size * 2 + 10) * sizeof (long));	    if (t) {		memcpy (t, edit->undo_stack, sizeof (long) * edit->stack_size);		free (edit->undo_stack);		edit->undo_stack = t;		edit->stack_size <<= 1;		edit->stack_size_mask = edit->stack_size - 1;	    }	}    }    spm1 = (edit->stack_pointer - 1) & edit->stack_size_mask;    if (push_action_disabled)	return;#ifdef FAST_MOVE_CURSOR    if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) {	va_list ap;	edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT;	edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask;	va_start (ap, c);	c = -(va_arg (ap, int));	va_end (ap);    } else#endif				/* ! FAST_MOVE_CURSOR */    if (spm1 != edit->stack_bottom && ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) {	int d;	if (edit->undo_stack[spm1] < 0) {	    d = edit->undo_stack[(sp - 2) & edit->stack_size_mask];	    if (d == c) {		if (edit->undo_stack[spm1] > -1000000000) {		    if (c < KEY_PRESS)	/* --> no need to push multiple do-nothings */			edit->undo_stack[spm1]--;		    return;		}	    }/* #define NO_STACK_CURSMOVE_ANIHILATION */#ifndef NO_STACK_CURSMOVE_ANIHILATION	    else if ((c == CURS_LEFT && d == CURS_RIGHT)		     || (c == CURS_RIGHT && d == CURS_LEFT)) {	/* a left then a right anihilate each other */		if (edit->undo_stack[spm1] == -2)		    edit->stack_pointer = spm1;		else		    edit->undo_stack[spm1]++;		return;	    }#endif	} else {	    d = edit->undo_stack[spm1];	    if (d == c) {		if (c >= KEY_PRESS)		    return;	/* --> no need to push multiple do-nothings */		edit->undo_stack[sp] = -2;		goto check_bottom;	    }#ifndef NO_STACK_CURSMOVE_ANIHILATION	    else if ((c == CURS_LEFT && d == CURS_RIGHT)		     || (c == CURS_RIGHT && d == CURS_LEFT)) {	/* a left then a right anihilate each other */		edit->stack_pointer = spm1;		return;	    }#endif	}    }    edit->undo_stack[sp] = c;  check_bottom:    edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask;/*if the sp wraps round and catches the stack_bottom then erase the first set of actions on the stack to make space - by moving stack_bottom forward one "key press" */    c = (edit->stack_pointer + 2) & edit->stack_size_mask;    if (c == edit->stack_bottom || ((c + 1) & edit->stack_size_mask) == edit->stack_bottom)	do {	    edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask;	} while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer);/*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */    if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS)	edit->stack_bottom = edit->stack_pointer = 0;}/*   TODO: if the user undos until the stack bottom, and the stack has not wrapped,   then the file should be as it was when he loaded up. Then set edit->modified to 0. */long pop_action (WEdit * edit){    long c;    unsigned long sp = edit->stack_pointer;    if (sp == edit->stack_bottom) {	return STACK_BOTTOM;    }    sp = (sp - 1) & edit->stack_size_mask;    if ((c = edit->undo_stack[sp]) >= 0) {/*	edit->undo_stack[sp] = '@'; */	edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask;	return c;    }    if (sp == edit->stack_bottom) {	return STACK_BOTTOM;    }    c = edit->undo_stack[(sp - 1) & edit->stack_size_mask];    if (edit->undo_stack[sp] == -2) {/*      edit->undo_stack[sp] = '@'; */	edit->stack_pointer = sp;    } else	edit->undo_stack[sp]++;    return c;}/* is called whenever a modification is made by one of the four routines below */static inline void edit_modification (WEdit * edit, long p){    edit->caches_valid = 0;    edit->modified = 1;    edit->screen_modified = 1;    if (edit->last_get_mb_rule > p - 1) {	edit->last_get_mb_rule = p - 1;	edit->mb_invalidate = 1;    }    if (edit->last_get_mb_rule > p - 1) {	edit->last_get_rule = p - 1;	edit->syntax_invalidate = 1;    }}/*   Basic low level single character buffer alterations and movements at the cursor.   Returns char passed over, inserted or removed. */void edit_insert (WEdit * edit, int c){/* check if file has grown to large */    if (edit->last_byte >= SIZE_LIMIT)	return;/* first we must update the position of the display window */    if (edit->curs1 < edit->start_display) {	edit->start_display++;	if (c == '\n')	    edit->start_line++;    }/* now we must update some info on the file and check if a redraw is required */    if (c == '\n') {	if (edit->book_mark)	    book_mark_inc (edit, edit->curs_line);	edit->curs_line++;	edit->total_lines++;	edit->force |= REDRAW_LINE_ABOVE | REDRAW_AFTER_CURSOR;    }/* tell that we've modified the file */    edit_modification (edit, edit->curs1);/* save the reverse command onto the undo stack */    edit_push_action (edit, BACKSPACE);/* update markers */    edit->mark1 += (edit->mark1 > edit->curs1);    edit->mark2 += (edit->mark2 > edit->curs1);/* add a new buffer if we've reached the end of the last one */    if (!(edit->curs1 & M_EDIT_BUF_SIZE))	edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = malloc (EDIT_BUF_SIZE);/* perfprm the insertion */    edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = (unsigned char) c;/* update file length */    edit->last_byte++;/* update cursor position */    edit->curs1++;}/* same as edit_insert and move left */void edit_insert_ahead (WEdit * edit, int c){    if (edit->last_byte >= SIZE_LIMIT)	return;    if (edit->curs1 < edit->start_display) {	edit->start_display++;	if (c == '\n')	    edit->start_line++;    }    if (c == '\n') {	if (edit->book_mark)	    book_mark_inc (edit, edit->curs_line);	edit->total_lines++;	edit->force |= REDRAW_AFTER_CURSOR;    }    edit_modification (edit, edit->curs1);    edit_push_action (edit, DELETE);    edit->mark1 += (edit->mark1 >= edit->curs1);    edit->mark2 += (edit->mark2 >= edit->curs1);    if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE))	edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = malloc (EDIT_BUF_SIZE);    edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c;    edit->last_byte++;    edit->curs2++;}int edit_delete (WEdit * edit){    int p;    if (!edit->curs2)	return 0;    edit->mark1 -= (edit->mark1 > edit->curs1);    edit->mark2 -= (edit->mark2 > edit->curs1);    p = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1];    if (!(edit->curs2 & M_EDIT_BUF_SIZE)) {	free (edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE]);	edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = NULL;    }    edit->last_byte--;    edit->curs2--;    if (p == '\n') {	if (edit->book_mark)	    book_mark_dec (edit, edit->curs_line);	edit->total_lines--;	edit->force |= REDRAW_AFTER_CURSOR;    }    edit_push_action (edit, p + 256);    if (edit->curs1 < edit->start_display) {	edit->start_display--;	if (p == '\n')	    edit->start_line--;    }    edit_modification (edit, edit->curs1);    return p;}int edit_backspace (WEdit * edit){    int p;    if (!edit->curs1)	return 0;    edit->mark1 -= (edit->mark1 >= edit->curs1);    edit->mark2 -= (edit->mark2 >= edit->curs1);    p = *(edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE] + ((edit->curs1 - 1) & M_EDIT_BUF_SIZE));    if (!((edit->curs1 - 1) & M_EDIT_BUF_SIZE)) {	free (edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]);	edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = NULL;    }    edit->last_byte--;    edit->curs1--;    if (p == '\n') {	if (edit->book_mark)	    book_mark_dec (edit, edit->curs_line);	edit->curs_line--;	edit->total_lines--;	edit->force |= REDRAW_AFTER_CURSOR;    }    edit_push_action (edit, p);    if (edit->curs1 < edit->start_display) {	edit->start_display--;	if (p == '\n')	    edit->start_line--;    }    edit_modification (edit, edit->curs1);    return p;}int edit_delete_wide (WEdit * edit){    struct mb_rule r;    r = get_mb_rule (edit, edit->curs1);    edit_delete (edit);    while (r.end--)	edit_delete (edit);    return r.ch;}extern int option_utf_interpretation;void edit_insert_wide (WEdit * edit, wchar_t wc){    unsigned char *c;    if (!option_utf_interpretation) {	edit_insert (edit, wc & 0xFF);	return;    }    c = wcrtomb_ucs4_to_utf8 (wc);    if (!*c) {	edit_insert (edit, *c);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -