📄 block.c
字号:
/******************* start of original comments ********************//* * Written by Douglas Thomson (1989/1990) * * This source code is released into the public domain. *//* * Name: dte - Doug's Text Editor program - block commands module * Purpose: This file contains all the commands than manipulate blocks. * File: block.c * Author: Douglas Thomson * System: this file is intended to be system-independent * Date: October 1, 1989 *//********************* end of original comments ********************//* * In the DTE editor, Doug only supported functions for STREAM blocks. * * The block routines have been EXTENSIVELY rewritten. This editor uses LINE, * STREAM, and BOX blocks. That is, one may mark entire lines, streams of * characters, or column blocks. Block operations are done in place. There * are no paste and cut buffers. In limited memory situations, larger block * operations can be carried out. Block operations can be done within or * across files. * * In TDE, version 1.1, I separated the BOX and LINE actions. * * In TDE, version 1.3, I put STREAM blocks back in. Added block upper case, * block lower case, and block strip high bit. * * In TDE, version 1.4, I added a block number function. Here at our lab, * I often need to number samples, lines, etc..., comes in fairly useful. * * In TDE, version 2.0, I added a box block sort function. * * In TDE, version 2.0e, I added BlockRot13, BlockFixUUE, and BlockEmailReply. * * In TDE, version 2.2, the big text buffer was changed to a double linked list. * all characters in the line of each node must be accurately counted. * * New editor name: TDE, the Thomson-Davis Editor. * Author: Frank Davis * Date: June 5, 1991, version 1.0 * Date: July 29, 1991, version 1.1 * Date: October 5, 1991, version 1.2 * Date: January 20, 1992, version 1.3 * Date: February 17, 1992, version 1.4 * Date: April 1, 1992, version 1.5 * Date: June 5, 1992, version 2.0 * Date: October 31, 1992, version 2.1 * Date: April 1, 1993, version 2.2 * Date: June 5, 1993, version 3.0 * Date: August 29, 1993, version 3.1 * Date: November 13, 1993, version 3.2 * Date: June 5, 1994, version 4.0 * Date: December 5, 1998, version 5.0 (jmh) * * This modification of Douglas Thomson's code is released into the * public domain, Frank Davis. You may distribute it freely. */#include "tdestr.h"#include "common.h"#include "tdefunc.h"#include "define.h"static void do_multi_box_mark( TDE_WIN * );static void do_multi_line_mark( TDE_WIN * );static void do_multi_stream_mark( TDE_WIN * );static void detab_begin( line_list_ptr, int, int, int );static int find_comment( text_ptr, text_ptr, int );static int find_comment_close( text_ptr, text_ptr, int );static void border_block_buff( text_ptr, int, long,long,long, text_ptr, int * );static int tabbed_bc = -1, tabbed_ec;static int tabbed_bc_ofs, tabbed_ec_ofs;long swap_br, swap_er = -1;int swap_bc, swap_ec;static int find_swap_lines( TDE_WIN *, line_list_ptr *, line_list_ptr *, long, long, int );static int find_swap_box( TDE_WIN *, long, long, int, int, int );/* * Name: mark_block * Class: primary editor function * Purpose: To record the position of the start of the block in the file. * Date: June 5, 1991 * Modified: August 9, 1997, Jason Hood - removed redundant logic, added markers * Passed: window: pointer to current window * Notes: Assume the user will mark begin and end of a block in either * line, stream, or box mode. If the user mixes types, then block * type defaults to current block type. * * jmh 980728: Allow explicit setting of the block beginning/end with the * MarkBegin and MarkEnd functions. If no block is set, default * to box. * Removed the markers - now inherent in goto_marker. * * jmh 990404: Mark a paragraph when the beginning/ending marks and the cursor * are all the same position. * jmh 990507: Modified MarkBox and MarkLine in the following manner: * MarkBox: mark character; * & again: mark word; * & again: mark string; * & again: mark paragraph. * * MarkLine: mark line; * & again: mark group of indented or blank lines; * & again: mark an additional line above and below; * & again: mark paragraph. * * Moved all that code into three separate functions. * * jmh 050714: marking a LINE after a STREAM will cause the first or last line * to be completely marked, keeping a STREAM block. */int mark_block( TDE_WIN *window ){int type;register file_infos *file; /* temporary file variable */register TDE_WIN *win; /* put window pointer in a register */int rc; win = window; file = win->file_info; if (win->rline > file->length || win->ll->len == EOF) return( ERROR ); switch (g_status.command) { case MarkBox: type = BOX; break; case MarkLine: type = LINE; break; case MarkStream: type = STREAM; break; case MarkBegin: case MarkEnd: type = (g_status.marked) ? file->block_type : BOX; break; default: return( ERROR ); } if (g_status.marked == FALSE) { g_status.marked = TRUE; g_status.marked_file = file; } rc = OK; /* * define blocks for only one file. it is ok to modify blocks in any window * pointing to original marked file. */ if (file == g_status.marked_file) { /* * mark beginning and ending column regardless of block mode. */ if (file->block_type <= NOTMARKED) { file->block_bc = file->block_ec = win->rcol; file->block_br = file->block_er = win->rline; } else if (g_status.command == MarkBegin) { file->block_bc = win->rcol; file->block_br = win->rline; } else if (g_status.command == MarkEnd) { if (type != STREAM || file->block_ec != -1) file->block_ec = win->rcol; file->block_er = win->rline; } else if (g_status.command_count == 0) { if (file->block_br <= win->rline) { if (type == LINE && file->block_type == STREAM) { if (file->block_br == win->rline && (win->rcol < file->block_bc || file->block_ec == -1)) file->block_ec = win->rcol; else { type = STREAM; file->block_ec = -1; --g_status.command_count; } } else file->block_ec = win->rcol; file->block_er = win->rline; } else { file->block_br = win->rline; if (file->block_bc < win->rcol && type != STREAM) file->block_ec = win->rcol; else { if (type == LINE && file->block_type == STREAM) { if (file->block_ec != -1) { file->block_bc = 0; type = STREAM; } else { file->block_bc = file->block_ec = win->rcol; } } else file->block_bc = win->rcol; } } } else { un_copy_line( win->ll, win, TRUE, TRUE ); if (is_line_blank( win->ll->line, win->ll->len, file->inflate_tabs ) && type != LINE) return( OK ); if (type == BOX) do_multi_box_mark( win ); else if (type == LINE) do_multi_line_mark( win ); else /* type == STREAM */ do_multi_stream_mark( win ); } /* * if user marks ending line less than beginning line then switch */ if (file->block_er < file->block_br) { long lnum = file->block_er; file->block_er = file->block_br; file->block_br = lnum; } /* * if user marks ending column less than beginning column then switch */ if (file->block_ec < file->block_bc && file->block_ec != -1 && (type != STREAM || file->block_br == file->block_er)) { int num = file->block_ec; file->block_ec = file->block_bc; file->block_bc = num; } file->block_type = type; file->dirty = GLOBAL; } else { /* * block already defined */ error( WARNING, win->bottom_line, block1 ); rc = ERROR; } return( rc );}/* * Name: do_multi_box_mark * Purpose: to mark a word, string or paragraph * Author: Jason Hood * Date: May 7, 1999 * Passed: window: pointer to current window * * jmh 991014: if on a non-letter when marking a word, mark a string. */static void do_multi_box_mark( TDE_WIN *window ){int num;long lnum;register file_infos *file; /* temporary file variable */line_list_ptr ll;text_ptr p;int (*space)( int ); /* Function to determine what a word is */int pb, pe; /* paragraph beginning/end columns */int tabs;int tab_size; if (g_status.command_count > 3) return; file = window->file_info; tabs = file->inflate_tabs; tab_size = file->ptab_size; ll = window->ll; if (g_status.command_count == 3) { lnum = window->rline; pb = MAX_LINE_LENGTH; pe = 0; do { num = first_non_blank( ll->line, ll->len, tabs, tab_size ); if (num < pb) pb = num; num = find_end( ll->line, ll->len, tabs, tab_size ) - 1; if (num > pe) pe = num; lnum--; ll = ll->prev; } while (!is_line_blank( ll->line, ll->len, tabs )); file->block_br = lnum + 1; lnum = window->rline + 1; ll = window->ll->next; while (!is_line_blank( ll->line, ll->len, tabs )) { num = first_non_blank( ll->line, ll->len, tabs, tab_size ); if (num < pb) pb = num; num = find_end( ll->line, ll->len, tabs, tab_size ) - 1; if (num > pe) pe = num; lnum++; ll = ll->next; } file->block_er = lnum - 1; } else { copy_line( ll, window, TRUE ); /* * Prevent uncopy calling the file modified. */ g_status.copied = FALSE; if (window->rcol >= g_status.line_buff_len) return; if (g_status.command_count == 1) { file->block_br = file->block_er = window->rline; pb = window->rcol - 1; pe = pb + 1; space = (myiswhitespc( g_status.line_buff[pe] )) ? bj_isspc : myiswhitespc; } else { pb = file->block_bc - 1; pe = file->block_ec + 1; space = bj_isspc; } p = g_status.line_buff + pb; for (; pb >= 0 && !space( *p-- ); --pb) ; ++pb; p = g_status.line_buff + pe; for (; pe < g_status.line_buff_len && !space( *p++ ); ++pe) ; --pe; } file->block_bc = pb; file->block_ec = pe;}/* * Name: do_multi_line_mark * Purpose: to mark like indentation or paragraph * Author: Jason Hood * Date: May 7, 1999 * Passed: window: pointer to current window * * jmh 991012: include "nested" indents. * jmh 050709: mark a group of blank lines. */static void do_multi_line_mark( TDE_WIN *window ){long lnum;register file_infos *file; /* temporary file variable */line_list_ptr ll;int i; /* indentation level */int indent; /* test for indentation? */int tabs;int tab_size; if (g_status.command_count > 3) return; file = window->file_info; tabs = file->inflate_tabs; tab_size = file->ptab_size; if (g_status.command_count == 2) { if (file->block_br > 1) --file->block_br; if (file->block_er < file->length) ++file->block_er; } else { indent = (g_status.command_count == 1); lnum = window->rline; ll = window->ll; if (is_line_blank( ll->line, ll->len, tabs)) { if (!indent) return; do { lnum--; ll = ll->prev; } while (ll->len != EOF && is_line_blank( ll->line, ll->len, tabs )); file->block_br = lnum + 1; lnum = window->rline + 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -