📄 edit.c
字号:
#include "global.h"
/*c=a/b when the remainder is greater
* than one then c plus one*/
int up_round(int base,int cut)
{
int temp;
temp = base/cut;
if(base%cut)
temp++;
return temp;
}
/*add one colum node*/
ecnode * add_cnode(ecnode * target)
{
ecnode * temp = NULL;
if((temp=(ecnode *)malloc(sizeof(ecnode))) == NULL)
return (ecnode *)0;
if(target == NULL) {
temp->next = current_row->chead;
temp->pre = NULL;
current_row->chead = temp;
} else if(target->next == NULL) {
target->next = temp;
temp->pre = target;
temp->next = NULL;
} else {
temp->next = target->next;
target->next->pre = temp;
temp->pre = target;
target->next = temp;
}
return temp;
}
/*delect one colum node*/
void dele_cnode(ecnode * target)
{
if(target->pre == NULL) {
current_row->chead = target->next;
if(target->next != NULL)
target->next->pre = NULL;
} else if(target->next == NULL) {
target->pre->next = NULL;
} else {
target->pre->next = target->next;
target->next->pre = target->pre;
}
free(target);
}
/*add one row node*/
ernode * add_rnode(ernode * target)
{
ernode * temp = NULL;
if((temp=(ernode *)malloc(sizeof(ernode)))==NULL)
return (ernode *)0;
if(target->next == 0) {
temp->next = 0;
target->next = temp;
temp->pre = target;
temp->chead = NULL;
temp->num = 0;
temp->line = 1;
} else {
temp->next = target->next;
target->next->pre = temp;
temp->pre = target;
target->next = temp;
temp->chead = NULL;
temp->num = 0;
temp->line = 1;
}
return temp;
}
/*delect one row node*/
void dele_rnode(ernode * target)
{
if(target->pre == NULL)
return;
if(target->next == NULL)
target->pre->next = NULL;
else {
target->pre->next = target->next;
target->next->pre = target->pre;
}
free(target);
}
/*do some initialization about the editor*/
void init_editor()
{
current_row = NULL;
current_col = NULL;
if((current_row=(ernode *)malloc(sizeof(ernode)))==NULL) {
fprintf(stderr,"malloc fail!\n");
exit(1);
}
current_row->chead = NULL;
current_row->num = 0;
current_row->line = 1;
current_row->pre = NULL;
current_row->next = NULL;
row_head = current_row;
current_x = 0;
current_y = 0;
log_x = 0;
line_num = 1;
}
/*when the user input an enter then it
* will be handled here*/
int handle_add_enter(int ch)
{
ecnode * ctemp = NULL;
ernode * rtemp = NULL;
int line;
/*there have been MIN_EDITOR_ROWS lines
* in the edit window.*/
if(line_num == MIN_EDITOR_ROWS) {
if(current_row->line==1)
return 0;
else {
line = up_round(log_x,COLS);
if((current_row->line-line)*COLS <=
current_row->num-log_x)
return 0;
else {
ctemp=add_cnode(current_col);
ctemp->ch = '\n';
if(current_col->ch=='\n')
current_row->chead = ctemp;
current_col = ctemp;
rtemp = add_rnode(current_row);
rtemp->num = current_row->num-log_x;
current_row->num = log_x+1;
if(current_row->line > 1)
current_row->line--;
current_row = rtemp;
current_x = 0;
log_x = 0;
current_y++;
}
}
} else {
ctemp=add_cnode(current_col);
ctemp->ch = '\n';
if(!current_col)
current_row->chead = ctemp;
else if(current_col->ch=='\n')
current_row->chead = ctemp;
current_col = ctemp;
rtemp = add_rnode(current_row);
rtemp->chead = ctemp->next;
rtemp->num = current_row->num-log_x;
current_row->num = log_x+1;
if(current_row->line > 1)
current_row->line--;
current_row = rtemp;
current_x = 0;
log_x = 0;
current_y++;
}
line_num++;
return 1;
}
/*when the user input a char then it
* will be handled here*/
int handle_add_char(int ch)
{
ecnode * ctemp = NULL;
ernode * rtemp = NULL;
int line = 0;
if(line_num == MIN_EDITOR_ROWS) {
if((current_row->line)*COLS-1 <
current_row->num+1)
return 0;
else {
ctemp = add_cnode(current_col);
ctemp->ch = ch;
if(current_col->ch=='\n')
current_row->chead = ctemp;
current_col = ctemp;
current_row->num++;
if(current_x+2 > COLS) {
current_x = 0;
current_y++;
} else
current_x++;
log_x++;
}
} else {
ctemp = add_cnode(current_col);
ctemp->ch = ch;
if(!current_col)
current_row->chead = ctemp;
else if(current_col->ch=='\n')
current_row->chead = ctemp;
current_col = ctemp;
current_row->num++;
line = up_round(current_row->num,COLS);
if(line > current_row->line) {
line_num++;
current_row->line++;
}
if(current_x+2 > COLS) {
current_x = 0;
current_y++;
} else
current_x++;
log_x++;
}
return 1;
}
/*if the char being deleted is an enter
* then it will be handle here.*/
int handle_dele_enter()
{
int line;
/*the enter is at the beginng of
* the window*/
if(!current_col->pre) {
dele_cnode(current_col);
log_x = 0;
current_x = 0;
current_y = 0;
line_num--;
current_row = current_row->pre;
current_row->num = current_row->next->num;
current_row->chead = current_row->next->chead;
current_row->line = current_row->next->line;
dele_rnode(current_row->next);
current_col = NULL;
/*the enter is the tail of the link*/
} else if(current_col->next == NULL) {
if(current_row->pre->chead->ch ==
'\n') {
current_col = current_col->pre;
dele_cnode(current_col->next);
current_y--;
current_x = 0;
log_x = 0;
line_num--;
current_row=current_row->pre;
current_row->chead=current_row->next->chead;
current_row->num = current_row->next->num;
current_row->line=current_row->next->line;
dele_rnode(current_row->next);
} else {
current_col = current_col->pre;
dele_cnode(current_col->next);
current_y--;
line_num--;
current_row=current_row->pre;
//current_row->num+=current_row->next->num;
current_row->num--;
log_x = current_row->num;
current_x = (current_row->num%COLS);
dele_rnode(current_row->next);
}
/*the enter is at the middle of the link*/
} else {
current_col = current_col->pre;
dele_cnode(current_col->next);
current_row=current_row->pre;
log_x = current_row->num-1;
current_x = (current_row->num%COLS)-1;
current_row->num+=current_row->next->num;
current_row->num--;
line = up_round(current_row->num,COLS);
if(line <= current_row->next->line) {
line_num--;
}
current_row->line = line;
current_y--;
dele_rnode(current_row->next);
}
return 1;
}
/*if the char being deleted is not an enter
* then it will be handle here.*/
int handle_dele_char()
{
int line;
/*the char is at the beginning of the link*/
if(!current_col->pre) {
current_row->chead = current_col->next;
dele_cnode(current_col);
log_x = 0;
current_x = 0;
current_row->num--;
current_col = NULL;
/*the char is not at the beginning of the link*/
} else {
current_col = current_col->pre;
dele_cnode(current_col->next);
log_x--;
if(current_x == 0)
current_y--;
current_x = (log_x%COLS);
current_row->num--;
if(current_x != 0) {
line = up_round(current_row->num,COLS);
if(line < current_row->line) {
line_num--;
if(current_row->line > 1)
current_row->line--;
}
}
}
return 1;
}
/*add the current input into the link*/
int add_one(int ch)
{
/*if the char is an enter*/
if(ch == FKEY_ENTER || ch == '\n') {
return handle_add_enter(ch);
/*if the char is not an enter*/
} else {
return handle_add_char(ch);
}
}
/*delete the char before cursor in the link*/
int dele_one()
{
char ch;
if(!current_col)
return 0;
ch = current_col->ch;
/*if the char is an enter*/
if(ch == FKEY_ENTER || ch == '\n') {
return handle_dele_enter();
/*if the char is not an enter*/
} else {
return handle_dele_char();
}
}
/*move the cursor one step rightwards*/
void move_left()
{
if(current_x == 0) {
if(current_y == 0)
return;
else if(current_col->ch == '\n') {
current_y--;
current_row = current_row->pre;
current_col = current_col->pre;
current_x = (current_row->num%COLS)-1;
log_x = current_row->num - 1;
} else {
current_y--;
current_col = current_col->pre;
log_x--;
current_x = log_x%COLS;
}
} else {
current_x--;
log_x--;
current_col = current_col->pre;
}
}
/*move the cursor one step leftwards*/
void move_right()
{
if(!current_row->chead)
return;
else if(!current_col) {
current_col = current_row->chead;
if(current_col->ch == '\n') {
current_row = current_row->next;
current_x = 0;
log_x = 0;
current_y++;
} else {
current_x++;
log_x++;
}
} else if(!current_col->next)
return;
else if(current_col->next->ch == '\n') {
current_row = current_row->next;
current_col = current_col->next;
current_x = 0;
log_x = 0;
current_y++;
} else if(current_x == COLS-1){
current_col = current_col->next;
current_x = 0;
log_x++;
current_y++;
} else {
current_col = current_col->next;
current_x++;
log_x++;
}
}
/*move the cursor one step upwards*/
void move_up()
{
int i;
int temp;
if(current_y == 0)
return;
else {
if(log_x > COLS) {
for(i = 0; i < COLS; i++)
current_col = current_col->pre;
current_y--;
log_x -= COLS;
} else {
current_row=current_row->pre;
temp = current_row->num%COLS-1;
if(temp > current_x) {
current_y--;
current_col = current_row->chead;
for(i = 0; i < current_row->num-
(temp-current_x)-2; i++)
current_col = current_col->next;
log_x = current_row->num-(temp-current_x)-1;
} else {
current_y--;
current_x = temp;
log_x = current_row->num-1;
current_col = current_row->chead;
while(current_col->ch!='\n')
current_col=current_col->next;
current_col = current_col->pre;
}
}
}
}
/*move the cursor one step downwards*/
void move_down()
{
int i;
int temp;
if(current_y == line_num-1)
return;
else {
if(current_row->num-log_x>=COLS) {
for(i = 0; i < COLS; i++)
current_col = current_col->next;
current_y++;
log_x += COLS;
} else {
current_row=current_row->next;
temp = current_row->num;
if(temp > current_x) {
current_y++;
current_col = current_row->chead;
if(current_x == 0)
current_col = current_col->pre;
else
for(i = 0; i < current_x-1; i++)
current_col = current_col->next;
log_x = current_x;
} else {
current_y++;
current_x = temp;
log_x = current_x;
current_col = current_row->chead;
while(current_col->next && current_col->
next->ch!='\n')
current_col=current_col->next;
}
}
}
}
/*destroy the structure of the editor.
* (two double links)*/
void destroy_editor()
{
ernode * rp1;
ernode * rp2;
ecnode * cp1;
ecnode * cp2;
rp1 = rp2 = row_head;
if(row_head)
cp1 = cp2 = row_head->chead;
else
cp1 = NULL;
while(rp1) {
rp2 = rp1->next;
free(rp1);
rp1 = rp2;
}
while(cp1) {
cp2 = cp1->next;
free(cp1);
cp1 = cp2;
}
}
/*to see whether the input char is allowed*/
int 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 1;
break;
default:
if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
return 1;
else
return 0;
break;
}
return 0;
}
void editor()
{
int kbinput;
int i;
ecnode * p;
init_editor();
while(1) {
kbinput = wgetch(editwin);
if(kbinput == '\t')
kbinput = ' ';
switch(kbinput) {
//case 'q':
// destroy_struct();
// destroy_editor();
// finish();
// return;
// break;
case KEY_BACKSPACE:
dele_one();
break;
case KEY_LEFT:
move_left();
wmove(editwin,current_y,current_x);
wrefresh(editwin);
continue;
break;
case KEY_RIGHT:
move_right();
wmove(editwin,current_y,current_x);
wrefresh(editwin);
continue;
break;
case KEY_UP:
move_up();
wmove(editwin,current_y,current_x);
wrefresh(editwin);
continue;
break;
case KEY_DOWN:
move_down();
wmove(editwin,current_y,current_x);
wrefresh(editwin);
continue;
break;
case FKEY_C_S:
destroy_editor();
return;
break;
default:
if(!allow_input(kbinput))
continue;
else if(!add_one(kbinput))
continue;
break;
}/*print the input*/
p = row_head->chead;
i = 0;
while(p) {
key_buffer[i] = p->ch;
i++;
p = p->next;
}
key_buffer[i] = '\0';
wclear(editwin);
mvwprintw(editwin,0,0,"%s",key_buffer);
wmove(editwin,current_y,current_x);
wrefresh(editwin);
}
}
/*handle the user input from the keyboard*/
void * thread_keyboard()
{
int c;
while(1) {
wclear(editwin);
wrefresh(editwin);
init_editor();
editor();
c = handle_cmd();
if(!c) {
send_mes(key_buffer,serfd);
break;
} else if(c < 0)
send_mes(key_buffer,serfd);
}
close(serfd);
finish();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -