1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-06-18 08:35:22 +00:00

basic: code review and minor refactoring.

This commit is contained in:
Renaud 2021-08-09 12:06:07 +08:00
parent 893e34b740
commit eaf516110f
2 changed files with 241 additions and 263 deletions

485
basic.c
View File

@ -1,19 +1,16 @@
/* basic.c -- implements basic.h */ /* basic.c -- implements basic.h */
#include "basic.h" #include "basic.h"
/* basic.c /* The routines in this file move the cursor around on the screen. They
* compute a new value for the cursor, then adjust ".". The display code
* The routines in this file move the cursor around on the screen. They always updates the cursor location, so only moves between lines, or
* compute a new value for the cursor, then adjust ".". The display code functions that adjust the top line in the window and invalidate the
* always updates the cursor location, so only moves between lines, or framing, are hard.
* functions that adjust the top line in the window and invalidate the
* framing, are hard. modified by Petri Kutvonen
*
* modified by Petri Kutvonen
*/ */
#include <stdio.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include "input.h" #include "input.h"
@ -22,340 +19,322 @@
#include "terminal.h" #include "terminal.h"
#include "window.h" #include "window.h"
#define CVMVAS 1 /* arguments to page forward/back in pages */
#define CVMVAS 1 /* arguments to page forward/back in pages */ int overlap = 0 ; /* $overlap: line overlap in forw/back page */
int curgoal ; /* $target: Goal for C-P, C-N */
int overlap = DEFAULT_OVERLAP ; /* line overlap in forw/back page */ /* This routine, given a pointer to a struct line, and the current cursor
int curgoal ; /* Goal for C-P, C-N */ goal column, return the best choice for the offset. The offset is
returned. Used by "C-N" and "C-P".
/*
* This routine, given a pointer to a struct line, and the current cursor goal
* column, return the best choice for the offset. The offset is returned.
* Used by "C-N" and "C-P".
*/ */
static unsigned getgoal( line_p dlp) { static unsigned getgoal( line_p dlp) {
int col ; int col = 0 ;
unsigned idx ; const unsigned len = llength( dlp) ;
const unsigned len = llength( dlp) ; unsigned idx = 0 ;
while( idx < len) {
unicode_t c ;
unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ;
col = 0 ; /* Take tabs, ^X and \xx hex characters into account */
idx = 0 ; if( c == '\t')
while( idx < len) { col += tabwidth - col % tabwidth ;
unicode_t c ; else if( c < 0x20 || c == 0x7F) /* ^x */
unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ; col += 2 ;
else if( c >= 0x80 && c <= 0xA0) /* \xx */
col += 3 ;
else {
int w = utf8_width( c) ; /* work around */
col += (w < 0) ? 2 : w ; /* unknown unicode width as \u */
}
/* Take tabs, ^X and \xx hex characters into account */ if( col > curgoal)
if( c == '\t') break ;
col += tabwidth - col % tabwidth ; else
else if( c < 0x20 || c == 0x7F) idx += width ;
col += 2 ; }
else if( c >= 0x80 && c <= 0xA0)
col += 3 ;
else
col += 1 ;
if( col > curgoal) return idx ;
break ;
idx += width ;
}
return idx ;
} }
/*
* Move the cursor to the beginning of the current line of active window. /* Move the cursor to the beginning of the current line of active window. */
*/
boolean gotobol( int f, int n) { boolean gotobol( int f, int n) {
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
return TRUE ; return TRUE ;
} }
/*
* Move the cursor to the end of the current line of active window. /* Move the cursor to the end of the current line of active window. */
*/
boolean gotoeol( int f, int n) { boolean gotoeol( int f, int n) {
curwp->w_doto = llength( curwp->w_dotp) ; curwp->w_doto = llength( curwp->w_dotp) ;
return TRUE ; return TRUE ;
} }
/*
* Goto the beginning of the buffer. Massive adjustment of dot. This is /* Goto the beginning of the buffer. Massive adjustment of dot. This is
* considered to be hard motion; it really isn't if the original value of dot considered to be hard motion; it really isn't if the original value of
* is the same as the new value of dot. Normally bound to "M-<". dot is the same as the new value of dot. Normally bound to "M-<".
*/ */
boolean gotobob( int f, int n) { boolean gotobob( int f, int n) {
curwp->w_dotp = lforw( curbp->b_linep) ; curwp->w_dotp = lforw( curbp->b_linep) ;
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ; curwp->w_flag |= WFHARD ;
return TRUE ; return TRUE ;
} }
/*
* Move to the end of the buffer. Dot is always put at the end of the file /* Move to the end of the buffer. Dot is always put at the end of the file
* (ZJ). The standard screen code does most of the hard parts of update. (ZJ). The standard screen code does most of the hard parts of update.
* Bound to "M->". Bound to "M->".
*/ */
boolean gotoeob( int f, int n) { boolean gotoeob( int f, int n) {
curwp->w_dotp = curbp->b_linep ; curwp->w_dotp = curbp->b_linep ;
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ; curwp->w_flag |= WFHARD ;
return TRUE ; return TRUE ;
} }
/*
* Move forward by full lines. If the number of lines to move is less than /* Move forward by full lines. If the number of lines to move is less than
* zero, call the backward line function to actually do it. The last command zero, call the backward line function to actually do it. The last
* controls how the goal column is set. Bound to "C-N". No errors are command controls how the goal column is set. Bound to "C-N". No errors
* possible. are possible.
*/ */
boolean forwline( int f, int n) { boolean forwline( int f, int n) {
line_p dlp ; assert( f == TRUE || n == 1) ;
if( n < 0)
return backline( f, -n) ;
if (n < 0) /* if we are on the last line as we start....fail the command */
return backline(f, -n); if( n && curwp->w_dotp == curbp->b_linep)
return FALSE ;
/* if we are on the last line as we start....fail the command */ /* if the last command was not a line move, reset the goal column */
if (curwp->w_dotp == curbp->b_linep) if( (lastflag & CFCPCN) == 0)
return FALSE; curgoal = getccol( FALSE) ;
/* if the last command was not a line move, reset the goal column */ /* flag this command as a line move */
if ((lastflag & CFCPCN) == 0) thisflag |= CFCPCN ;
curgoal = getccol(FALSE);
/* flag this command as a line move */ /* and move the point down */
thisflag |= CFCPCN; line_p dlp = curwp->w_dotp ;
while( n && dlp != curbp->b_linep) {
dlp = lforw( dlp) ;
n -= 1 ;
}
/* and move the point down */ /* reseting the current position */
dlp = curwp->w_dotp; curwp->w_dotp = dlp ;
while( n && dlp != curbp->b_linep) { curwp->w_doto = getgoal( dlp) ;
dlp = lforw( dlp) ; curwp->w_flag |= WFMOVE ;
n -= 1 ; return (n == 0) ? TRUE : FALSE ;
}
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
} }
/*
* This function is like "forwline", but goes backwards. The scheme is exactly /* This function is like "forwline", but goes backwards. The scheme is
* the same. Check for arguments that are less than zero and call your exactly the same. Check for arguments that are less than zero and call
* alternate. Figure out the new line and call "movedot" to perform the your alternate. Figure out the new line and call "movedot" to perform
* motion. No errors are possible. Bound to "C-P". the motion. No errors are possible. Bound to "C-P".
*/ */
boolean backline( int f, int n) { boolean backline( int f, int n) {
line_p dlp ; if( n < 0)
return forwline( f, -n) ;
if (n < 0) /* if we are on the first line as we start....fail the command */
return forwline(f, -n); if( n && lback( curwp->w_dotp) == curbp->b_linep)
return FALSE ;
/* if we are on the first line as we start....fail the command */ /* if the last command was not a line move, reset the goal column */
if (lback(curwp->w_dotp) == curbp->b_linep) if( (lastflag & CFCPCN) == 0)
return FALSE; curgoal = getccol( FALSE) ;
/* if the last command was not a line move, reset the goal column */ /* flag this command as a line move */
if ((lastflag & CFCPCN) == 0) thisflag |= CFCPCN ;
curgoal = getccol(FALSE);
/* flag this command as a line move */ /* and move the point up */
thisflag |= CFCPCN; line_p dlp = curwp->w_dotp ;
while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ;
n -= 1 ;
}
/* and move the point up */ /* reseting the current position */
dlp = curwp->w_dotp; curwp->w_dotp = dlp ;
while( n && lback( dlp) != curbp->b_linep) { curwp->w_doto = getgoal( dlp) ;
dlp = lback( dlp) ; curwp->w_flag |= WFMOVE ;
n -= 1 ; return (n == 0) ? TRUE : FALSE ;
}
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
} }
/*
* Move to a particular line. /* Move to a particular line.
* *
* @n: The specified line position at the current buffer. * @n: The specified line position at the current buffer.
*/ */
int gotoline( int f, int n) { BINDABLE( gotoline) {
/* Get an argument if one doesnt exist. */ /* Get an argument if one doesn't exist. */
if( f == FALSE) { if( f == FALSE) {
int status ; char *arg ; /* Buffer to hold argument. */
char *arg ; /* Buffer to hold argument. */
status = newmlarg( &arg, "Line to GOTO: ", 0) ; int status = newmlarg( &arg, "goto-line: ", 0) ;
if( status != TRUE) { if( status != TRUE)
mloutstr( "(Aborted)") ; return status ;
return status ;
}
n = atoi( arg) ; n = atoi( arg) ;
free( arg) ; free( arg) ;
} f = TRUE ;
}
/* Handle the case where the user may be passed something like this: /* Handle the case where the user may be passed something like this:
* em filename + * ue filename +
* In this case we just go to the end of the buffer. * In this case we just go to the end of the buffer.
*/ */
if (n == 0) if( n == 0)
return gotoeob(f, n); return gotoeob( f, n) ;
/* If a bogus argument was passed, then returns false. */ /* If a bogus argument was passed, then returns false. */
if (n < 0) if( n < 0)
return FALSE; return FALSE ;
/* First, we go to the begin of the buffer. */ /* First, we go to the begin of the buffer. */
gotobob(f, n); gotobob( f, n) ;
return (n == 1) ? TRUE : forwline( f, n - 1) ; return (n == 1) ? TRUE : forwline( TRUE, n - 1) ;
} }
/*
* Scroll forward by a specified number of lines, or by a full page if no /* Scroll forward by a specified number of lines, or by a full page if no
* argument. Bound to "C-V". The "2" in the arithmetic on the window size is argument. Bound to "C-V". The "2" in the arithmetic on the window size
* the overlap; this value is the default overlap value in ITS EMACS. Because is the overlap; this value is the default overlap value in ITS EMACS.
* this zaps the top line in the display window, we have to do a hard update. Because this zaps the top line in the display window, we have to do a
hard update.
*/ */
boolean forwpage( int f, int n) { boolean forwpage( int f, int n) {
line_p lp ; line_p lp ;
if (f == FALSE) { if( f == FALSE) {
#if SCROLLCODE #if SCROLLCODE
if (term.t_scroll != NULL) /* $scroll == FALSE */ if (term.t_scroll != NULL) /* $scroll == FALSE */
if (overlap == 0) /* $overlap == 0 */ if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ; n = curwp->w_ntrows * 2 / 3 ;
else else
n = curwp->w_ntrows - overlap; n = curwp->w_ntrows - overlap;
else else
#endif #endif
n = curwp->w_ntrows - 2; /* Default scroll. */ n = curwp->w_ntrows - 2; /* Default scroll. */
if (n <= 0) /* Forget the overlap. */ if (n <= 0) /* Forget the overlap. */
n = 1; /* If tiny window. */ n = 1; /* If tiny window. */
} else if (n < 0) } else if( n < 0)
return backpage(f, -n); return backpage(f, -n);
#if CVMVAS #if CVMVAS
else /* Convert from pages. */ else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */ n *= curwp->w_ntrows; /* To lines. */
#endif #endif
/* lp = curwp->w_linep; */ /* lp = curwp->w_linep; */
lp = curwp->w_dotp ; lp = curwp->w_dotp ;
while( n && lp != curbp->b_linep) { while( n && lp != curbp->b_linep) {
lp = lforw( lp) ; lp = lforw( lp) ;
n -= 1 ; n -= 1 ;
} }
/* curwp->w_linep = lp; */ /* curwp->w_linep = lp; */
curwp->w_dotp = lp; curwp->w_dotp = lp;
curwp->w_doto = 0; curwp->w_doto = 0;
reposition( TRUE, 0) ; reposition( TRUE, 0) ;
#if SCROLLCODE #if SCROLLCODE
curwp->w_flag |= WFHARD | WFKILLS; curwp->w_flag |= WFHARD | WFKILLS;
#else #else
curwp->w_flag |= WFHARD; curwp->w_flag |= WFHARD;
#endif #endif
return TRUE; return TRUE ;
} }
/*
* This command is like "forwpage", but it goes backwards. The "2", like /* This command is like "forwpage", but it goes backwards. The "2", like
* above, is the overlap between the two windows. The value is from the ITS above, is the overlap between the two windows. The value is from the
* EMACS manual. Bound to "M-V". We do a hard update for exactly the same ITS EMACS manual. Bound to "M-V". We do a hard update for exactly the
* reason. same reason.
*/ */
boolean backpage( int f, int n) { boolean backpage( int f, int n) {
line_p lp ; line_p lp ;
if (f == FALSE) { /* interactive, default n = 1 supplied */ if( f == FALSE) { /* interactive, default n = 1 supplied */
/* in interactive mode, first move dot to top of window */ /* in interactive mode, first move dot to top of window */
if( curwp->w_dotp != curwp->w_linep) { if( curwp->w_dotp != curwp->w_linep) {
curwp->w_dotp = curwp->w_linep ; curwp->w_dotp = curwp->w_linep ;
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
/* curwp->w_flag |= WFMOVE ; */ /* curwp->w_flag |= WFMOVE ; */
return TRUE ; return TRUE ;
} }
#if SCROLLCODE #if SCROLLCODE
if (term.t_scroll != NULL) /* $scroll != FALSE */ if (term.t_scroll != NULL) /* $scroll != FALSE */
if (overlap == 0) /* $overlap == 0 */ if (overlap == 0) /* $overlap == 0 */
n = curwp->w_ntrows * 2 / 3 ; n = curwp->w_ntrows * 2 / 3 ;
else else
n = curwp->w_ntrows - overlap; n = curwp->w_ntrows - overlap;
else else
#endif #endif
n = curwp->w_ntrows - 2; /* Default scroll. */ n = curwp->w_ntrows - 2; /* Default scroll. */
if (n <= 0) /* Don't blow up if the. */ if (n <= 0) /* Don't blow up if the. */
n = 1; /* Window is tiny. */ n = 1; /* Window is tiny. */
} else if (n < 0) } else if (n < 0)
return forwpage(f, -n); return forwpage(f, -n);
#if CVMVAS #if CVMVAS
else /* Convert from pages. */ else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */ n *= curwp->w_ntrows; /* To lines. */
#endif #endif
/* lp = curwp->w_linep; */ /* lp = curwp->w_linep; */
lp = curwp->w_dotp ; lp = curwp->w_dotp ;
while( n && lback( lp) != curbp->b_linep) { while( n && lback( lp) != curbp->b_linep) {
lp = lback( lp) ; lp = lback( lp) ;
n -= 1 ; n -= 1 ;
} }
/* curwp->w_linep = lp; */ /* curwp->w_linep = lp; */
curwp->w_dotp = lp; curwp->w_dotp = lp;
curwp->w_doto = 0; curwp->w_doto = 0;
reposition( TRUE, (f == FALSE) ? 1 : 0) ; reposition( TRUE, (f == FALSE) ? 1 : 0) ;
#if SCROLLCODE #if SCROLLCODE
curwp->w_flag |= WFHARD | WFINS; curwp->w_flag |= WFHARD | WFINS;
#else #else
curwp->w_flag |= WFHARD; curwp->w_flag |= WFHARD;
#endif #endif
return TRUE; return TRUE;
} }
/*
* Set the mark in the current window to the value of "." in the window. No /* Set the mark in the current window to the value of "." in the window.
* errors are possible. Bound to "M-.". No errors are possible. Bound to M-. set-mark.
*/ */
boolean setmark( int f, int n) { boolean setmark( int f, int n) {
curwp->w_markp = curwp->w_dotp; curwp->w_markp = curwp->w_dotp ;
curwp->w_marko = curwp->w_doto; curwp->w_marko = curwp->w_doto ;
mloutstr( "(Mark set)") ; mloutstr( "(Mark set)") ;
return TRUE ; return TRUE ;
} }
/* /* Swap the values of "." and "mark" in the current window. If no mark as
* Swap the values of "." and "mark" in the current window. This is pretty been previously set, set it. Bound to C-X C-X exchange-point-and-mark.
* easy, because all of the hard work gets done by the standard routine
* that moves the mark about. The only possible error is "no mark". Bound to
* "C-X C-X".
*/ */
boolean swapmark( int f, int n) { boolean swapmark( int f, int n) {
line_p odotp ; line_p odotp = curwp->w_dotp ;
int odoto; int odoto = curwp->w_doto ;
if( curwp->w_markp) {
curwp->w_dotp = curwp->w_markp ;
curwp->w_doto = curwp->w_marko ;
curwp->w_flag |= WFMOVE ;
}
if( curwp->w_markp == NULL) { curwp->w_markp = odotp ;
mloutstr( "No mark in this window") ; curwp->w_marko = odoto ;
return FALSE ; return TRUE ;
}
odotp = curwp->w_dotp;
odoto = curwp->w_doto;
curwp->w_dotp = curwp->w_markp;
curwp->w_doto = curwp->w_marko;
curwp->w_markp = odotp;
curwp->w_marko = odoto;
curwp->w_flag |= WFMOVE;
return TRUE;
} }
/* end of basic.c */ /* end of basic.c */

19
basic.h
View File

@ -3,24 +3,23 @@
#ifndef _BASIC_H_ #ifndef _BASIC_H_
#define _BASIC_H_ #define _BASIC_H_
#include "retcode.h" #include "names.h"
/* /* $overlap is the size of the line overlap when kbd calls page forw/back
** $overlap is the size of the line overlap when kbd calls page forw/back if 0, page will move by 2/3 of the window size (1/3 page overlap)
** if 0, page will move by 2/3 of the window size (1/3 page overlap) default to 0
** default to 0 */
*/ extern int overlap ; /* $overlap: line overlap in forw/back page */
#define DEFAULT_OVERLAP 0
extern int overlap ; /* line overlap in forw/back page */
/* $target (== curgoal) is the column target when doing line move */ /* $target (== curgoal) is the column target when doing line move */
extern int curgoal ; /* Goal for C-P previous-line, C-N next-line */ extern int curgoal ; /* $target: Goal for C-P previous-line, C-N next-line */
/* Bindable functions */
boolean gotobol( int f, int n) ; boolean gotobol( int f, int n) ;
boolean gotoeol( int f, int n) ; boolean gotoeol( int f, int n) ;
int gotoline( int f, int n) ; BINDABLE( gotoline) ;
boolean gotobob( int f, int n) ; boolean gotobob( int f, int n) ;
boolean gotoeob( int f, int n) ; boolean gotoeob( int f, int n) ;
boolean forwline( int f, int n) ; boolean forwline( int f, int n) ;