📄 edmisc.c
字号:
++col;
}
return(col);
}
/*
* Return current line number in file
*/
globle int getcline()
{
int i;
struct LINE *clp;
i = 0;
clp = curbp->b_linep;
while(clp != curwp->w_dotp) {
i++;
clp = lforw(clp);
}
if (i == 0)
return(cntlines());
return(i);
}
/*
* Return total number of lines in file
*/
globle int cntlines()
{
int i;
struct LINE *clp;
i = 1;
clp = lforw(curbp->b_linep);
while( clp != curbp->b_linep) {
i++;
clp = lforw(clp);
}
return(i);
}
/*
* Go to a specified line number
*/
#if IBM_TBC
#pragma argsused
#endif
globle int gotoline(
void *theEnv,
int f,
int n)
{
register int line;
char buf[5];
register int i;
register int s;
struct LINE *clp;
if ((s=mlreply(theEnv,"Goto line: ", buf, 5)) != TRUE)
return (s);
if((line = atoi(buf)) <= 0) {
mlwrite("Invalid line number!");
return(FALSE);
}
else if(line > cntlines()) {
mlwrite("Not that many lines in buffer!");
return(FALSE);
}
i = 0;
clp = lforw(curbp->b_linep);
while(i < line - 1) {
i++;
clp = lforw(clp);
}
curwp->w_dotp = clp;
curwp->w_doto = 0;
curwp->w_flag |= WFMOVE;
return (TRUE);
}
/*
* Twiddle the two characters on either side of dot. If dot is at the end of
* the line twiddle the two characters before it. Return with an error if dot
* is at the beginning of line; it seems to be a bit pointless to make this
* work. This fixes up a very common typo with a single stroke. Normally bound
* to "C-T". This always works within a line, so "WFEDIT" is good enough.
*/
#if IBM_TBC
#pragma argsused
#endif
globle int twiddle(
void *theEnv,
int f,
int n)
{
register LINE *dotp;
register int doto;
register int cl;
register int cr;
dotp = curwp->w_dotp;
doto = curwp->w_doto;
if (doto==llength(dotp) && --doto<0)
return (FALSE);
cr = lgetc(dotp, doto);
if (--doto < 0)
return (FALSE);
cl = lgetc(dotp, doto);
lputc(dotp, doto+0, cr);
lputc(dotp, doto+1, cl);
lchange(WFEDIT);
return (TRUE);
}
/*
* Quote the next character, and insert it into the buffer. All the characters
* are taken literally, with the exception of the newline, which always has
* its line splitting meaning. The character is always read, even if it is
* inserted 0 times, for regularity. Bound to "M-Q" (for me) and "C-Q" (for
* Rich, and only on terminals that don't need XON-XOFF).
*/
#if IBM_TBC
#pragma argsused
#endif
globle int quote(
void *theEnv,
int f,
int n)
{
register int s;
register int c;
c = (*term.t_getchar)();
if (n < 0)
return (FALSE);
if (n == 0)
return (TRUE);
if (c == '\n') {
do {
s = lnewline(theEnv);
} while (s==TRUE && --n);
return (s);
}
return (linsert(theEnv,n, c));
}
/*
* Set tab size if given non-default argument (n <> 1). Otherwise, insert a
* tab into file. If given argument, n, of zero, change to true tabs.
* If n > 1, simulate tab stop every n-characters using spaces. This has to be
* done in this slightly funny way because the tab (in ASCII) has been turned
* into "C-I" (in 10 bit code) already. Bound to "C-I".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int tab(
void *theEnv,
int f,
int n)
{
if (n < 0)
return (FALSE);
if (n == 0 || n > 1) {
tabsize = n;
return(TRUE);
}
if (! tabsize)
return(linsert(theEnv,1, '\t'));
return(linsert(theEnv,tabsize - (getccol(FALSE) % tabsize), ' '));
}
/*
* Open up some blank space. The basic plan is to insert a bunch of newlines,
* and then back up over them. Everything is done by the subcommand
* procerssors. They even handle the looping. Normally this is bound to "C-O".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int openline(
void *theEnv,
int f,
int n)
{
register int i;
register int s;
if (n < 0)
return (FALSE);
if (n == 0)
return (TRUE);
i = n; /* Insert newlines. */
do {
s = lnewline(theEnv);
} while (s==TRUE && --i);
if (s == TRUE) /* Then back up overtop */
s = backchar(theEnv,f, n); /* of them all. */
return (s);
}
/*
* Insert a newline. Bound to "C-M". If you are at the end of the line and the
* next line is a blank line, just move into the blank line. This makes "C-O"
* and "C-X C-O" work nicely, and reduces the ammount of screen update that
* has to be done. This would not be as critical if screen update were a lot
* more efficient.
*/
#if IBM_TBC
#pragma argsused
#endif
globle int newline(
void *theEnv,
int f,
int n)
{
register LINE *lp;
register int s;
if (n < 0)
return (FALSE);
while (n--) {
lp = curwp->w_dotp;
if (llength(lp) == curwp->w_doto
&& lp != curbp->b_linep
&& llength(lforw(lp)) == 0) {
if ((s=forwchar(theEnv,FALSE, 1)) != TRUE)
return (s);
} else if ((s=lnewline(theEnv)) != TRUE)
return (s);
}
return (TRUE);
}
/*
* Delete blank lines around dot. What this command does depends if dot is
* sitting on a blank line. If dot is sitting on a blank line, this command
* deletes all the blank lines above and below the current line. If it is
* sitting on a non blank line then it deletes all of the blank lines after
* the line. Normally this command is bound to "C-X C-O". Any argument is
* ignored.
*/
#if IBM_TBC
#pragma argsused
#endif
globle int deblank(
void *theEnv,
int f,
int n)
{
register LINE *lp1;
register LINE *lp2;
long nld;
lp1 = curwp->w_dotp;
while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
lp1 = lp2;
lp2 = lp1;
nld = 0;
while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
++nld;
if (nld == 0)
return (TRUE);
curwp->w_dotp = lforw(lp1);
curwp->w_doto = 0;
return (ldelete(theEnv,nld,FALSE));
}
/*
* Insert a newline, then enough tabs and spaces to duplicate the indentation
* of the previous line. Assumes tabs are every eight characters. Quite simple.
* Figure out the indentation of the current line. Insert a newline by calling
* the standard routine. Insert the indentation by inserting the right number
* of tabs and spaces. Return TRUE if all ok. Return FALSE if one of the
* subcomands failed. Normally bound to "C-J".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int indent(
void *theEnv,
int f,
int n)
{
register int nicol;
register int c;
register int i;
if (n < 0)
return (FALSE);
while (n--) {
nicol = 0;
for (i=0; i<llength(curwp->w_dotp); ++i) {
c = lgetc(curwp->w_dotp, i);
if (c!=' ' && c!='\t')
break;
if (c == '\t')
nicol |= 0x07;
++nicol;
}
if (lnewline(theEnv) == FALSE
|| ((i=nicol/8)!=0 && linsert(theEnv,i, '\t')==FALSE)
|| ((i=nicol%8)!=0 && linsert(theEnv,i, ' ')==FALSE))
return (FALSE);
}
return (TRUE);
}
/*
* Delete forward. This is real easy, because the basic delete routine does
* all of the work. Watches for negative arguments, and does the right thing.
* If any argument is present, it kills rather than deletes, to prevent loss
* of text if typed with a big argument. Normally bound to "C-D".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int forwdel(
void *theEnv,
int f,
int n)
{
if (n < 0)
return (backdel(theEnv,f, -n));
if (f != FALSE) { /* Really a kill. */
if ((lastflag&CFKILL) == 0)
kdelete(theEnv);
thisflag |= CFKILL;
}
return (ldelete(theEnv,(long) n, f));
}
/*
* Delete backwards. This is quite easy too, because it's all done with other
* functions. Just move the cursor back, and delete forwards. Like delete
* forward, this actually does a kill if presented with an argument. Bound to
* both "RUBOUT" and "C-H".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int backdel(
void *theEnv,
int f,
int n)
{
register int s;
if (n < 0)
return (forwdel(theEnv,f, -n));
if (f != FALSE) { /* Really a kill. */
if ((lastflag&CFKILL) == 0)
kdelete(theEnv);
thisflag |= CFKILL;
}
if ((s=backchar(theEnv,f, n)) == TRUE)
s = ldelete(theEnv,(long) n, f);
return (s);
}
/*
* Kill text. If called without an argument, it kills from dot to the end of
* the line, unless it is at the end of the line, when it kills the newline.
* If called with an argument of 0, it kills from the start of the line to dot.
* If called with a positive argument, it kills from dot forward over that
* number of newlines. If called with a negative argument it kills backwards
* that number of newlines. Normally bound to "C-K".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int kill_fwd(
void *theEnv,
int f,
int n)
{
register int chunk;
register LINE *nextp;
if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */
kdelete(theEnv); /* last wasn't a kill. */
thisflag |= CFKILL;
if (f == FALSE) {
chunk = llength(curwp->w_dotp)-curwp->w_doto;
if (chunk == 0)
chunk = 1;
} else if (n == 0) {
chunk = curwp->w_doto;
curwp->w_doto = 0;
} else if (n > 0) {
chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
nextp = lforw(curwp->w_dotp);
while (--n) {
if (nextp == curbp->b_linep)
return (FALSE);
chunk += llength(nextp)+1;
nextp = lforw(nextp);
}
} else {
mlwrite("neg kill");
return (FALSE);
}
return (ldelete(theEnv,(long) chunk, TRUE));
}
/*
* Yank text back from the kill buffer. This is really easy. All of the work
* is done by the standard insert routines. All you do is run the loop, and
* check for errors. Bound to "C-Y". The blank lines are inserted with a call
* to "newline" instead of a call to "lnewline" so that the magic stuff that
* happens when you type a carriage return also happens when a carriage return
* is yanked back from the kill buffer.
*/
#if IBM_TBC
#pragma argsused
#endif
globle int yank(
void *theEnv,
int f,
int n)
{
register int c;
register int i;
if (n < 0)
return (FALSE);
while (n--) {
i = 0;
while ((c=kremove(i)) >= 0) {
if (c == '\n') {
if (newline(theEnv,FALSE, 1) == FALSE)
return (FALSE);
} else {
if (linsert(theEnv,1, c) == FALSE)
return (FALSE);
}
++i;
}
}
return (TRUE);
}
/* =========================================================================
* SEARCH FUNCTIONS
* =========================================================================
*/
/*
* The functions in this section implement commands that search in the forward
* and backward directions. There are no special characters in the search
* strings. Probably should have a regular expression search, or something
* like that.
*
* They also implement commands that do the followings
* - Replaces all the occurences of a string,
* from the current point of cursor to the end of file,
* with a new string.
* - search for matching bracket
*
* REVISION HISTORY:
*
* ? Steve Wilhite, 1-Dec-85
* - massive cleanup on code.
*
* Huyen_Anh Vu Ly, 16-Dec-86
* - extending the capability of Emacs included the followings:
* -*- backward search and replace all the occurences of a string,
* C-X R.
* -*- backward search and replace some of te occurences of a string,
* M-R.
* -*- forward search and replace all the occurences of a string,
* C-X S.
* -*- forward search and replace some occurences of a string,
* M-S.
* -*- find the matching bracket for : (,),[,],{,},
* C-X M.
*/
/*
* Search forward. Get a search string from the user, and search, beginning at
* ".", for the string. If found, reset the "." to be just after the match
* string, and [perhaps] repaint the display. Bound to "C-S".
*/
#if IBM_TBC
#pragma argsused
#endif
globle int forwsearch(
void *theEnv,
int f,
int n)
{
register LINE *clp;
register int cbo;
register LINE*tlp;
register int tbo;
register int c;
register char *pp;
register int s;
if ((s = readpattern(theEnv,"Search")) != TRUE)
return (s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -