#include "tdestr.h"
#include "common.h"
#include "tdefunc.h"
#include "define.h"
int mark_block( WINDOW *window )
{
int type;
int num;
long lnum;
register file_infos *file; /* 临时文件 */
register WINDOW *win; /* 把当前窗口指针放到一个临时寄存器里面 */
int rc;
win = window;
file = win->file_info;
if (win->rline > file->length || win->ll->len == EOF)
return( ERROR );
if (g_status.marked == FALSE) {
g_status.marked = TRUE;
g_status.marked_file = file;
}
if (g_status.command == MarkBox)
type = BOX;
else if (g_status.command == MarkLine)
type = LINE;
else if (g_status.command == MarkStream)
type = STREAM;
else
return( ERROR );
rc = OK;
/*
* 仅对于一个文件定义块。用户可以在这个文件的任何窗口进行操作。
*/
if (file == g_status.marked_file) {
/*
* 不管块的模式标识块的起始和中止位置
*/
if (file->block_type == NOTMARKED) {
file->block_ec = file->block_bc = win->rcol;
file->block_er = file->block_br = win->rline;
} else {
if (file->block_br > win->rline) {
file->block_br = win->rline;
if (file->block_bc < win->rcol && type != STREAM)
file->block_ec = win->rcol;
else
file->block_bc = win->rcol;
} else {
if (type != STREAM) {
file->block_ec = win->rcol;
file->block_er = win->rline;
} else {
if (win->rline == file->block_br &&
win->rline == file->block_er) {
if (win->rcol < file->block_bc)
file->block_bc = win->rcol;
else
file->block_ec = win->rcol;
} else if (win->rline == file->block_br)
file->block_bc = win->rcol;
else {
file->block_ec = win->rcol;
file->block_er = win->rline;
}
}
}
/*
* 如果用户标识的块的终止位置在起始位置前,那么交换两个位置。
*/
if (file->block_er < file->block_br) {
lnum = file->block_er;
file->block_er = file->block_br;
file->block_br = lnum;
}
/*
* 如果用户标识的块的终止列在起始列前,那么交换两个位置。
*/
if ((file->block_ec < file->block_bc) && (type != STREAM ||
(type == STREAM && file->block_br == file->block_er))) {
num = file->block_ec;
file->block_ec = file->block_bc;
file->block_bc = num;
}
}
/*
* 如果块类型已经被定义,但是如果用户使用混和模式,那么块的
* 类型被置为当前块的类型
*/
if (file->block_type != NOTMARKED) {
/*
* 如果块的类型是矩形块,那么要保证左上角小于右下脚
* 如果块的类型是stream块,那么保证起始列小于中止列
*/
if (type == BOX) {
if (file->block_ec < file->block_bc) {
num = file->block_ec;
file->block_ec = file->block_bc;
file->block_bc = num;
}
}
}
assert( file->block_er >= file->block_br );
file->block_type = type;
file->dirty = GLOBAL;
} else {
/*
* 已经定义好块
*/
error( WARNING, win->bottom_line, block1 );
rc = ERROR;
}
return( rc );
}
/*
* Name: unmark_block
* Class: primary editor function
* Purpose: To set all block information to NULL or 0
* Date: June 5, 1991
* Passed: arg_filler: variable to match array of function pointers prototype
* Notes: Reset all block variables if marked, otherwise return.
* If a marked block is unmarked then redraw the screen(s).
*/
int unmark_block( WINDOW *arg_filler )
{
register file_infos *marked_file;
if (g_status.marked == TRUE) {
marked_file = g_status.marked_file;
g_status.marked = FALSE;
g_status.marked_file = NULL;
marked_file->block_start = NULL;
marked_file->block_end = NULL;
marked_file->block_bc = marked_file->block_ec = 0;
marked_file->block_br = marked_file->block_er = 0l;
if (marked_file->block_type)
marked_file->dirty = GLOBAL;
marked_file->block_type = NOTMARKED;
}
return( OK );
}
/*
* Name: restore_marked_block
* Class: helper function
* Purpose: To restore block beginning and ending row after an editing function
* Date: June 5, 1991
* Passed: window: pointer to current window
* net_change: number of bytes added or subtracted
* Notes: If a change has been made before the marked block then the
* beginning and ending row need to be adjusted by the number of
* lines added or subtracted from file.
*/
void restore_marked_block( WINDOW *window, int net_change )
{
long length;
register file_infos *marked_file;
if (g_status.marked == TRUE && net_change != 0) {
marked_file = g_status.marked_file;
length = marked_file->length;
/*
* restore is needed only if a block is defined and window->file_info is
* same as marked file and there was a net change in file length.
*/
if (marked_file == window->file_info) {
/*
* if cursor is before marked block then adjust block by net change.
*/
if (marked_file->block_br > window->rline) {
marked_file->block_br += net_change;
marked_file->block_er += net_change;
marked_file->dirty = GLOBAL;
/*
* if cursor is somewhere in marked block don't restore, do redisplay
*/
} else if (marked_file->block_er >= window->rline)
marked_file->dirty = GLOBAL;
/*
* check for lines of marked block beyond end of file
*/
if (marked_file->block_br > length)
unmark_block( window );
else if (marked_file->block_er > length) {
marked_file->block_er = length;
marked_file->dirty = GLOBAL;
}
}
}
}
/*
* Name: prepare_block
* Class: helper function
* Purpose: To prepare a window/file for a block read, move or copy.
* Date: June 5, 1991
* Passed: window: pointer to current window
* file: pointer to file information.
* text_line: pointer to line in file to prepare.
* lend: line length.
* bc: beginning column of BOX.
* Notes: The main complication is that the cursor may be beyond the end
* of the current line, in which case extra padding spaces have
* to be added before the block operation can take place.
* this only occurs in BOX and STREAM operations.
* since we are padding a line, do not trim trailing space.
*/
int prepare_block( WINDOW *window, line_list_ptr ll, int bc )
{
register int pad = 0; /* amount of padding to be added */
register int len;
assert( bc >= 0 );
assert( bc < MAX_LINE_LENGTH );
assert( ll->len != EOF );
assert( g_status.copied == FALSE );
copy_line( ll );
detab_linebuff( );
len = g_status.line_buff_len;
pad = bc - len;
if (pad > 0) {
/*
* insert the padding spaces
*/
assert( pad >= 0 );
assert( pad < MAX_LINE_LENGTH );
memset( g_status.line_buff+len, ' ', pad );
g_status.line_buff_len += pad;
}
/*
* if mode.inflate_tabs, let's don't entab the line until we get
* thru processing this line, e.g. copying, numbering....
*/
return( un_copy_line( ll, window, FALSE ) );
}
/*
* Name: pad_dest_line
- 1
- 2
- 3
- 4
前往页