共有回帖数  0  个 
	 
	
	
	
     
          
          
               
				
			 
				
					 
 
            
				   - 
						
						
							 
									#define DEL     263
#define ENTER     10
#define UP     259
#define DOWN     258
#define LEFT    260
#define RIGHT    261
#define COMMAND 58
#define BUF_SIZE 256
#define LINE_SIZE 1000
#define MIN(x,y)   ((x)(y)?(x):(y))
#include"procerr.h"
#includecurses.h
#includestring.h
char big_mem[10000],buf[BUF_SIZE];
chtype ch,ch_buf[BUF_SIZE];
int count[LINE_SIZE];
bool show=1,save=0,out=0;
int save_x=0,save_y=0;
int enter_x,del_x;
int fd=-1;
int pad_x=500,pad_y=1000;
int change_y=0,nread,nwrite,offset=0,cursor_offset=0,line=0;
WINDOW*pad,*command,*info;
static void func_step(void);
static void func_del_ch(void);
static void func_del_ln(void);
static void func_enter(void);
static void func_change_down(void);
static void func_change_up(void);
static void func_command(void);
static void func_text_save(void);
static void func_pad_save(int);
static bool func_text_load(void);
static bool func_pad_load(void);
static void func_count_line(void);
static void func_info(void);
int main(int argc,char*argv[]){
    initscr();    
    noecho();//不回显
    cbreak();//预处理模式
    keypad(stdscr,TRUE);//启用方向健
    refresh();
    raw();//关闭特殊键
    fd=open(argv[1],O_RDWR|O_CREAT,PERM_FILE);    
    func_text_load();
    func_pad_load();
    func_count_line();
    func_info();
    while(1)
        {                      
        switch(ch=getch()){
            case -1:
            case 410:
                func_pad_load();
                if(show)func_info();
                break;    
            case DEL:
                if(save_x0) 
                    { 
                    func_del_ch();
                    count[save_y+change_y]--;
                    cursor_offset--;
    func_pad_save(0);
                    if(show)func_info();
                    }
                else if(save_y0) 
                    { 
                        int i;    
                        del_x=count[save_y+change_y-1];    
                        count[save_y+change_y-1]+=count[save_y+change_y]-1;
                        for(i=save_y+change_y;iline-1;i++)
                            count=count[i+1];
                        line--;
                    func_del_ln();
                    cursor_offset--;
                    func_pad_save(0);
                    if(show)func_info();    
                    }
                break;
            case DOWN:
                if(save_y  LINES-1){
                    cursor_offset+=count[save_y+change_y]-save_x+MIN(count[save_y+change_y+1]-1,save_x);/////////////////////
                    save_y++;
                    wmove(pad,save_y,(save_x=MIN(count[save_y+change_y]-1,save_x)));
                    prefresh(pad,0,0,0,0,LINES-1,COLS-1);            
         }
                else if(save_y==LINES-1 && (save_y+change_y)  (line-1) ){
                    func_change_down();
                    }
                if(show)func_info();
                break;
            case UP:
                if(save_y0){ 
                    cursor_offset-=save_x+count[save_y+change_y-1];
                    cursor_offset+=MIN(count[save_y+change_y-1]-1,save_x);
                    save_y--;    
                    wmove(pad,save_y,(save_x=MIN(count[change_y+save_y]-1,save_x)));    
                    prefresh(pad,0,0,0,0,LINES-1,COLS-1);
                    }
                else if(save_y==0 && change_y0){
                    func_change_up();
                    }
                if(show)func_info();
                break;
            case LEFT:
                if(save_x0){save_x--;func_step();cursor_offset--;}
                if(show)func_info();
                break;
            case RIGHT:
                if(save_xcount[change_y+save_y]-1){save_x++;func_step();cursor_offset++;}
                if(show)func_info();
                break;
    case ENTER://不支持卷屏的func_enter
                func_enter();
                cursor_offset++;
                func_pad_save(1);
                if(show)func_info();
                break;
            case COMMAND:
                func_command();
                if(show)func_info();
                else func_step();
                if(save)func_text_save();
                if(out) goto EXAPLEM_END;
                break;
            default:
                winsch(pad,ch);
                count[save_y+change_y]++;
                if(save_xCOLS){
                    save_x++;func_step();
                    cursor_offset++;
                    func_pad_save(1);    
                    }
                else if((save_y+change_y)LINES){ 
                    save_x=0;save_y++;func_step();//不支持卷屏
                    }
                if(show)func_info();
                break;
            }
        }
EXAPLEM_END:
    noraw();    
    echo();
    nocbreak();
    delwin(pad);
    endwin();
    return 0;
EC_CLEANUP_BGN
    endwin();
    return 1;
EC_CLEANUP_END    
}
static void func_step()
{
    wmove(pad,save_y,save_x);
    if(show)prefresh(pad,0,0,0,0,LINES,COLS-5);    
    else prefresh(pad,0,0,0,0,LINES,COLS);
}
static void func_del_ch()//offset_end
{
    save_x--;
    func_step();
    wdelch(pad);
    prefresh(pad,0,0,0,0,LINES-1,COLS-1);
}
static void func_del_ln()//offset_end
{   
    int i=0;
    save_x=COLS-1;
    wmove(pad,save_y,save_x);
    memset(ch_buf,' ',BUF_SIZE);
    while(save_x0 && winch(pad)==' '){
            save_x--;
            wmove(pad,save_y,save_x);
                }
        //准备复制
    buf[save_x+1]=' ';
    
    for(;save_x=0;){
        ch_buf[save_x]=winch(pad);
        save_x--;
        i++;
        wmove(pad,save_y,save_x);
            }    
        //复制了一个串包含回车 
                
        wdeleteln(pad);
        save_y--;
        save_x=del_x-1;
        wmove(pad,save_y,save_x);
        //准备黏贴
        waddchstr(pad,ch_buf);
        //实施黏贴
        prefresh(pad,0,0,0,0,LINES-1,COLS-1);
    
}
static void func_enter(void)                
{
    int i;
if(lineLINE_SIZE-1){        
    line++;
    for(i=line-1;isave_y+1;i--)
        count=count[i-1];        
    count[save_y+1]=count[save_y]-save_x;
    count[save_y]=save_x+1;//加了回车    
    enter_x=save_x;
    ch_buf[save_x]=' ';
    save_x--;
    func_step();
    for(;save_x=0;){
            ch_buf[save_x]=winch(pad);
            save_x--;                
           func_step();
            }                        
    winsertln(pad);
    waddchstr(pad,ch_buf);
    save_y++;                    
    wmove(pad,save_y,(save_x=enter_x));    
    while(save_x0)func_del_ch();
    prefresh(pad,0,0,0,0,LINES-1,COLS-1);
    return;
    }
else
    return;
}        
static void func_command(void)
{
    int i;
    command=newwin(1,160,LINES-1,0);
    mvwprintw(command,0,0,"command:");
    wmove(command,0,8);
    wrefresh(command);
    for(i=0,enter_x=8;(ch=getch())!='n';i++){
        if(ch==DEL){
            if(enter_x8)enter_x--;
            wmove(command,0,enter_x);
            wdelch(command);
            wrefresh(command);
        }
        else if(ch='a' && ch='z'){
            buf=(char)ch;
            waddch(command,ch);
            enter_x++;
            wmove(command,0,enter_x);
            wrefresh(command);
            }
        }
        buf=' ';
    if(strcmp(buf,"q")==0) out=1;
    else if(strcmp(buf,"w")==0) save=1;
    else if( strcmp(buf,"wq")==0) out=save=1;
    else if(strcmp(buf,"i")==0) {
        if(show)show--;else show++;
            }
    prefresh(pad,0,0,0,0,LINES-1,COLS-1);
}
static void func_pad_save(int add_or_not)
{
    int i;
    if(add_or_not==1){
        cursor_offset--;
        big_mem[strlen(big_mem)+1]=' ';
        for(i=strlen(big_mem);icursor_offset;i--)
            big_mem=big_mem[i-1];
big_mem[cursor_offset]=ch;
        cursor_offset++;
    }
    else{
        for(i=cursor_offset;istrlen(big_mem)-1;i++)
        big_mem=big_mem[i+1];
        big_mem=' ';
    }
}
static void func_text_save(void)//将数组保存到文本之中
{
    lseek(fd,0,SEEK_SET);
    write(fd,big_mem,strlen(big_mem));
}
            
static bool func_text_load(void)
{
    memset(buf,' ',strlen(buf));
    memset(big_mem,' ',strlen(big_mem));
    while((nread=read(fd,buf,BUF_SIZE))0){
        strcat(big_mem,buf);            
        memset(buf,' ',strlen(buf));
        }
    return 0;
EC_CLEANUP_BGN
    return -1;
EC_CLEANUP_END    
}
static bool func_pad_load(void)//每次根据cursor_offset来设置光标
{
    int x,y,off;
    static first=1;
    pad=newpad(LINES,COLS);
    wprintw(pad,"%s",big_mem+offset);
    
    if(first){
        wmove(pad,save_y,save_x);
        prefresh(pad,0,0,0,0,LINES,COLS);
    first=0;
    }
    else{
    off=offset;
    for(y=0;off=cursor_offset;y++)
        off+=count[y+change_y];
        y--;
    off-=count[y+change_y];
    x=cursor_offset-off;    
    save_y=y;
    save_x=x;
    wmove(pad,save_y,save_x);
    prefresh(pad,0,0,0,0,LINES,COLS);
    }
    return 0;
EC_CLEANUP_BGN
    return -1;
EC_CLEANUP_END    
}static void func_change_down(void)
{
   cursor_offset+=count[save_y+change_y]-save_x+MIN(count[save_y+change_y+1]-1,save_x);/////////////////////
   offset+=count[change_y];
   change_y++;       //BUG
   
   pad=newpad(LINES,COLS);       
   wprintw(pad,"%s",big_mem+offset);
   wmove(pad,save_y,(save_x=MIN(save_x,count[save_y+change_y]-1)));//让其跳到下一行的末尾
   prefresh(pad,0,0,0,0,LINES,COLS);   
}
static void func_change_up(void)
{
   cursor_offset-=save_x+count[save_y+change_y-1];
   cursor_offset+=MIN(count[save_y+change_y-1]-1,save_x);
   change_y--;   //BUG
   offset-=count[change_y];
   pad=newpad(LINES,COLS);       
   wprintw(pad,"%s",big_mem+offset);
   wmove(pad,save_y,save_x);
   prefresh(pad,0,0,0,0,LINES,COLS);   
}
static void func_count_line(void) //BUG 如果只有1行并且其中没有n的时候,无法建立count数组,最后一行无法建立
{
   int i,pre=0,cur=0;
   
   for(i=0;istrlen(big_mem);i++)
       if(big_mem=='n'|| big_mem==' '){
           cur=i;
           count[line]=cur-pre+1;
           pre=cur+1;
           line++;
           }
       
}
static void func_info()
{
   int i;
   info=newwin(LINES,8,0,COLS-8);
   mvwprintw(info,0,0,"%d:%d",cursor_offset,count[change_y]);
   for(i=1;iMIN(line,LINES);i++){
       mvwprintw(info,i,0,"%d",count[i+change_y]);
       }
   wrefresh(info);
   wmove(pad,save_y,save_x);
   prefresh(pad,0,0,0,0,LINES,COLS-9);   
   
}
自己用linux下curses库写的一个文本编辑器,实现了基本的光标操作,del,enter,打开,保存,显示每行长度等功能。有几个BUG - - 写了5天 差点精神崩溃
							 
							 
							 
							  
							  
							  楼主 2015-12-10 13:33 回复
						 
						 
           
          
          
         
   
         
      
 
   
             
                  
                  
 
 
 
     
	 
  
	Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
	
	意见反馈 | 
	关于直线 | 
	版权声明 | 
	会员须知