📄 block.c
字号:
xbc = bc + block_len;
if (lens <= (ec + block_len + 1))
add = lens - xbc;
}
}
if (add > 0)
*rc = delete_box_block( &s_w, source, xbc, add );
}
}
}
/*
* if we are doing any BOX action we need to move the source pointer
* to the next line.
*/
source = source->next;
/*
* if we are doing any action other than DELETE, we need to move
* the destination to the next line in marked block.
* In BOX mode, we may need to pad the end of the file
* with a blank line before we process the next line.
*/
if (action != DELETE && action != FILL && action != NUMBER) {
p = dest->next;
if (p->len != EOF)
dest = p;
else if (li < er) {
padded_file = TRUE;
pad_dest_line( window, dest_file, p );
dest = dest->next;
}
}
}
}
if (block_buff != NULL)
free( block_buff );
if (swap_buff != NULL)
free( swap_buff );
if (padded_file) {
w = g_status.window_list;
while (w != NULL) {
if (w->file_info == dest_file && w->visible)
show_size( w );
w = w->next;
}
}
show_avail_mem( );
}
/*
* Name: load_box_buff
* Class: helper function
* Purpose: copy the contents of a BOX to a block buffer.
* Date: June 5, 1991
* Passed: block_buff: local buffer for block moves
* ll: node to source line in file to load
* bc: beginning column of BOX. used only in BOX operations.
* ec: ending column of BOX. used only in BOX operations.
* filler: character to fill boxes that end past eol
* Notes: For BOX blocks, there are several things to take care of:
* 1) The BOX begins and ends within a line - just copy the blocked
* characters to the block buff. 2) the BOX begins within a line
* but ends past the eol - copy all the characters within the line
* to the block buff then fill with padding. 3) the BOX begins and
* ends past eol - fill entire block buff with padding (filler).
* the fill character varies with the block operation. for sorting
* a box block, the fill character is '\0'. for adding text to
* the file, the fill character is a space.
*/
void load_box_buff( char *block_buff, line_list_ptr ll, int bc, int ec,
char filler )
{
int len;
int avlen;
register int i;
register char *bb;
text_ptr s;
assert( bc >= 0 );
assert( ec >= bc );
assert( ec < MAX_LINE_LENGTH );
bb = block_buff;
len = ll->len;
s = detab_a_line( ll->line, &len );
/*
* block start may be past eol
*/
if (len < ec + 1) {
/*
* does block start past eol? - fill with pad
*/
assert( ec + 1 - bc >= 0 );
memset( block_buff, filler, (ec + 1) - bc );
if (len >= bc) {
/*
* block ends past eol - fill with pad
*/
avlen = len - bc;
s += bc;
for (i=avlen; i>0; i--)
*bb++ = *s++;
}
} else {
/*
* block is within line - copy block to buffer
*/
avlen = (ec + 1) - bc;
s = s + bc;
for (i=avlen; i>0; i--)
*bb++ = *s++;
}
}
/*
* Name: copy_buff_2file
* Class: helper function
* Purpose: copy the contents of block buffer to destination file
* Date: June 5, 1991
* Passed: window: pointer to current window
* block_buff: local buffer for moves
* dest: pointer to destination line in destination file
* rcol: if in BOX mode, destination column in destination file
* block_len: if in BOX mode, width of block to copy
* action: type of block action
* Notes: In BOX mode, the destination line has already been prepared.
* Just copy the BOX buffer to the destination line.
*/
int copy_buff_2file( WINDOW *window, char *block_buff, line_list_ptr dest,
int rcol, int block_len, int action )
{
char *s;
char *d;
int len;
int pad;
int add;
copy_line( dest );
if (mode.inflate_tabs)
detab_linebuff( );
len = g_status.line_buff_len;
assert( len >= 0 );
assert( len < MAX_LINE_LENGTH );
assert( rcol >= 0 );
assert( rcol < MAX_LINE_LENGTH );
assert( block_len >= 0 );
assert( block_len < BUFF_SIZE );
if (rcol > len) {
pad = rcol - len;
assert( pad >= 0 );
assert( pad < MAX_LINE_LENGTH );
memset( g_status.line_buff + len, ' ', pad );
len += pad;
}
s = g_status.line_buff + rcol;
/*
* s is pointing to location to perform BOX operation. If we do a
* FILL or OVERLAY, we do not necessarily add any extra space. If the
* line does not extend all the thru the BOX then we add.
* we always add space when we COPY, KOPY, or MOVE
*/
if (action == FILL || action == OVERLAY || action == NUMBER || action == SWAP) {
add = len - rcol;
if (add < block_len) {
pad = block_len - add;
assert( pad >= 0 );
assert( pad < MAX_LINE_LENGTH );
memset( g_status.line_buff + len, ' ', pad );
len += pad;
}
} else {
d = s + block_len;
add = len - rcol;
assert( add >= 0 );
assert( add < MAX_LINE_LENGTH );
memmove( d, s, add );
len += block_len;
}
assert( rcol + block_len <= len );
assert( len >= 0 );
assert( len < MAX_LINE_LENGTH );
memmove( s, block_buff, block_len );
g_status.line_buff_len = len;
if (mode.inflate_tabs)
entab_linebuff( );
return( un_copy_line( dest, window, TRUE ) );
}
/*
* Name: block_fill
* Class: helper function
* Purpose: fill the block buffer with character
* Date: June 5, 1991
* Passed: block_buff: local buffer for moves
* fill_char: fill character
* block_len: number of columns in block
* Notes: Fill block_buffer for block_len characters using fill_char. This
* function is used only for BOX blocks.
*/
void block_fill( char *block_buff, int fill_char, int block_len )
{
assert( block_len >= 0 );
assert( block_len < BUFF_SIZE );
assert( block_buff != NULL );
memset( block_buff, fill_char, block_len );
}
/*
* Name: number_block_buff
* Class: helper function
* Purpose: put a number into the block buffer
* Date: June 5, 1991
* Passed: block_buff: local buffer for moves
* block_len: number of columns in block
* block_num: long number to fill block
* just: LEFT or RIGHT justified?
* Notes: Fill block_buffer for block_len characters with number.
* This function is used only for BOX blocks.
*/
void number_block_buff( char *block_buff, int block_len, long block_num,
int just )
{
int len; /* length of number buffer */
int i;
char temp[MAX_COLS]; /* buffer for long number to ascii conversion */
assert( block_len >= 0 );
assert( block_len < BUFF_SIZE );
block_fill( block_buff, ' ', block_len );
len = strlen( ltoa( block_num, temp, 10 ) );
if (just == RIGHT) {
block_len--;
len--;
for (;block_len >= 0 && len >= 0; block_len--, len--)
block_buff[block_len] = temp[len];
} else {
for (i=0; block_len > 0 && i < len; block_len--, i++)
block_buff[i] = temp[i];
}
}
/*
* Name: restore_cursors
* Class: helper function
* Purpose: a file has been modified - must restore all cursor pointers
* Date: June 5, 1991
* Passed: file: pointer to file with changes
* Notes: Go through the window list and adjust the cursor pointers
* as needed.
*/
void restore_cursors( file_infos *file )
{
register WINDOW *window;
line_list_ptr ll;
long n;
assert( file != NULL );
window = g_status.window_list;
while (window != NULL) {
if (window->file_info == file) {
window->bin_offset = 0;
if (window->rline < 1L)
window->rline = 1L;
if (window->rline > file->length)
window->rline = file->length;
ll = file->line_list;
n = 1L;
for (; n < window->rline; n++) {
window->bin_offset += ll->len;
ll = ll->next;
}
window->ll = ll;
if (window->rline < (window->cline - (window->top_line+window->ruler-1)))
window->cline = (int)window->rline + window->top_line+window->ruler-1;
if (window->cline < window->top_line + window->ruler)
window->cline = window->top_line + window->ruler;
if (window->visible)
show_size( window );
}
window = window->next;
}
}
/*
* Name: delete_box_block
* Class: helper function
* Purpose: delete the marked text
* Date: June 5, 1991
* Passed: s_w: source window
* source: pointer to line with block to delete
* bc: beginning column of block - BOX mode only
* add: number of characters in block to delete
* Notes: Used only for BOX blocks. Delete the block.
*/
int delete_box_block( WINDOW *s_w, line_list_ptr source, int bc, int add )
{
char *s;
int number;
assert( s_w != NULL );
assert( source != NULL );
assert( bc >= 0 );
assert( bc < MAX_LINE_LENGTH );
assert( add >= 0 );
assert( add < MAX_LINE_LENGTH );
copy_line( source );
detab_linebuff( );
number = g_status.line_buff_len - bc;
s = g_status.line_buff + bc + add;
assert( number >= 0 );
assert( number < MAX_LINE_LENGTH );
assert( bc + add >= 0 );
assert( bc + add < MAX_LINE_LENGTH );
assert( add <= g_status.line_buff_len );
memmove( s - add, s, number );
g_status.line_buff_len -= add;
entab_linebuff( );
return( un_copy_line( source, s_w, TRUE ) );
}
/*
* Name: check_block
* Class: helper function
* Purpose: To check that the block is still valid.
* Date: June 5, 1991
* Notes: After some editing, the marked block may not be valid. For example,
* deleting all the lines in a block in another window. We don't
* need to keep up with the block text pointers while doing normal
* editing; however, we need to refresh them before doing block stuff.
*/
void check_block( void )
{
register file_infos *file;
WINDOW filler;
file = g_status.marked_file;
if (file == NULL || file->block_br > file->length)
unmark_block( &filler );
else {
if (file->block_er > file->length)
file->block_er = file->length;
find_begblock( file );
find_endblock( file );
}
}
/*
* Name: find_begblock
* Class: helper editor function
* Purpose: find the beginning line in file with marked block
* Date: June 5, 1991
* Passed: file: file containing marked block
* Notes: file->block_start contains starting line of marked block.
*/
void find_begblock( file_infos *file )
{
line_list_ptr ll;
long li; /* line counter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -