📄 block.c
字号:
}}/* * Name: shift_block * Class: helper function * Purpose: To shift block beginning/ending column after an editing function * Author: Jason Hood * Date: October 9, 1999 * Passed: file: pointer to file containing block * rline: line number where changed occurred * rcol: position within rline where changed occurred * net_change: number of characters added or removed * Notes: Only applies to the beginning or ending line of a STREAM block, * or a single-line BOX block. * Characters are added at rcol, removed before rcol. * shift_tabbed_block() should be called first (only for real tabs), * the line should be modified, and then this function called. */void shift_block( file_infos *file, long rline, int rcol, int net_change ){int type;int bc, ec;long br, er; type = abs( file->block_type ); br = file->block_br; er = file->block_er; if (net_change != 0 && ((type == BOX && rline == br && rline == er) || (type == STREAM && (rline == br || (rline == er && file->block_ec != -1))))) { if (tabbed_bc >= 0) { bc = tabbed_bc; ec = tabbed_ec; } else { bc = file->block_bc; ec = file->block_ec; } if (net_change > 0) { if (type == STREAM && br != er) { if (rline == br) { if (rcol <= bc) bc += net_change; } else { if (rcol <= ec) ec += net_change; } } else if (rcol <= ec) { ec += net_change; if (rcol <= bc) bc += net_change; } } else { if (type == STREAM && br != er) { if (rline == br) { if (rcol <= bc) bc += net_change; else if (rcol + net_change < bc) bc = rcol + net_change; } else { if (rcol <= ec) ec += net_change; else if (rcol + net_change < ec) { ec = rcol + net_change - 1; if (ec < 0) ec = 0; } } } else { if (rcol <= bc) { bc += net_change; if (ec != -1) ec += net_change; } else if (rcol <= ec) { ec += net_change; if (rcol + net_change < bc) bc = rcol + net_change; } else if (rcol + net_change <= ec) { ec = rcol + net_change - 1; if (ec < bc) { ec = file->block_bc; file->block_type = -type; if (g_status.marked && g_status.marked_file == file) { g_status.marked = FALSE; g_status.marked_file = NULL; } } } } } if (tabbed_bc >= 0) { bc = detab_adjust_rcol( g_status.line_buff, bc, file->ptab_size ) + tabbed_bc_ofs; if (ec != -1) ec = detab_adjust_rcol( g_status.line_buff, ec, file->ptab_size ) + tabbed_ec_ofs; } file->block_bc = bc; file->block_ec = ec; } tabbed_bc = tabbed_ec = -1;}/* * 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( TDE_WIN *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, window, TRUE ); 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 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, FALSE ) );}/* * Name: pad_dest_line * Class: helper function * Purpose: To prepare a window/file for a block move or copy. * Date: June 5, 1991 * Passed: window: pointer to current window * dest_file: pointer to file information. * dest_line: pointer to line in file to prepare. * ll: pointer to linked list node to insert new node * Notes: We are doing a BOX action (except DELETE). We have come * to the end of the file and have no more lines. All this * routine does is add a blank line to file. */int pad_dest_line( TDE_WIN *window, file_infos *dest_file, line_list_ptr ll ){int rc;line_list_ptr new_node; rc = OK; new_node = new_line( 0, &rc ); if (rc == OK) insert_node( dest_file, ll, new_node ); else { /* * file too big */ error( WARNING, window->bottom_line, block4 ); } return( rc );}/* * Name: block_operation * Class: primary editor function * Purpose: Master BOX, STREAM, or LINE routine. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Operations on BOXs, STREAMs, or LINEs require several common * operations. All require finding the beginning and ending marks. * This routine will handle block operations across files. Since one * must determine the relationship of source and destination blocks * within a file, it is relatively easy to expand this relationship * across files. * This is probably the most complicated routine in the editor. It * is not easy to understand. * * jmh 980728: update syntax highlight flags. * jmh 980801: Add BORDER action. * jmh 980810: renamed from move_copy_delete_overlay_block; * added left/right/center justify line and box blocks. * jmh 991026: allow LINE overlays. * jmh 991112: Add SUM action. */int block_operation( TDE_WIN *window ){int action;TDE_WIN *source_window = NULL; /* source window for block moves */line_list_ptr source; /* source for block moves */line_list_ptr dest; /* destination for block moves */int lens; /* length of source line */int lend; /* length of destination line */int add; /* characters being added from another line */int block_len; /* length of the block */line_list_ptr block_start; /* start of block in file */line_list_ptr block_end; /* end of block in file - not same for LINE or BOX */int prompt_line;int same; /* are dest and source files the same file? */int source_only; /* does operation affect only the block? */int source_changed; /* does the operation affect only the dest? */file_infos *source_file;file_infos *dest_file;int rcol, bc, ec; /* temporary column variables */long rline; /* temporary real line variable */long br, er; /* temporary line variables */long block_num; /* starting number for block number */long block_inc; /* increment to use for block number */int block_base; /* radix of the block number */int block_type;int fill_char = 0; /* fill character or length of pattern */text_t style[MAX_COLS+2]; /* border characters or fill pattern */int style_len[8]; /* border lengths */int rc;LANGUAGE *syntax;const char *errmsg = NULL;long number; /* * initialize block variables */ rc = un_copy_line( window->ll, window, TRUE, TRUE ); check_block( &source_window ); if (g_status.marked == FALSE || rc == ERROR) return( ERROR ); source_only = TRUE; source_changed = TRUE; switch (g_status.command) { case MoveBlock : action = MOVE; source_only = FALSE; break; case DeleteBlock : action = DELETE; break; case CopyBlock : action = COPY; source_only = FALSE; source_changed = FALSE; break; case KopyBlock : action = KOPY; source_only = FALSE; source_changed = FALSE; break; case FillBlock : case FillBlockDown : case FillBlockPattern : action = FILL; break; case OverlayBlock : action = OVERLAY; source_only = FALSE; source_changed = FALSE; break; case NumberBlock : action = NUMBER; break; case SwapBlock : action = SWAP; source_only = FALSE; break; case BorderBlock : case BorderBlockEx : action = BORDER; break; case BlockLeftJustify : case BlockRightJustify : case BlockCenterJustify : action = JUSTIFY; break; case SumBlock: action = SUM; source_changed = FALSE; break; default : return( ERROR ); } source_file = g_status.marked_file; dest_file = window->file_info; if ((source_file->read_only && source_changed) || (dest_file->read_only && !source_only)) return( ERROR ); prompt_line = window->bottom_line; block_start = source_file->block_start; block_end = source_file->block_end; if (block_start == NULL || block_end == NULL) return( ERROR ); block_type = source_file->block_type; if (block_type != LINE && block_type != STREAM && block_type != BOX) return( ERROR ); dest = window->ll; rline = window->rline; if (!source_only) if (dest->next == NULL || (dest->prev == NULL && (block_type != LINE || action == SWAP))) return( ERROR ); rc = OK; /* * jmh 980810: let's verify the block type at the beginning. */ if (block_type != BOX) { switch (action) { case NUMBER: errmsg = block3a; break; case FILL: errmsg = block2; break; case BORDER: errmsg = block26; break; case SUM: errmsg = block34; break; } } if (block_type == STREAM) { switch (action) { case OVERLAY: errmsg = block5; break; case SWAP: errmsg = block3b; break; case JUSTIFY: errmsg = block29; break; } } if (errmsg != NULL) { error( WARNING, prompt_line, errmsg ); return( ERROR ); } /* * set up Beginning Column, Ending Column, Beginning Row, Ending Row */ bc = source_file->block_bc; ec = source_file->block_ec; br = source_file->block_br; er = source_file->block_er; /* * if we are BOX FILLing or BOX NUMBERing, beginning column is bc, * not the column of cursor * jmh 980801: as with BORDERing. * jmh 980810: and JUSTIFYing. * jmh 991112: and SUMming. */ rcol = (source_only) ? bc : window->rcol; /* * must find out if source and destination file are the same. */ same = FALSE; if (source_only) { rc = (action == FILL) ? get_block_fill_char(window, &fill_char, style) : (action == NUMBER) ? get_block_numbers( &block_num, &block_inc, &block_base ) : (action == BORDER) ? get_block_border_style(window,style,style_len) : OK; if (rc == ERROR) return( ERROR ); dest = block_start; same = TRUE; } if (source_file == dest_file && !source_only) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -