📄 utils.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 - miscellaneous utilities * Purpose: This file contains miscellaneous functions that were required * in more than one of the other files, or were thought to be * likely to be used elsewhere in the future. * File: utils.c * Author: Douglas Thomson * System: this file is intended to be system-independent * Date: October 1, 1989 *//********************* end of original comments ********************//* * The utility routines have been EXTENSIVELY rewritten. Update screens as * needed. Most times, only one line has changed. Just show changed line * in all windows if it is on screen. * * Support routines for text lines longer than screen width have been added. * Currently support lines as long as 1040 characters. * * In DTE, Doug chose to test whether characters are part of a word. In TDE, * we will test whether characters are not part of a word. The character * set not part of a word will not change as much as the characters that * are part of a word. In most languages, human and computer, the delimiters * are much more common across languages than the tokens that make up a word. * Thanks to Pierre Jelenc, pcj1@columbia.edu, for recommending looking for * delimiters. * * 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 "define.h"#include "tdefunc.h"#if defined( __WIN32__ )#include <process.h>#endifextern long swap_br, swap_er; /* block.c */extern int swap_bc, swap_ec;extern int copied_rcol; /* undo.c */extern int copied_mod;extern int copied_dirty;extern long found_rline; /* findrep.c */extern int found_rcol;extern int found_vlen; int auto_reload = FALSE; /* for file.c */static int ruler1 = -1, ruler2 = -1; /* for the popup ruler *//* * Name: execute * Purpose: run a function * Author: Jason Hood * Date: November 21, 1999 * Passed: window: window where function executes * Returns: depends on the function * Notes: ignore non-viewer functions if the file is read-only. * Uses g_status.command for the function, sets g_status.command_count. * Don't keep a count of PullDown. */int execute( TDE_WIN *window ){int rc;int func = g_status.command; if (func >= 0 && func < NUM_FUNCS && (!window->file_info->read_only || !(func_flag[func] & F_MODIFY))) { if (func != PullDown) { if (func == g_status.last_command) ++g_status.command_count; else g_status.command_count = 0; } rc = (*do_it[func])( window ); if (func != PullDown) g_status.last_command = func; } else rc = ERROR; return( rc );}/* * Name: myiswhitespc * Purpose: To determine whether or not a character is *NOT* part of a "word". * Date: July 4, 1992 * Passed: c: the character to be tested * Returns: TRUE if c is in the character set *NOT* part of a word * Notes: The characters in the set not part of a word will not change as * as much as the characters that are part of a word. In most * languages, human and computer, the delimiters are much more * common than the tokens that make up a word. For example, * the set of punction characters don't change as much across * languages, human and computer, as the characters that make * up the alphabet, usually. In other words, the delimiters * are fairly constant across languages. */int myiswhitespc( int c ){ return( c == ' ' || (bj_ispunct( c ) && c != '_') || bj_iscntrl( c ) );}/* * Name: myisnotwhitespc * Purpose: to determine whether or not a character is part of a word * Author: Jason Hood * Date: May 21, 1998 * Passed: c: the character to be tested * Returns: TRUE if c is in the character set part of a word * Notes: used by the various word movement functions. * 991022: decided to make this a global function; * renamed from not_myiswhitespc. */int myisnotwhitespc( int c ){ /* return( !myiswhitespc( c ) ); */ return( c == '_' || (c != ' ' && !bj_ispunct( c ) && !bj_iscntrl( c )) );}/* * Name: check_virtual_col * Purpose: ensure integrity of rcol, ccol, and bcol * Date: June 5, 1991 * Passed: window: pointer to current window * rcol: real column of cursor * ccol: current or logical column of cursor * jmh 980724: update cursor cross * jmh 021210: when moving beyond the window, place ccol at the end of the * window, instead of the start. */void check_virtual_col( TDE_WIN *window, int rcol, int ccol ){register int bcol;int start_col;int end_col;file_infos *file; file = window->file_info; bcol = window->bcol; start_col = window->start_col; end_col = window->end_col; /* * is logical column past end of screen? */ if (ccol > end_col) { ccol = rcol - bcol + start_col; if (ccol > end_col) { ccol = end_col; bcol = rcol - (ccol - start_col); file->dirty = LOCAL | RULER; } } /* * is logical column behind start of screen? */ if (ccol < start_col) { if (bcol >= (start_col - ccol)) bcol -= (start_col - ccol); ccol = start_col; file->dirty = LOCAL | RULER; } /* * is real column < base column? */ if (rcol < bcol) { ccol = rcol + start_col; bcol = 0; if (ccol > end_col) { bcol = rcol; ccol = start_col; } file->dirty = LOCAL | RULER; } /* * current column + base column MUST equal real column */ if ((ccol - start_col) + bcol != rcol) { if (bcol < 0 || bcol > rcol) { bcol = rcol; file->dirty = LOCAL | RULER; } ccol = rcol - bcol + start_col; if (ccol > end_col) { /*bcol = rcol; ccol = start_col;*/ ccol = end_col; bcol = rcol - (ccol - start_col); file->dirty = LOCAL | RULER; } } /* * rcol CANNOT be negative */ if (rcol < 0) { rcol = bcol = 0; ccol = start_col; file->dirty = LOCAL | RULER; } if (rcol >= MAX_LINE_LENGTH) { rcol = MAX_LINE_LENGTH - 1; bcol = rcol - (ccol - start_col); file->dirty = LOCAL | RULER; } assert( rcol >= 0 ); assert( rcol < MAX_LINE_LENGTH ); assert( bcol >= 0 ); assert( bcol < MAX_LINE_LENGTH ); assert( ccol >= start_col ); assert( ccol <= end_col ); window->bcol = bcol; window->ccol = ccol; window->rcol = rcol; /* * If the cursor cross is on, set LOCAL update. This is not as * efficient as it should be, but is a whole lot easier than * modifying every function that could move the cursor left or right. */ if (mode.cursor_cross) file->dirty = LOCAL | RULER;}/* * Name: check_cline * Purpose: ensure integrity of cline * Author: Jason Hood * Date: March 27, 2003 * Passed: window: pointer to window * cline: new cline * Returns: TRUE if cline was outside the window (an update is required) * Notes: also ensures TOF remains as the top line */int check_cline( TDE_WIN *window, int cline ){int update = FALSE; if (cline < window->top_line) { cline = window->top_line; update = TRUE; } else { if (cline > window->bottom_line) { cline = window->bottom_line; update = TRUE; } if (cline > window->rline + window->top_line) { cline = (int)window->rline + window->top_line; update = TRUE; } } window->cline = cline; return( update );}/* * Name: new_line * Purpose: create a new line structure * Author: Jason Hood * Date: February 27, 2003 * Passed: type: type of the line * rc: place to store error code (should be OK on entry) * Returns: the new line */line_list_ptr new_line( long type, int *rc ){line_list_ptr ll; ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), rc ); if (*rc == OK) { ll->line = NULL; ll->len = 0; ll->type = type; } return( ll );}/* * Name: new_line_text * Purpose: create a new line with text * Author: Jason Hood * Date: February 27, 2003 * Passed: text: the text of the line to copy * len: the length of the above * type: the type of the line * rc: pointer to return code (should be OK on entry) * Returns: pointer to the new line */line_list_ptr new_line_text( text_ptr text, int len, long type, int *rc ){line_list_ptr ll;text_ptr t; t = (text_ptr)my_malloc( len, rc ); ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), rc ); if (*rc == OK) { my_memcpy( t, text, len ); ll->line = t; ll->len = len; ll->type = type; } else { my_free( ll ); my_free( t ); } return( ll );}/* * Name: copy_line * Purpose: To copy the cursor line, if necessary, into the current line * buffer, so that changes can be made efficiently. * Date: June 5, 1991 * Passed: ll: line to be copied to line buffer * window: window containing the line * tabs: TRUE to detab * Notes: See un_copy_line, the reverse operation. * DO NOT use the C library string functions on text in * g_status.line_buff, because Null characters are allowed as * normal text in the file. */void copy_line( line_list_ptr ll, TDE_WIN *window, int tabs ){register int len; assert( ll != NULL ); len = ll->len; if (len != EOF) { if (g_status.copied == FALSE) { assert( len < MAX_LINE_LENGTH ); my_memcpy( g_status.line_buff, ll->line, len ); g_status.line_buff_len = len; g_status.copied = TRUE; g_status.buff_node = ll; /* * jmh 021011: remember the original rcol position for RestoreLine * jmh 030225: likewise with modified. * jmh 030302: and dirty. */ copied_rcol = window->rcol; copied_mod = window->file_info->modified; copied_dirty = (int)ll->type & DIRTY; } if (tabs) detab_linebuff( window->file_info->inflate_tabs, window->file_info->ptab_size ); }}/* * Name: un_copy_line * Purpose: To copy the cursor line, if necessary, from the current line * buffer, shifting the main text to make the right amount of * room. * Date: June 5, 1991 * Passed: test_line: location in file to copy line buffer * window: pointer to current window * del_trailing: delete the trailing blanks at eol? TRUE or FALSE * tabs: TRUE to entab * Notes: For some functions, trailing spaces should not be removed when * returning the line buffer to the main text. The JoinLine function * is a good example. We need to leave trailing space so when we * join lines - the current line will extend at least up to * the column of the cursor. We need to leave trailing space * during BOX block operations. * See copy_line, the reverse operation. * * jmh 011203: only display the available memory if the window is visible. * jmh 031114: reset the buff_node pointer (for RestoreLine). */int un_copy_line( line_list_ptr ll, TDE_WIN *window, int del_trailing, int tabs ){text_ptr p;size_t len; /* length of line buffer text */size_t ll_len; /* length of ll->line */int net_change;int rc;text_ptr c;file_infos *file;TDE_WIN *wp; rc = OK; if (mode.do_backups == TRUE) rc = backup_file( window ); if (g_status.copied == TRUE && ll->len != EOF) { file = window->file_info; if (tabs) entab_linebuff( file->inflate_tabs, file->ptab_size ); /* * if we are deleting the entire line, don't worry about * deleting the trailing space, since we're deleting entire line. */ if (g_status.command == DeleteLine) del_trailing = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -