📄 e3.c
字号:
//----------------------------------------------------------------------// e3.c v0.92 Copyright (C) 2000 Albrecht Kleine <kleine@ak.sax.de>// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.////---------------------------------------------------------------------#ifndef __GNUC__#error "Sorry, but I need GNU C."#endif#define CURSORMGNT#define LESSWRITEOPS#ifdef LESSWRITEOPS#define LESSWRITEOPS_OR_CURSORMGNT#endif#ifdef CURSORMGNT#define LESSWRITEOPS_OR_CURSORMGNT#endif#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <stdio.h>#include <sys/ioctl.h>#include <termios.h>#include <sys/stat.h>#include <string.h>#include <stdlib.h>struct termios termios,orig;//---------------------------------------------------------------------//// CONSTANT DATA AREA//#define lowest 0x3bunsigned char Ktable[]={ 0x45 - lowest, // ^K@ xlatb table for making pseudo-scancode 0x45 - lowest, // ^ka 45h points to an an offset in jumptab1 0x41 - lowest, // ^kb 41h for example points to KeyCtrlKB function offset 0x43 - lowest, // ^kc 0x5d - lowest, // ^kd 0x45 - lowest, // ^ke 45h means SimpleRet i.e. 'do nothing' 0x45 - lowest, // ^kf 0x45 - lowest, // ^kg 0x57 - lowest, // ^kh 0x45 - lowest, // ^ki 0x45 - lowest, // ^kj 0x42 - lowest, // ^kk 0x45 - lowest, // ^kl 0x45 - lowest, // ^km 0x45 - lowest, // ^kn 0x45 - lowest, // ^ko 0x45 - lowest, // ^kp 0x46 - lowest, // ^kq 0x3d - lowest, // ^kr 0x5c - lowest, // ^ks 0x45 - lowest, // ^kt 0x45 - lowest, // ^ku 0x3b - lowest, // ^kv 0x3e - lowest, // ^kw 0x44 - lowest, // ^kx 0x4e - lowest, // ^ky 0x45 - lowest}; // ^kzunsigned char Qtable[]={ 0x45 - lowest, // ^q@ ditto for ^Q menu 0x54 - lowest, // ^qa 0x5a - lowest, // ^qb 0x61 - lowest, // ^qc former 76h ctrl-PageDown 0x4f - lowest, // ^qd 0x58 - lowest, // ^qe 0x55 - lowest, // ^qf 0x45 - lowest, // ^qg 0x4a - lowest, // ^qh, ^qDEL 0x62 - lowest, // ^qi 0x45 - lowest, // ^qj 0x5b - lowest, // ^qk 0x45 - lowest, // ^ql 0x45 - lowest, // ^qm 0x45 - lowest, // ^qn 0x45 - lowest, // ^qo 0x4c - lowest, // ^qp 0x45 - lowest, // ^qq 0x63 - lowest, // ^qr former ctrl-PageUp 0x47 - lowest, // ^qs 0x45 - lowest, // ^qt 0x45 - lowest, // ^qu 0x56 - lowest, // ^qv 0x5e - lowest, // ^qw former 73h ctrl-left 0x59 - lowest, // ^qx 0x40 - lowest, // ^qy 0x5f - lowest}; // ^qz former 74h ctrl-right// Using terminals the F-keys are not yet supported (was DOS only). //------char filename[] =" NAME:";char filesave[] =" SAVE:";char asksave[] ="SAVE? Y/N";char block[] ="BLK NAME:";char askfind[] ="^QF FIND:";char askreplace1[] ="^QA REPL:";char askreplace2[] ="^QA WITH:";char asklineno[] ="^QI LINE:";char optiontext[] ="OPT? C/B";#define stdtxtlen 10char screencolors0[]={27,'[','4','0','m',27,'[','3','7','m'};char bold0[]={27,'[','0','m'}; // reset to b/wchar screencolors1[]={27,'[','4',/*'4'*/'1','m',27,'[','3','3','m'}; // yellow on red /*blue*/char bold1[]={27,'[','1','m',27,'[','7','m'}; // bold #define reversevideoX bold1 // good for "linux" terminal on /dev/tty (but not xterm,kvt)#define scolorslen 14#define boldlen 4 // take care length of bold0 == length of bold1#define O_WRONLY_CREAT_TRUNC 01101#define PERMS 0644char resfile[]=LIBDIR"/e3.res";char helpfile[]=LIBDIR"/e3ws.hlp";#define TAB 8#define TABCHAR 0x9 // ^I#define SPACECHAR ' '#define CHANGED '*'#define UNCHANGED SPACECHAR#define LINEFEED 0xa#define NEWLINE LINEFEED//---------------------------------------------------------------------unsigned char screenbuffer [62*(160+32)]; // estimated 62 lines 160 columns, 32 byte ESC seq (ca.12k)#define screenbuffer_end screenbuffer[62*(160+32)] // If you really have higher screen resolution, // ...no problem, except some useless redrawing happens.#define winsize_size 8unsigned char winsize [winsize_size];#define setkplen 10unsigned char setkp [setkplen]; // to store cursor ESC seq like db 27,'[000;000H'long revvoff;long lines; // equ 24 or similar i.e. screen lines-1 (1 for statusline)long columns; // equ 80 or similar dword (using only LSB)long columne; // helper for display of current columnlong zloffst; // helper: chars scrolled out at left borderlong fileptr; // helper for temp storage of current pos in filelong kurspos; // cursor position set by DispNewScreen()long kurspos2; // cursor position set by other functionslong tabcnt; // longernal helper byte in DispNewScreen() onlylong changed; // status byte: (UN)CHANGEDlong oldQFpos;long bereitsges; // byte used for ^Llong blockbegin;long blockende;long endeedit; // byte controls program exitlong old; // helper for ^QPlong veryold; // dittolong linenr; // current linelong showblock; // helper for ^KHlong suchlaenge; // helper for ^QA,^QFlong repllaenge;long vorwarts;long grossklein; // helper byte for ^QF,^QAlong ch2linebeg; // helper keeping cursor pos max at EOL (up/dn keys)long numeriere; // byte controls re-numerationlong read_b; // buffer for getcharlong isbold; // control of bold display of ws-blockslong inverse;long insstat;#define errlen 100unsigned char error [errlen]; // reserved space for string: 'ERROR xxx:tttteeeexxxxtttt',0long maxlen;#define maxfilenamelen 255unsigned char filepath [maxfilenamelen+1];unsigned char bakpath [maxfilenamelen+1];unsigned char blockpath [maxfilenamelen+1];unsigned char replacetext [maxfilenamelen+1];unsigned char suchtext [maxfilenamelen+1];#define optslen 8unsigned char optbuffer [optslen]; // buffer for search/replace options and for ^QIlong uid;long gid;long perms;struct stat fstatbuf;unsigned char screenline [256+4*scolorslen]; // max possible columns + 4 color ESC seq per line // (buffer for displaying a text line)#define errbufsize 4000unsigned char errmsgs [errbufsize];//------#define max 10240000unsigned char text [max];#define sot (text+1) // start-of-text//--------------------------- END OF DATA SECTION ---------------------long stack[100];#define RETURN goto *(*esp--)#define CALL(calladr,retadr) *++esp=(long)&&_loc##retadr; goto calladr; _loc##retadr:#define PUSH(arg) *++esp=arg#define POP(arg) (long*)arg=*esp--int main(int argc,char**argv,char **envp){ long eax=0,ecx=0,edx=0,ebx=0,edi=0,esi=0,extra=0,extra2=0,parm; long *esp=stack; unsigned char *ebp=0; #define jumps1 0x29 static void* jarray[]={ &&KeyCtrlKV, // 3bh ^KV F1 (DOS only) &&KeyCtrlL, // 3ch ^L F2 (ditto) &&KeyCtrlKR, // 3dh ^KR F3 (etc) &&KeyCtrlKW, // 3eh ^KW &&KeyCtrlT, // 3fh ^T &&KeyCtrlQY, // 40h ^QY &&KeyCtrlKB, // 41h ^KB &&KeyCtrlKK, // 42h ^KK &&KeyCtrlKC, // 43h ^KC &&KeyCtrlKX, // 44h ^KX F10 &&SimpleRet, // 45h F11 &&KeyCtrlKQ, // 46h F12 &&KeyHome, // 47h &&KeyUp, // 48h &&KeyPgUp, // 49h &&KeyCtrlQDel, // 4ah ^QDel &&KeyLeft, // 4bh &&KeyCtrlQP, // (5 no num lock) &&KeyRight, // 4dh &&KeyCtrlKY, // (+) ^KY &&KeyEnd, // 4fh &&KeyDown, // 50H &&KeyPgDn, // 51h &&KeyIns, // 52H &&KeyDel, // 53H &&KeyCtrlQA, // 54h ^QA sF1 &&KeyCtrlQF, // 55h ^QF sf1 &&KeyCtrlQV, // 56h &&KeyCtrlKH, // 57h &&KeyCtrlQE, // 58h &&KeyCtrlQX, // 59h &&KeyCtrlQB, // 5Ah ^QB &&KeyCtrlQK, // 5Bh ^QK sF8 &&KeyCtrlKS, // 5ch ^KS sF9 &&KeyCtrlKD, // 5dh ^KD sF10 &&KeyCtrlLeft, // 5eh ^Left was 73h (compare notes above) &&KeyCtrlRight, // 5fh ^Right (was 74h) &&SimpleRet, // 60h ^End (was 75h) &&KeyCtrlQC, // 61h ^PageDown (was 76h) &&KeyCtrlQI, // 62h ^Home (was 77h) &&KeyCtrlQR, // 63h ^PageUp (was 84h)// jumps1......= 29h &&SimpleRet, // ^@ (only former DOS version has a "jumptab2") &&KeyHome, // ^a (compare notes above) &&SimpleRet, // ^b &&KeyPgDn, // ^c &&KeyRight, // ^d &&KeyUp, // ^e &&KeyEnd, // ^f &&KeyDel, // ^g 7 &&KeyDell, // ^h 8 DEL (7fh is translated to this) &&NormChar, // ^i 9 &&KeyRet, // ^j = 0ah &&CtrlKMenu, // ^k b &&KeyCtrlL, // ^l c &&SimpleRet, // ^m 0dh &&SimpleRet, // ^n e &&SimpleRet, // ^o f &&SimpleRet, // ^p 10 &&CtrlQMenu, // ^q 11 &&KeyPgUp, // ^r 12 &&KeyLeft, // ^s 13 &&KeyCtrlT, // ^t 14 &&SimpleRet, // ^u 15 &&KeyIns, // ^v 16 &&SimpleRet, // ^w 17 &&KeyDown, // ^x 18 &&KeyCtrlY, // ^y 19 &&SimpleRet, // ^z &&SimpleRet // esc }; CALL(SetTermStruc,0); CALL(ReadResource,1); esi=(long)*++argv;#ifdef CURSORMGNT if (!strcmp(getenv("TERM"),"linux")) revvoff+=boldlen; // special inverse cursor on linux terminals#endif //------ do { CALL(NewFile,2); if (extra) break; do { CALL(DispNewScreen,3); CALL(RestoreStatusLine,4); CALL(HandleChar,5); } while (!endeedit); esi=0; // just like if no arg is present } while (endeedit==2); // ^KD repeat edit using another file//------ CALL(KursorStatusLine,6); ecx = (long)&text; // enter next line on terminal NEWLINE is @ byte [text] edx=1; CALL(WriteFile0,7); eax = (long)&orig; CALL(SetTermStruc2,8); // restore termios settings goto Exit;//---------------------------------------------------------------------// MAIN function for processing keys//HandleChar:CALL(ReadChar,9); if (!eax) goto CompJump2; // eax=0 for cursor keys if (eax>=0x1c) goto NormChar; ebx = eax+jumps1; goto CompJump2;NormChar:CALL(CheckMode,10); if (!extra) goto OverWriteChar; PUSH(eax); eax=1; CALL(InsertByte,11); POP(eax); if (extra) goto InsWriteEnd; // error: text buffer fullOverWriteChar:*(unsigned char*)edi++=eax; changed = CHANGED;InsWriteEnd:RETURN;//------//// helper for HandleChar//CtrlKMenu:ebx = (long)&Ktable; ecx = 0x20204b5e; // ^K goto Menu;CtrlQMenu:ebx = (long)&Qtable; ecx = 0x2020515e; // ^QMenu: CALL(MakeScanCode,12); if (eax>=27) goto EndeRet; // if no valid scancodeCompJump2:ebx=(long)jarray[(int)ebx];//------ CALL(*ebx,13); // the general code jump dispatcher//------ if (numeriere) { PUSH(edi); esi=edi; edi = (long)(sot); linenr=0; do { linenr++; CALL(LookForward,14); ++edi; // point to start of next line } while ((unsigned long)edi<=(unsigned long)esi); POP(edi); } numeriere = 0; RETURN;//------MakeScanCode:CALL(WriteTwo,15); // ebx expects xlat-table PUSH(ebx); CALL(GetChar,16); POP(ebx); eax&=0x1f; if (eax>=27) goto EndeRet; ebx=*((unsigned char*)(ebx+eax)); // returns pseudo "scancode" in ebxEndeRet:RETURN; // exception: ok=cy here//---------------------------------------------------------------------//// processing special keys: cursor, ins, del//KeyRet: CALL(CheckMode,17); if (!extra) goto OvrRet; CALL(CountToLineBegin,18); // set esi / returns eax ++esi; ++esi; if (!eax) goto KeyRetNoIndent; eax=-1;KeyRetSrch:++eax; // search non (SPACE or TABCHAR) if (*(unsigned char*)(esi+eax)==SPACECHAR) goto KeyRetSrch; if (*(unsigned char*)(esi+eax)==TABCHAR) goto KeyRetSrch;KeyRetNoIndent: PUSH(esi); PUSH(eax); // eax is 0 or =indented chars CALL(GoDown,19); POP(eax); PUSH(eax); ++eax; // 1 extra for 0ah CALL(InsertByte,20); POP(ecx); // # blanks POP(esi); // where to copy if (extra) goto SimpleRet; ++linenr; *(unsigned char*)edi++=NEWLINE; if (ecx) do { *(unsigned char*)edi++=*(unsigned char*)esi++; } while (--ecx); // copy upper line i.e. SPACES,TABS into nextSimpleRet:RETURN;OvrRet: eax=0; ch2linebeg = eax; goto DownRet;//------KeyDown:CALL(CountColToLineBeginVis,21);DownRet:CALL(GoDown,22); CALL(LookLineDown,23); goto SetColumn;//------KeyUp: CALL(GoUp,24); CALL(CountColToLineBeginVis,25); CALL(LookLineUp,26); goto SetColumn;//------KeyPgUp:CALL(CountColToLineBeginVis,27); CALL(LookPageUp,28); goto SetColumn;//------KeyPgDn:CALL(CountColToLineBeginVis,29); CALL(LookPgDown,30); // 1st char last line//------SetColumn:ecx = ch2linebeg; // maximal columns edx=0; // counts visible columns i.e. expand TABs --edi;SCloop: ++edi; if (edx>=ecx) goto SCret; if (*(unsigned char*)edi==NEWLINE) goto SCret; // don't go beyond line earlier line end if (*(unsigned char*)edi==TABCHAR) goto SCtab; ++edx; // count columns
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -