2013-05-20 01:16:08 -04:00
|
|
|
/* region.c -- implements region.h */
|
|
|
|
#include "region.h"
|
|
|
|
|
2021-08-07 09:34:13 -04:00
|
|
|
/* The routines in this file deal with the region, that magic space between
|
|
|
|
"." and mark. Some functions are commands. Some functions are just for
|
|
|
|
internal use.
|
|
|
|
|
|
|
|
Modified by Petri Kutvonen
|
2005-05-31 11:50:56 -04:00
|
|
|
*/
|
|
|
|
|
2021-07-19 08:50:32 -04:00
|
|
|
#include <assert.h>
|
2021-08-11 05:02:19 -04:00
|
|
|
#include <stddef.h>
|
2010-11-14 21:10:03 -05:00
|
|
|
|
2013-09-20 06:10:30 -04:00
|
|
|
#include "buffer.h"
|
2021-08-18 04:54:35 -04:00
|
|
|
#include "defines.h"
|
2010-11-14 21:10:03 -05:00
|
|
|
#include "line.h"
|
2015-02-12 23:31:59 -05:00
|
|
|
#include "mlout.h"
|
2013-10-10 00:33:13 -04:00
|
|
|
#include "random.h"
|
2013-09-20 06:10:30 -04:00
|
|
|
#include "window.h"
|
2005-05-31 11:50:56 -04:00
|
|
|
|
2021-08-07 09:34:13 -04:00
|
|
|
/* Kill the region. Ask getregion() to figure out the bounds of the
|
|
|
|
region. Move "." to the start, and kill the characters. Bound to C-W
|
|
|
|
kill-region.
|
2005-05-31 11:50:56 -04:00
|
|
|
*/
|
2021-08-03 01:37:06 -04:00
|
|
|
BINDABLE( killregion) {
|
2021-08-07 09:34:13 -04:00
|
|
|
region_t region ;
|
2005-05-31 11:50:56 -04:00
|
|
|
|
2021-07-19 08:50:32 -04:00
|
|
|
assert( !(curbp->b_mode & MDVIEW)) ;
|
2021-08-07 09:34:13 -04:00
|
|
|
|
|
|
|
int ret = getregion( ®ion) ;
|
|
|
|
if( ret != TRUE)
|
|
|
|
return ret ;
|
|
|
|
|
|
|
|
if( (lastflag & CFKILL) == 0) /* This is a kill type */
|
|
|
|
kdelete() ; /* command, so do magic */
|
|
|
|
|
|
|
|
thisflag |= CFKILL ; /* kill buffer stuff. */
|
|
|
|
curwp->w_dotp = region.r_linep ;
|
|
|
|
curwp->w_doto = region.r_offset ;
|
|
|
|
return ldelete( region.r_size, TRUE) ;
|
2005-05-31 11:50:56 -04:00
|
|
|
}
|
|
|
|
|
2021-08-03 01:37:06 -04:00
|
|
|
/* Copy all of the characters in the region to the kill buffer. Don't move
|
2021-08-07 09:34:13 -04:00
|
|
|
dot at all. This is a bit like a kill region followed by a yank. Bound
|
|
|
|
to M-W copy-region.
|
2005-05-31 11:50:56 -04:00
|
|
|
*/
|
2021-08-03 01:37:06 -04:00
|
|
|
BINDABLE( copyregion) {
|
2021-08-07 09:34:13 -04:00
|
|
|
region_t region ;
|
|
|
|
|
|
|
|
int ret = getregion( ®ion) ;
|
|
|
|
if( ret != TRUE)
|
|
|
|
return ret ;
|
|
|
|
|
|
|
|
if( (lastflag & CFKILL) == 0) /* Kill type command. */
|
|
|
|
kdelete() ;
|
|
|
|
|
|
|
|
thisflag |= CFKILL ;
|
|
|
|
line_p linep = region.r_linep ; /* Current line. */
|
|
|
|
int loffs = region.r_offset ; /* Current offset. */
|
|
|
|
while( region.r_size--) {
|
|
|
|
if( loffs == llength( linep)) { /* End of line. */
|
|
|
|
ret = kinsert( '\n') ;
|
|
|
|
if( ret != TRUE)
|
|
|
|
return ret ;
|
|
|
|
|
|
|
|
linep = lforw( linep) ;
|
|
|
|
loffs = 0 ;
|
2005-09-30 18:26:09 -04:00
|
|
|
} else { /* Middle of line. */
|
2021-08-07 09:34:13 -04:00
|
|
|
ret = kinsert( lgetc( linep, loffs)) ;
|
|
|
|
if( ret != TRUE)
|
|
|
|
return ret ;
|
|
|
|
|
|
|
|
++loffs ;
|
2005-09-30 18:26:09 -04:00
|
|
|
}
|
|
|
|
}
|
2021-08-07 09:34:13 -04:00
|
|
|
|
2015-02-12 23:31:59 -05:00
|
|
|
mloutstr( "(region copied)") ;
|
2021-08-07 09:34:13 -04:00
|
|
|
return TRUE ;
|
2005-05-31 11:50:56 -04:00
|
|
|
}
|
|
|
|
|
2021-08-07 09:34:13 -04:00
|
|
|
/* Lower case region & Upper case region. Zap all of the upper/lower case
|
|
|
|
characters in the region to lower/upper case. Use the region code to
|
|
|
|
set the limits. Scan the buffer, doing the changes. Call "lchange" to
|
|
|
|
ensure that redisplay is done in all buffers. Bound to C-X C-L
|
|
|
|
case-region-lower and C-X C-U case-region-upper.
|
2005-05-31 11:50:56 -04:00
|
|
|
*/
|
2021-08-07 09:34:13 -04:00
|
|
|
static int utol( int c) {
|
|
|
|
return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : -1 ;
|
|
|
|
}
|
2005-05-31 11:50:56 -04:00
|
|
|
|
2021-08-07 09:34:13 -04:00
|
|
|
static int ltou( int c) {
|
|
|
|
return (c >= 'a' && c <= 'z') ? c + 'A' - 'a' : -1 ;
|
2005-05-31 11:50:56 -04:00
|
|
|
}
|
|
|
|
|
2021-08-07 09:34:13 -04:00
|
|
|
static int caseregion( int (* cconv)( int)) {
|
|
|
|
region_t region ;
|
2005-05-31 11:50:56 -04:00
|
|
|
|
2021-07-19 08:50:32 -04:00
|
|
|
assert( !(curbp->b_mode & MDVIEW)) ;
|
|
|
|
|
2021-08-07 09:34:13 -04:00
|
|
|
int ret = getregion( ®ion) ;
|
|
|
|
if( ret != TRUE)
|
|
|
|
return ret ;
|
|
|
|
|
|
|
|
lchange( WFHARD) ;
|
|
|
|
line_p linep = region.r_linep ;
|
|
|
|
int loffs = region.r_offset ;
|
|
|
|
while( region.r_size--) {
|
|
|
|
if( loffs == llength( linep)) {
|
|
|
|
linep = lforw( linep) ;
|
|
|
|
loffs = 0 ;
|
2005-09-30 18:26:09 -04:00
|
|
|
} else {
|
2021-08-07 09:34:13 -04:00
|
|
|
int c = cconv( lgetc( linep, loffs)) ;
|
|
|
|
if( c != -1)
|
|
|
|
lputc( linep, loffs, c) ;
|
|
|
|
|
|
|
|
++loffs ;
|
2005-09-30 18:26:09 -04:00
|
|
|
}
|
|
|
|
}
|
2021-08-07 09:34:13 -04:00
|
|
|
|
|
|
|
return TRUE ;
|
|
|
|
}
|
|
|
|
|
|
|
|
BINDABLE( lowerregion) {
|
|
|
|
return caseregion( utol) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
BINDABLE( upperregion) {
|
|
|
|
return caseregion( ltou) ;
|
2005-05-31 11:50:56 -04:00
|
|
|
}
|
|
|
|
|
2021-08-03 01:37:06 -04:00
|
|
|
/* This routine figures out the bounds of the region in the current window,
|
|
|
|
* and fills in the fields of the "region_t" structure pointed to by "rp".
|
|
|
|
* Because the dot and mark are usually very close together, we scan
|
|
|
|
* outward from dot looking for mark. This should save time. Return a
|
|
|
|
* standard code. Callers of this routine should be prepared to get an
|
|
|
|
* "ABORT" status; we might make this have the conform thing later.
|
2005-05-31 11:50:56 -04:00
|
|
|
*/
|
2021-08-03 01:37:06 -04:00
|
|
|
int getregion( region_p rp) {
|
|
|
|
line_p flp, blp ;
|
|
|
|
long fsize, bsize ;
|
2005-05-31 11:50:56 -04:00
|
|
|
|
2021-08-11 05:02:19 -04:00
|
|
|
if (curwp->w_markp == NULL)
|
|
|
|
return mloutfail( "No mark set in this window") ;
|
|
|
|
|
2005-09-30 18:26:09 -04:00
|
|
|
if (curwp->w_dotp == curwp->w_markp) {
|
|
|
|
rp->r_linep = curwp->w_dotp;
|
|
|
|
if (curwp->w_doto < curwp->w_marko) {
|
|
|
|
rp->r_offset = curwp->w_doto;
|
|
|
|
rp->r_size =
|
|
|
|
(long) (curwp->w_marko - curwp->w_doto);
|
|
|
|
} else {
|
|
|
|
rp->r_offset = curwp->w_marko;
|
|
|
|
rp->r_size =
|
|
|
|
(long) (curwp->w_doto - curwp->w_marko);
|
|
|
|
}
|
2010-08-29 06:03:55 -04:00
|
|
|
return TRUE;
|
2005-09-30 18:26:09 -04:00
|
|
|
}
|
|
|
|
blp = curwp->w_dotp;
|
|
|
|
bsize = (long) curwp->w_doto;
|
|
|
|
flp = curwp->w_dotp;
|
|
|
|
fsize = (long) (llength(flp) - curwp->w_doto + 1);
|
|
|
|
while (flp != curbp->b_linep || lback(blp) != curbp->b_linep) {
|
|
|
|
if (flp != curbp->b_linep) {
|
|
|
|
flp = lforw(flp);
|
|
|
|
if (flp == curwp->w_markp) {
|
|
|
|
rp->r_linep = curwp->w_dotp;
|
|
|
|
rp->r_offset = curwp->w_doto;
|
|
|
|
rp->r_size = fsize + curwp->w_marko;
|
2010-08-29 06:03:55 -04:00
|
|
|
return TRUE;
|
2005-09-30 18:26:09 -04:00
|
|
|
}
|
|
|
|
fsize += llength(flp) + 1;
|
|
|
|
}
|
|
|
|
if (lback(blp) != curbp->b_linep) {
|
|
|
|
blp = lback(blp);
|
|
|
|
bsize += llength(blp) + 1;
|
|
|
|
if (blp == curwp->w_markp) {
|
|
|
|
rp->r_linep = blp;
|
|
|
|
rp->r_offset = curwp->w_marko;
|
|
|
|
rp->r_size = bsize - curwp->w_marko;
|
2010-08-29 06:03:55 -04:00
|
|
|
return TRUE;
|
2005-09-30 18:26:09 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-08-11 05:02:19 -04:00
|
|
|
|
|
|
|
return mloutfail( "Bug: lost mark") ;
|
2005-05-31 11:50:56 -04:00
|
|
|
}
|
2021-08-03 01:37:06 -04:00
|
|
|
|
|
|
|
/* end of region.c */
|