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

📄 zped.c

📁 这是我写的一个仿照linux下编辑器vim写的一个简单的全屏文本编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <ctype.h>
#include <locale.h>
#include <limits.h>
#include <assert.h>
#include <termios.h>
#include <term.h>
#include <curses.h>

#include "zped.h"
#include "myExternal.h"

struct termios oldterm;		/*The user's original term settings*/

/*Add one char to the buffer*/
void do_char(int ch)
{
    add_one(ch);
    //update_line(cursor_y,current_R);
    //wrefresh(edit);
}



/*Delect one char in the buffer*/
void dele_char()
{
	dele_one();
	//update_line(cursor_y,current_R);
	//wrefresh(edit);
}



/*Do some initialization of the global variables*/
void global_ini()
{
	filename = 0;
	editwinrows = 0;
	totalLine = 1;
	current_x = 0;
	current_y = 0;
	cursor_y = 0;
	move_x = 0;
	change = 0;
	current_R = (Rnode *)malloc(sizeof(Rnode));
	current_R->pre = 0;
	current_R->next = 0;
	current_R->num = 0;
	current_R->rowHead = 0;
	fileTop = current_R;
	fileBot = current_R;
	editTop = current_R;
	buffer = 0;
	searchTarget[0] = 0;
	searchCount = 0;
}


/*Show the error message.*/
void showErrorM(char * message)
{
     /* Restore the old term settings */
    tcsetattr(0, TCSANOW, &oldterm);

    clear();
    refresh();
    resetty();
    endwin();

    if(message != 0)
	fprintf(stderr, message);
    exit(1);
}



/*Do the initialzation of the windows(the edit window,the bottom window and the middle window)*/
void window_ini()
{
    //int i = 0;
    char message[] = "The window is too small, please make it larger";
    if((editwinrows = LINES - 2) < MIN_EDITOR_ROWS)
	showErrorM(message);
    /* Setup the main text window */
    edit = newwin(editwinrows, COLS, 0, 0);
    /* Setup the middle window*/
    midwin = newwin(1,COLS,LINES - 2,0);
    /* Setup the bottom window*/
    botwin = newwin(1,COLS,LINES -1,0);
    keypad(edit, TRUE);
    keypad(botwin,TRUE);
    keypad(midwin,TRUE);
}




/*When leaving the editor or wanting to edit another file,
the buffer must to be destroy and the resource will be free.*/
bool destroyStruct()
{
	Rnode * Rtemp;
	Rnode * Rnext;
	Cnode * Ctemp;
	Cnode * Cnext;
	Rtemp = fileTop;
	if(Rtemp->next == 0) {
		if(Rtemp ->rowHead == 0) {
			free(Rtemp);
		} else {
			Ctemp = Rtemp->rowHead;
			Cnext = Ctemp->next;
			while(Cnext) {
				free(Ctemp);
				Ctemp = Cnext;
				Cnext = Cnext->next;
			}
			free(Ctemp);
		}
	} else {
		Rnext = Rtemp->next;
		while(Rnext) {
			if(Rtemp->rowHead == 0) {
				free(Rtemp);
			} else {
				Ctemp = Rtemp->rowHead;
				Cnext = Ctemp->next;
				while(Cnext) {
					free(Ctemp);
					Ctemp = Cnext;
					Cnext = Cnext->next;
				}
				free(Ctemp);
			}
			free(Rtemp);
			Rtemp = Rnext;
			Rnext = Rnext->next;
		}
		if(Rtemp ->rowHead == 0) {
			free(Rtemp);
		} else {
			Ctemp = Rtemp->rowHead;
			Cnext = Ctemp->next;
			while(Cnext) {
				free(Ctemp);
				Ctemp = Cnext;
				Cnext = Cnext->next;
			}
			free(Ctemp);
		}
	}
	return 1;
}




/*When leaving the editor ,some properties of the term 
will be returned to original condtion.*/
void finish()
{
    //wattroff(midwin,A_REVERSE);
    keypad(edit, TRUE);
    nocbreak();
    nl();
    echo();
    endwin();
    noraw();

    /* Restore the old term settings */
    tcsetattr(0, TCSANOW, &oldterm);

    exit(0);
}

bool allow_input(int ch) 
{
	switch(ch) {
	case '`':case '@':case '#':case '$':
	case '~':case '%':case '^':case '&':
	case '!':case '*':case '(':case ')':
	case '-':case '_':case '+':case '=':
	case '\\':case '|':case '{':case '}':
	case '[':case ']':case '\'':case '"':
	case ',':case '<':case '.':case '>':
	case ';':case ':':case '/':case '?':
	case ' ':case '\n':case FKEY_ENTER:
		return true;
		break;
	default:
		if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
			return true;
		else 
			return false;
		break;
	}
	return false;
}


/*This function will handle the commands which can be seem in
the bottom window.There are many kinds of the commands such as
open file,new one file,save a file,search a string,replace a
string,and so on.*/
bool handleCom(int key, char * pathName)
{
	int count = 1;
	int kbinput;
	int i = 0;
	int j =0;
	int replaceCount = 0;
	int n = 0;
	long gotoline = 0;
	char temp[MAXSIZE];
	char command[MAXSIZE];
	char replaceWord[MAXSIZE];
	char searchNotFind[] = "The word is not found.";
	char writeFileFail[] = "The file can not be written.";
	char writeFileSuccess[] = "The file has been written.";
	char pathNeeded[] = "Please enter a valid path.";
	char writeNeeded[] = "No write since last change.";
	char fileNotFind[] = " was not found.";
	char replace[] = "Mition complete.";
	int charNum = 1;
	int icurrent_x = 1;

	command[0] = 0;
	replaceWord[0] = 0;
	wclear(botwin);
	mvwaddch(botwin,0,0,key);
	wrefresh(botwin);
	/*Store the command into the array,and show it at the bottow
	window.*/
	temp[0] = key;
	while((kbinput = wgetch(botwin)) != FKEY_ENTER) {
		if(kbinput == FKEY_ESC) {
			wclear(botwin);
			wrefresh(botwin);
			wrefresh(edit);
			return 0;
		} else if(kbinput == KEY_BACKSPACE) {
			//here delect char
			if(icurrent_x > 0) {
				memmove(&temp[icurrent_x],&temp[icurrent_x+1],charNum-icurrent_x);
				charNum--;
				icurrent_x--;
				temp[charNum] = '\0';
				wclear(botwin);
				wprintw(botwin,"%s",temp);
				wmove(botwin,0,icurrent_x);
			}
		} else if(kbinput == KEY_LEFT) {
			if(icurrent_x > 0) {
				icurrent_x--;
				wmove(botwin,0,icurrent_x);
			}
		} else if(kbinput == KEY_RIGHT) {
			if(icurrent_x < charNum) {
				icurrent_x++;
				wmove(botwin,0,icurrent_x);
			}
		} else if(kbinput == KEY_HOME) {
			icurrent_x = 0;
			wmove(botwin,0,icurrent_x);
		} else if(kbinput == KEY_END) {
			icurrent_x = charNum;
			wmove(botwin,0,icurrent_x);
		} else {
			//here add char 
			if(allow_input(kbinput)) {
				memmove(&temp[icurrent_x+1],&temp[icurrent_x],charNum-icurrent_x);
				charNum++;
				temp[icurrent_x] = kbinput;
				temp[charNum] = '\0';
				wclear(botwin);
				wprintw(botwin,"%s",temp);
				icurrent_x++;
				wmove(botwin,0,icurrent_x);
			}
		}
	}
	/*':'means the follow command are save,new file,edit another file,
	replace or quit*/
	if(temp[0] == ':') {
		/*'w'means "write" the buffer to the file*/
		if(temp[1] == 'w') {
			if(pathName[0] == 0) {
				/*If there is no file name the editor will give it the name "a.out"*/
				strcpy(command,"a.out");
				if(!writeOneFile(command)) {
					wclear(botwin);
					wprintw(botwin,"%s",writeFileFail);
					wrefresh(botwin);
					wrefresh(edit);
					return 0;
				} else {
					wclear(botwin);
					wprintw(botwin,"%s",writeFileSuccess);
					wrefresh(botwin);
					wrefresh(edit);
					change = 0;
					midwinBarUpdate(command);
				}
			} else {
				if(!writeOneFile(pathName)) {
					wclear(botwin);
					wprintw(botwin,"%s",writeFileFail);
					wrefresh(botwin);
					wrefresh(edit);
					return 0;
				} else {
					wclear(botwin);
					wprintw(botwin,"%s",writeFileSuccess);
					wrefresh(botwin);
					wrefresh(edit);
					change = 0;
					midwinBarUpdate(pathName);
				}
			}
		    /*'s' means "save as",s follows a path and its name*/
		} else if(temp[1] == 's') {
			sscanf(temp,":s %s",command);
			if(command[0] == 0) {
				wclear(botwin);
				wprintw(botwin,"%s",pathNeeded);
				wrefresh(botwin);
				wrefresh(edit);
				return 0;
			} else {
				if(!writeOneFile(command)) {
					wclear(botwin);
					wprintw(botwin,"%s",writeFileFail);
					wrefresh(botwin);
					wrefresh(edit);
					return 0;
				} else {
					strcpy(pathName,command);
					wclear(botwin);
					wprintw(botwin,"%s",writeFileSuccess);
					wrefresh(botwin);
					wrefresh(edit);
					change = 0;
					midwinBarUpdate(pathName);
				}
			}
		    /*'e' means "edit",e follows the path and its name of the file
		    which user want to edit*/
		} else if(temp[1] == 'e') {
			sscanf(temp,":e %s",command);
			if(change) {
				wclear(botwin);
				wprintw(botwin,"%s",writeNeeded);
				wrefresh(botwin);
			} else {
				destroyStruct();
				global_ini();
				if(readOneFile(command)) {
					edit_refresh();
					strcpy(pathName,command);
					midwinBarUpdate(pathName);
				} else {
					strcat(command,fileNotFind);
					wclear(botwin);
					wprintw(botwin,"%s",command);
					wrefresh(botwin);
				}
			}
		    /*'q' means quit*/
		} else if(temp[1] == 'q') {
			    /*q follows a '!' means to abandon the change to the file*/
			if(temp[2] == '!') {
				destroyStruct();
				finish();
			} else {
				if(change) {
					wclear(botwin);
					wprintw(botwin,"%s",writeNeeded);
					wrefresh(botwin);
					wrefresh(edit);
				} else {
					destroyStruct();
					finish();
				}
			}
		    /*'r' means replace*/
		} else if(temp[1] == 'r') {
			    /*r follows a '%' means to replace the string with another
			    in the whole file*/
			if(temp[2] == '%')
				i = 3;
			    /*If there is no '%' after the r means to replace the string 
			    with another in the current line.*/
			else
				i = 2;
			for(; temp[i] && (temp[i] == ' ' || temp[i] == '\t'); i++);
			j = 0;
			for(; temp[i] && (temp[i] != ' ' && temp[i] != '\t'); i++)
				searchTarget[j++] = temp[i];
			searchCount = j;
			if(searchCount == 0)
				searchTarget[0] = 0;
			for(; temp[i] && (temp[i] == ' ' || temp[i] == '\t'); i++);
			j = 0;
			for(;temp[i] && (temp[i] != ' ' && temp[i] != '\t'); i++)
				replaceWord[j++] = temp[i];
			replaceCount = j;
			if(replaceCount == 0)
				replaceWord[0] = 0;
			if(temp[2] == '%') {
				if(replace_below(replaceWord,replaceCount)) {
					wclear(botwin);
					wprintw(botwin,"%s",replace);
					wrefresh(botwin);
					edit_refresh();
					change = 1;
					midwinBarUpdate(pathName);
				} else {
					wclear(botwin);
					wprintw(botwin,"%s",searchNotFind);
					wrefresh(botwin);
					wrefresh(edit);
				}
			} else {
				if(replace_line(replaceWord,replaceCount)) {
					wclear(botwin);
					wprintw(botwin,"%s",replace);
					wrefresh(botwin);
					update_line(cursor_y,current_R);
					change = 1;
					midwinBarUpdate(pathName);
				} else {
					wclear(botwin);
					wprintw(botwin,"%s",searchNotFind);
					wrefresh(botwin);
					wrefresh(edit);
				}
			}
		    /*To new one file.*/
		} else if(strcmp(temp,":new") == 0) {
			if(change) {
				wclear(botwin);
				wprintw(botwin,"%s",writeNeeded);
				wrefresh(botwin);
				wrefresh(edit);
			} else {
				destroyStruct();
				global_ini();
				pathName[0] = 0;
				wclear(botwin);
				wrefresh(botwin);
				midwinBarUpdate(pathName);
				edit_refresh();
			}
		}
	    /*To search a string forwards*/
	} else if(temp[0] == '/') {
		searchInit();
		strcpy(searchTarget,&temp[1]);
		searchCount = charNum-1;
		if(search_down()) {
			current_R = searchRow;
			current_x = search_x - charNum + 1;

⌨️ 快捷键说明

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