📄 ed.c
字号:
* record that file has been modified */ show_size( win ); show_avail_mem( ); } else { /* * cannot duplicate line */ error( WARNING, win->bottom_line, ed5 ); } return( rc );}/* * Name: back_space * Purpose: To delete the character to the left of the cursor. * Date: June 5, 1991 * Modified: August 10, 1997, Jason Hood - added WordDeleteBack * Passed: window: pointer to current window * Notes: If the cursor is at the left of the line, then combine the * current line with the previous one. * If in indent mode, and the cursor is on the first non-blank * character of the line, then match the indentation of an * earlier line. * In WordDeleteBack, delete all whitespace, if any, then all * non-whitespace up to the first whitespace (similar to WordLeft). * If there is only whitespace, join with the previous line. * * jmh 980605: Corrected WordDeleteBack error when there was only one space * at the beginning of the line. * 980614: Corrected WordDeleteBack error when only leading spaces were * deleted. * 980701: Allow blank lines to be deleted if at eof. * jmh 981129: Correct sync bug of above. * Recognize cursor update direction. Simply move the other way and * use the insert_overwrite function to overwrite a space. However, * CUR_LEFT in insert mode just calls char_del_under. * jmh 020911: Changed WordDeleteBack to join with previous line, * since I added the DelBegOfLine function. * jmh 021210: Corrected WordDeleteBack error on blank lines. * jmh 050707: Corrected up/down cursor direction beyond EOF. */int back_space( TDE_WIN *window ){int rc; /* return code */int len; /* length of the current line */text_ptr source; /* source of block move to delete character */text_ptr dest; /* destination of block move */text_ptr p; /* previous line in file */int plen; /* length of previous line */int del_count; /* number of characters to delete */int pos = 0; /* the position of the first non-blank char */int rcol;int ccol;int old_bcol;register TDE_WIN *win; /* put window pointer in a register */TDE_WIN *wp;line_list_ptr temp_ll;int tabs;int tab_size; win = window; if (win->ll->len == EOF) { if (win->ll->prev == NULL || win->ll->prev->len != 0) rc = ERROR; else { prepare_move_up( win ); rc = line_kill( win ); } return( rc ); } rc = OK; tabs = win->file_info->inflate_tabs; tab_size = win->file_info->ptab_size; rcol = win->rcol; if (mode.cur_dir != CUR_RIGHT) { if (mode.cur_dir == CUR_LEFT) ++rcol; else if (mode.cur_dir == CUR_DOWN) { if (win->ll->prev->len == EOF) rc = ERROR; else prepare_move_up( win ); } else /* mode.cur_dir == CUR_UP */ { if (win->ll->next->len == EOF) rc = ERROR; else prepare_move_down( win ); } if (rc == OK) { if (g_status.copied) g_status.line_buff[rcol] = ' '; else { rcol = entab_adjust_rcol( win->ll->line, win->ll->len, rcol, tab_size ); if (rcol < win->ll->len) win->ll->line[rcol] = ' '; } show_curl_line( win ); if (mode.cur_dir == CUR_LEFT) check_virtual_col( win, rcol, ++win->ccol ); } return( rc ); } copy_line( win->ll, win, FALSE ); adjust_for_tabs( &rcol, tabs, tab_size ); len = g_status.line_buff_len; ccol = win->ccol; old_bcol = win->bcol; if (g_status.command == WordDeleteBack) { pos = (rcol < len) ? rcol-1 : len-1; while (pos >= 0 && myiswhitespc( g_status.line_buff[pos] )) --pos; if (pos == -1 && win->rline > 1 && rcol <= len) { /* * remove the leading whitespace prior to joining */ g_status.line_buff_len -= rcol; memcpy( g_status.line_buff, g_status.line_buff + rcol, g_status.line_buff_len ); rcol = 0; } } if (rcol == 0) { if (win->rline > 1) { /* * combine this line with the previous, if any */ assert( win->ll->prev != NULL ); p = win->ll->prev->line; plen = win->ll->prev->len; if (len + 2 + plen >= MAX_LINE_LENGTH) { /* * cannot combine lines */ error( WARNING, win->bottom_line, ed4 ); return( ERROR ); } win->file_info->modified = TRUE; if ((rc = un_copy_line( win->ll, win, TRUE, FALSE )) == OK) { dec_line( win, FALSE ); win->ll->type |= DIRTY; copy_line( win->ll, win, TRUE ); len = g_status.line_buff_len; win->rcol = rcol = len; p = win->ll->next->line; plen = win->ll->next->len; /* * copy previous line into new previous line. */ assert( plen >= 0 ); assert( len >= 0 ); my_memcpy( g_status.line_buff+len, p, plen ); g_status.line_buff_len = len + plen; load_undo_buffer( win->file_info, p, plen ); my_free( p ); temp_ll = win->ll->next; if (temp_ll->prev != NULL) temp_ll->prev->next = temp_ll->next; temp_ll->next->prev = temp_ll->prev; syntax_check_lines( win->ll, win->file_info->syntax ); --win->file_info->length; ++win->rline; adjust_windows_cursor( win, -1 ); restore_marked_block( win, -1 ); --win->rline; wp = g_status.window_list; while (wp != NULL) { if (wp->file_info == win->file_info) { if (wp != win) { if (wp->ll == temp_ll) wp->ll = win->ll->next; } } wp = wp->next; } my_free( temp_ll ); if (win->cline > win->top_line) --win->cline; /* * make sure cursor stays on the screen, at the end of the * previous line */ ccol = rcol - win->bcol; show_size( win ); show_avail_mem( ); check_virtual_col( win, rcol, ccol ); win->file_info->dirty = GLOBAL; show_ruler( win ); } } else return( ERROR ); } else { if (g_status.command == WordDeleteBack) { while (pos >= 0 && !myiswhitespc( g_status.line_buff[pos] )) --pos; del_count = rcol - pos - 1; } else { /* * normal delete * * find out how much to delete (depends on indent mode) */ del_count = 1; /* the default */ if (mode.indent) { /* * indent only happens if the cursor is on the first * non-blank character of the line */ pos = first_non_blank( g_status.line_buff, len, tabs, tab_size ); if (pos == win->rcol || is_line_blank( g_status.line_buff, len, tabs )) { /* * now work out how much to indent */ temp_ll = win->ll->prev; for (; temp_ll != NULL; temp_ll=temp_ll->prev) { p = temp_ll->line; if (!is_line_blank( p, temp_ll->len, tabs )) { plen = first_non_blank( p, temp_ll->len, tabs, tab_size ); if (plen < win->rcol) { /* * found the line to match * * jmh 980524: remove the tabs if using real tabs * jmh 990502: that was dumb - just adjust plen * jmh 991004: add spaces, too */ if (tabs == 2 && mode.insert) { adjust_for_tabs( &plen, tabs, tab_size ); len = g_status.line_buff_len; rcol = entab_adjust_rcol( g_status.line_buff, len, win->rcol, tab_size ); } del_count = rcol - plen; break; } } } } } } /* * move text to delete char(s), unless no chars actually there */ if (rcol - del_count < len) { dest = g_status.line_buff + rcol - del_count; if (rcol > len) { source = g_status.line_buff + len; pos = 0; len = rcol - del_count; } else { source = g_status.line_buff + rcol; pos = len - rcol; len -= del_count; } shift_tabbed_block( win->file_info ); assert( pos >= 0 ); assert( len >= 0 ); assert( len <= MAX_LINE_LENGTH ); memmove( dest, source, pos ); g_status.line_buff_len = len; shift_block( win->file_info, win->rline, rcol, -del_count ); if (tabs == 2 && mode.insert) { pos = detab_adjust_rcol( g_status.line_buff, rcol - del_count, tab_size ); del_count = win->rcol - pos; } entab_linebuff( tabs, tab_size ); } rcol = win->rcol - del_count; ccol -= del_count; win->file_info->dirty = NOT_LOCAL; win->ll->type |= DIRTY; show_ruler_char( win ); show_changed_line( win ); check_virtual_col( win, rcol, ccol ); if (!win->file_info->dirty) show_curl_line( win ); if (old_bcol != win->bcol) show_ruler( win ); } win->file_info->modified = TRUE; return( rc );}/* * Name: transpose * Purpose: swap two characters * Date: September 11, 1997 * Author: Jason Hood * Passed: window: pointer to current window * Notes: swaps the current character with the previous character; * if at bol (ie. column 1) swap with the next character; * if at eol (ie. one more than length) swap the two previous chars. * * 980502: Test line first; detabbed the buffer before testing length. */int transpose( TDE_WIN *window ){register TDE_WIN *win;char swap; /* the swapped character */int which; /* whether it's previous or next */int rcol; /* the current character */int len; /* length of the line */ win = window; if (win->ll->len == EOF) return( OK ); rcol = win->rcol; copy_line( win->ll, win, TRUE ); len = g_status.line_buff_len; if (len < 2 || rcol > len) return( OK ); if (rcol == len) --rcol; which = (rcol > 0) ? -1 : 1; swap = g_status.line_buff[rcol+which]; g_status.line_buff[rcol+which] = g_status.line_buff[rcol]; g_status.line_buff[rcol] = swap; entab_linebuff( win->file_info->inflate_tabs, win->file_info->ptab_size ); win->file_info->dirty = GLOBAL; win->file_info->modified = TRUE; window->ll->type |= DIRTY; show_changed_line( win ); return( OK );}/* * Name: line_kill * Purpose: To delete the line the cursor is on. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: win->ll->s == NULL then do not do a * line kill (can't kill a NULL line). */int line_kill( TDE_WIN *window ){register TDE_WIN *win; /* put window pointer in a register */register TDE_WIN *wp;line_list_ptr killed_node;int rc; win = window; killed_node = win->ll; rc = OK; if (killed_node->len != EOF) { win->file_info->modified = TRUE; if (mode.do_backups == TRUE) rc = backup_file( win ); if (rc == OK) { load_undo_buffer( win->file_info, g_status.copied ? g_status.line_buff : killed_node->line, g_status.copied ? g_status.line_buff_len : killed_node->len ); --win->file_info->length; win->ll = win->ll->next; killed_node->prev->next = killed_node->next; killed_node->next->prev = killed_node->prev; wp = g_status.window_list; while (wp != NULL) { if (wp->file_info == win->file_info) { if (wp != win) { if (wp->ll == killed_node) wp->ll = win->ll; } } wp = wp->next; } /* * free the line and the node */ my_free( killed_node->line ); my_free( killed_node ); win->file_info->dirty = NOT_LOCAL; g_status.copied = FALSE; /* * move all cursors one according to i, restore begin and end block */ adjust_windows_cursor( win, -1 ); restore_marked_block( win, -1 ); syntax_check_lines( win->ll, win->file_info->syntax ); /* * we are not doing a GLOBAL update, so update current window here */ if (win->file_info->dirty == NOT_LOCAL) my_scroll_down( win ); show_size( win ); show_avail_mem( ); } } else rc = ERROR; return( rc );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -