📄 zped.c
字号:
#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 + -