📄 ed.c
字号:
}/* * Name: char_del_under * Purpose: To delete the character under the cursor. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: If the cursor is beyond the end of the line, then this * command is ignored. * DeleteChar and StreamDeleteChar use this function. * * jmh 980524: added test for real tabs. */int char_del_under( TDE_WIN *window ){text_ptr source; /* source of block move to delete character */int len;register TDE_WIN *win; /* put window pointer in a register */int rcol; win = window; if (win->ll->len == EOF) return( OK ); rcol = win->rcol; copy_line( win->ll, win, FALSE ); adjust_for_tabs( &rcol, win->file_info->inflate_tabs, win->file_info->ptab_size ); if (rcol < (len = g_status.line_buff_len)) { /* * move text to delete using buffer */ source = g_status.line_buff + rcol + 1; assert( len - rcol >= 0 ); shift_tabbed_block( win->file_info ); memmove( source-1, source, len - rcol ); --g_status.line_buff_len; shift_block( win->file_info, win->rline, rcol+1, -1 ); entab_linebuff( win->file_info->inflate_tabs, win->file_info->ptab_size ); win->file_info->dirty = GLOBAL; win->file_info->modified = TRUE; win->ll->type |= DIRTY; show_changed_line( win ); } else if (g_status.command == StreamDeleteChar) join_line( win ); else if (win->file_info->modified == FALSE) /* * prevent un_copy_line from indicating the file is modified */ g_status.copied = FALSE; return( OK );}/* * Name: eol_kill * Purpose: To delete everything from the cursor to the end of the line. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: If the cursor is beyond the end of the line, then this * command is ignored. */int eol_kill( TDE_WIN *window ){register TDE_WIN *win; /* put window pointer in a register */ win = window; if (win->ll->len == EOF) return( OK ); copy_line( win->ll, win, TRUE ); if (win->rcol < g_status.line_buff_len) { load_undo_buffer( win->file_info, g_status.line_buff, g_status.line_buff_len ); /* * truncate to delete rest of line */ shift_block( win->file_info, win->rline, g_status.line_buff_len, win->rcol - g_status.line_buff_len ); g_status.line_buff_len = win->rcol; entab_linebuff( win->file_info->inflate_tabs, win->file_info->ptab_size ); win->file_info->dirty = GLOBAL; win->file_info->modified = TRUE; win->ll->type |= DIRTY; show_changed_line( win ); } return( OK );}/* * Name: bol_kill * Purpose: to delete or erase everything from beginning of line till the cursor * Author: Jason Hood * Date: September 11, 2002 * Passed: window: pointer to current window * Notes: delete works similar to home: it will take the first non-blank as * the beginning of the line, then the first column. * erase will overwrite with blanks, rather than actually delete. * ignored if cursor is already at the first column. * * 021011: fixed delete bugs beyond EOL, on non-empty blank lines and tabs. * 060914: update syntax highlighting on GLOBAL change. */int bol_kill( TDE_WIN *window ){register TDE_WIN *win; /* put window pointer in a register */int rcol, bol;int del_count;int tabs, tab_size;int old_bcol; win = window; if (win->ll->len == EOF) return( OK ); rcol = win->rcol; tabs = win->file_info->inflate_tabs; tab_size = win->file_info->ptab_size; if (rcol != 0) { copy_line( win->ll, win, (g_status.command == EraseBegOfLine) ); load_undo_buffer( win->file_info, g_status.line_buff, g_status.line_buff_len ); if (g_status.command == EraseBegOfLine) memset( g_status.line_buff, ' ', rcol ); else { adjust_for_tabs( &rcol, tabs, tab_size ); old_bcol = bol = first_non_blank( g_status.line_buff, g_status.line_buff_len, tabs, tab_size ); if (tabs) bol = entab_adjust_rcol( g_status.line_buff, g_status.line_buff_len, bol, tab_size ); if (rcol <= bol || is_line_blank( g_status.line_buff, g_status.line_buff_len, tabs )) bol = 0; shift_tabbed_block( win->file_info ); if (rcol >= g_status.line_buff_len) { del_count = win->rcol - old_bcol; g_status.line_buff_len = bol; } else { memcpy( g_status.line_buff + bol, g_status.line_buff + rcol, g_status.line_buff_len - rcol ); del_count = rcol - bol; g_status.line_buff_len -= del_count; if (tabs == 2 && mode.insert) { old_bcol = detab_adjust_rcol(g_status.line_buff, bol, tab_size); del_count = win->rcol - old_bcol; } } shift_block( win->file_info, win->rline, rcol, bol - rcol ); show_ruler_char( win ); old_bcol = win->bcol; check_virtual_col( win, win->rcol - del_count, win->ccol - del_count ); if (old_bcol != win->bcol) show_ruler( win ); } entab_linebuff( tabs, tab_size ); win->file_info->modified = TRUE; win->ll->type |= DIRTY; if (!win->file_info->dirty) { win->file_info->dirty = GLOBAL; show_changed_line( win ); } else { win->file_info->dirty = GLOBAL; syntax_check_lines( win->ll, win->file_info->syntax ); } } return( OK );}/* * Name: set_tabstop * Purpose: To set the current interval between tab stops * Date: October 1, 1989 * Notes: Tab interval must be reasonable, and this function will * not allow tabs more than g_display.ncols / 2. * jmh 991126: ensure tabs are greater than 0. * jmh 021028: allow tabs to be up to g_display.ncols. * jmh 021105: use MAX_TAB_SIZE define. */int set_tabstop( TDE_WIN *window ){register int rc;file_infos *file; file = window->file_info; set_dlg_num( EF_Logical, file->ltab_size ); set_dlg_num( EF_Physical, file->ptab_size ); rc = do_dialog( tabs_dialog, tabs_proc ); if (rc == OK) { file->ltab_size = (int)get_dlg_num( EF_Logical ); file->ptab_size = (int)get_dlg_num( EF_Physical ); show_tab_modes( ); if (file->inflate_tabs) file->dirty = GLOBAL; } return( rc );}/* * Name: tabs_proc * Purpose: dialog callback for SetTabs * Author: Jason Hood * Date: December 1, 2003 * Notes: ensure tabs don't go beyond limits. */int tabs_proc( int id, char *text ){int tab;int rc = OK; if (id == IDE_LOGICAL || id == IDE_PHYSICAL) { tab = atoi( text ); if (tab < 1 || tab > MAX_TAB_SIZE) { /* * tab size too long */ error( WARNING, g_display.end_line, (id==IDE_LOGICAL) ? ed8a : ed8b ); rc = ERROR; } } return( rc );}/* * Name: dynamic_tab_size * Purpose: interactively change the physical tab size * Author: Jason Hood * Date: March 4, 2003 * Notes: use left/right to change by one, up/down by four. */int dynamic_tab_size( TDE_WIN *window ){TDE_WIN *win[20];file_infos *file;int tab, old_tab;int prompt_line;long key;int func;DISPLAY_BUFF;char str[6];int cnt, j; file = window->file_info; if (file->ref_count > 1) { cnt = -1; for (window = g_status.window_list; window; window = window->next) if (window->file_info == file && window->visible && cnt < 19) win[++cnt] = window; } else { win[0] = window; cnt = 0; } tab = old_tab = file->ptab_size; prompt_line = g_display.mode_line; SAVE_LINE( prompt_line ); /* * Tab size: */ eol_clear( 0, prompt_line, Color( Help ) ); s_output( ed7c, prompt_line, 0, Color( Help ) ); xygoto( -1, -1 ); do { sprintf( str, "%d ", file->ptab_size ); s_output( str, prompt_line, ED7C_SLOT, Color( Help ) ); key = getkey( ); func = (key == _ENTER) ? Rturn : (key == _ESC) ? AbortCommand: getfunc( key ); switch (func) { case CharLeft: case StreamCharLeft: if (file->ptab_size > 1) --file->ptab_size; break; case CharRight: case StreamCharRight: if (file->ptab_size < MAX_TAB_SIZE) ++file->ptab_size; break; case LineUp: if (file->ptab_size > 4) file->ptab_size -= 4; else file->ptab_size = 1; break; case LineDown: if (file->ptab_size < MAX_TAB_SIZE - 3) file->ptab_size += 4; else file->ptab_size = MAX_TAB_SIZE; break; } if (tab != file->ptab_size) { tab = file->ptab_size; for (j = cnt; j >= 0; --j) display_current_window( win[j] ); } } while (func != Rturn && func != AbortCommand); RESTORE_LINE( prompt_line ); if (old_tab != file->ptab_size) { if (func == Rturn) { if (file->ref_count > 20) file->dirty = GLOBAL; show_tab_modes( ); } else { file->ptab_size = old_tab; file->dirty = GLOBAL; } } return( OK );}/* * Name: show_line_col * Purpose: show current real line and column of current cursor position * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Blank old position and display new position. current line and * column may take up to 12 columns, which allows the display of * 9,999 columns and 9,999,999 lines. * * jmh 980804: prevent display of current character when resizing windows. * actually made the line:col 12 columns, not the 13 it was (it * was either that, or make min window width 16; since 10 million * lines is at least 20 million bytes (crlf) I don't think it's * a problem). * jmh 980822: display marker indicators in the mode line. * jmh 990408: modified current character display code; * made hex_digit static; * added base offset (line:col+ofs) to indicate horizontal scroll. * jmh 990915: added " =EOL" when cursor is at end-of-line. * jmh 990923: corrected binary offset when used with inflated tabs. * jmh 990924: only blank the markers when necessary, since it appears to * flicker on fast computers. * jmh 991027: don't display markers when sizing windows. * jmh 991029: don't display with SwapBlock as well. * jmh 021028: don't display with ISearch*. * jmh 030330: corrected position of binary offset (relative to right edge). * jmh 050708: don't display base offset on large files. */void show_line_col( TDE_WIN *window ){int i, j;register int k;char line_col[20];static const char hex_digit[] = "0123456789abcdef";file_infos *file;static long old_rline;int do_mode; line_col[19] = '\0'; k = 19; /* * convert base offset to ascii and store in display buffer. */ if (window->bcol != 0) { i = numlen( window->bcol ); if (i + numlen( window->rcol+1 ) + numlen( window->rline ) + 2 <= 12) { k -= i; my_ltoa( window->bcol, line_col + k, 10 ); line_col[--k] = '+'; } } /* * convert column to ascii and store in display buffer. */ i = numlen( window->rcol+1 ); j = line_col[k]; k -= i; my_ltoa( window->rcol+1, line_col + k, 10 ); line_col[k+i] = j; /* * convert line to ascii and store in display buffer. */ i = numlen( window->rline ); k -= i + 1; my_ltoa( window->rline, line_col + k, 10 ); /* * put in colon to separate line and column */ line_col[k+i] = ':'; /* * blank out the remainder of the display. */ while (--k >= 7) line_col[k] = ' '; /* * find line to start line:column display then output */ s_output( line_col+7, window->top, window->end_col-11, Color( Head ) ); file = window->file_info; do_mode = (g_status.command != SizeWindow && g_status.command != SwapBlock && g_status.command != PopupRuler && !(g_status.search & SEARCH_I)); if (do_mode && !mode.draw) { strcpy( line_col, " = " ); i = window->rcol; k = -2; if (g_status.copied) { if (file->inflate_tabs)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -