📄 ed.c
字号:
if (rcol > len) {
source = g_status.line_buff + len;
pos = 0;
len = (rcol + 1) - del_count;
} else {
source = g_status.line_buff + rcol;
pos = len - rcol;
len = len - del_count;
}
assert( pos >= 0 );
assert( len >= 0 );
assert( len <= MAX_LINE_LENGTH );
memmove( dest, source, pos );
g_status.line_buff_len = len;
entab_linebuff( );
}
rcol -= del_count;
ccol -= del_count;
win->file_info->dirty = NOT_LOCAL;
win->ll->dirty = TRUE;
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) {
make_ruler( win );
show_ruler( win );
}
}
win->file_info->modified = TRUE;
return( rc );
}
/*
* 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( WINDOW *window )
{
register WINDOW *win; /* put window pointer in a register */
register WINDOW *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 ? (text_ptr)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;
if (killed_node->prev != NULL)
killed_node->prev->next = killed_node->next;
else
win->file_info->line_list = win->ll;
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
*/
if (killed_node->line != NULL)
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 );
/*
* 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 );
}
/*
* 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.
*/
int char_del_under( WINDOW *window )
{
char *source; /* source of block move to delete character */
int len;
register WINDOW *win; /* put window pointer in a register */
win = window;
if (win->rline > win->file_info->length || win->ll->len == EOF)
return( OK );
copy_line( win->ll );
detab_linebuff( );
if (win->rcol < (len = g_status.line_buff_len)) {
/*
* move text to delete using buffer
*/
source = g_status.line_buff + win->rcol + 1;
assert( len - win->rcol >= 0 );
memmove( source-1, source, len - win->rcol );
--g_status.line_buff_len;
entab_linebuff( );
win->file_info->dirty = GLOBAL;
win->file_info->modified = TRUE;
win->ll->dirty = TRUE;
show_changed_line( win );
} else if (g_status.command == StreamDeleteChar)
join_line( win );
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( WINDOW *window )
{
register WINDOW *win; /* put window pointer in a register */
win = window;
if (win->rline > win->file_info->length || win->ll->len == EOF)
return( OK );
copy_line( win->ll );
detab_linebuff( );
load_undo_buffer( win->file_info, (text_ptr)g_status.line_buff,
g_status.line_buff_len );
if (win->rcol < g_status.line_buff_len) {
/*
* truncate to delete rest of line
*/
g_status.line_buff_len = win->rcol;
entab_linebuff( );
win->file_info->dirty = GLOBAL;
win->ll->dirty = TRUE;
show_changed_line( win );
}
return( OK );
}
/*
* Name: undo_line
* Purpose: To retrieve unaltered line if possible.
* Date: June 5, 1991
* Passed: window: pointer to current window
* Notes: Changes are made to the line buffer so the underlying text has
* not changed. Put the unchanged line from the file into the
* line buffer and display it.
*/
int undo_line( WINDOW *window )
{
register WINDOW *win; /* put window pointer in a register */
win = window;
if (win->rline <= win->file_info->length && win->ll->len != EOF &&
g_status.copied) {
g_status.copied = FALSE;
copy_line( win->ll );
detab_linebuff( );
win->file_info->dirty = GLOBAL;
show_changed_line( win );
}
return( OK );
}
/*
* Name: undo
* Purpose: To retrieve (pop) a line from the undo stack
* Date: September 26, 1991
* Passed: window: pointer to current window
* Notes: Insert an empty line into the file then pop the line in the undo
* stack. When we pop line 0, there are no more lines on the stack.
* Set the stack pointer to -1 to indicate an empty stack.
*/
int undo( WINDOW *window )
{
register WINDOW *win; /* put window pointer in a register */
line_list_ptr node;
win = window;
if (win->file_info->undo_count > 0) {
entab_linebuff( );
if (un_copy_line( win->ll, win, TRUE ) == ERROR)
return( ERROR );
node = win->file_info->undo_top;
win->file_info->undo_top = node->next;
win->file_info->undo_top->prev = NULL;
--win->file_info->undo_count;
node->next = node->prev = NULL;
++win->file_info->length;
if (win->ll->prev != NULL)
win->ll->prev->next = node;
node->prev = win->ll->prev;
win->ll->prev = node;
node->next = win->ll;
win->ll = node;
win->ll->dirty = TRUE;
if (win->ll->prev == NULL)
win->file_info->line_list = win->ll;
adjust_windows_cursor( win, 1 );
/*
* we have now undeleted a line. increment the file length and display
* it.
*/
win->file_info->dirty = GLOBAL;
show_size( win );
show_avail_mem( );
}
return( OK );
}
/*
* Name: beg_next_line
* Purpose: To move the cursor to the beginning of the next line.
* Date: October 4, 1991
* Passed: window: pointer to current window
*/
int beg_next_line( WINDOW *window )
{
int rc;
window->rcol = 0;
rc = prepare_move_down( window );
check_virtual_col( window, window->rcol, window->ccol );
sync( window );
make_ruler( window );
show_ruler( window );
return( rc );
}
/*
* Name: next_line
* Purpose: To move the cursor to the first character of the next line.
* Date: October 4, 1991
* Passed: window: pointer to current window
*/
int next_line( WINDOW *window )
{
register int rcol;
register WINDOW *win; /* put window pointer in a register */
int rc;
win = window;
rc = prepare_move_down( win );
rcol = first_non_blank( win->ll->line, win->ll->len );
check_virtual_col( win, rcol, win->ccol );
sync( win );
make_ruler( win );
show_ruler( win );
return( rc );
}
/*
* Name: home
* Purpose: To move the cursor to the left of the current line.
* Date: June 5, 1991
* Passed: window: pointer to current window
* Notes: this routine is made a little more complicated with cursor sync.
* if the g_status.copied flag is set we need to see from what file
* the line_buff was copied.
*/
int home( WINDOW *window )
{
register int rcol;
register WINDOW *win; /* put window pointer in a register */
text_ptr p;
win = window;
if (g_status.copied && win->file_info == g_status.current_window->file_info){
rcol = first_non_blank( (text_ptr)g_status.line_buff,
g_status.line_buff_len );
if (is_line_blank( (text_ptr)g_status.line_buff, g_status.line_buff_len))
rcol = 0;
} else {
p = win->ll->line;
if (p == NULL)
rcol = 0;
else {
rcol = first_non_blank( p, win->ll->len );
if (is_line_blank( p, win->ll->len ))
rcol = 0;
}
}
if (win->rcol == rcol)
rcol = 0;
check_virtual_col( win, rcol, win->ccol );
sync( win );
make_ruler( win );
show_ruler( win );
return( OK );
}
/*
* Name: goto_eol
* Purpose: To move the cursor to the eol character of the current line.
* Date: June 5, 1991
* Passed: window: pointer to current window
* Notes: this routine is made a little more complicated with cursor sync.
* if the g_status.copied flag is set we need to see from what file
* the line_buff was copied.
*/
int goto_eol( WINDOW *window )
{
register int rcol;
register WINDOW *win; /* put window pointer in a register */
win = window;
rcol = find_end( win->ll->line, win->ll->len );
if (g_status.copied) {
if (win->file_info == g_status.current_window->file_info)
rcol = find_end( (text_ptr)g_status.line_buff, g_status.line_buff_len);
}
win->ccol = win->start_col + rcol - win->bcol;
check_virtual_col( win, rcol, win->ccol );
sync( win );
make_ruler( win );
show_ruler( win );
return( OK );
}
/*
* Name: goto_top
* Purpose: To move the cursor to the top of the current window.
* Date: June 5, 1991
* Passed: window: pointer to current window
* Notes: If the start of the file occurs before the top of the window,
* then the start of the file is moved to the top of the window.
*/
int goto_top( WINDOW *window )
{
register WINDOW *win; /* put window pointer in a register */
win = window;
entab_linebuff( );
if (un_copy_line( win->ll, win, TRUE ) == ERROR)
return( ERROR );
update_line( win );
for (; win->cline > win->top_line+win->ruler; win->cline--,win->rline--) {
if (win->rline <= 1L)
break;
else {
win->ll = win->ll->prev;
win->bin_offset -= win->ll->len;
}
}
show_curl_line( win );
sync( win );
return( OK );
}
/*
* Name: goto_bottom
* Purpose: To move the cursor to the bottom of the current window.
* Date: June 5, 1991
* Passed: window: pointer to current window
*/
int goto_bottom( WINDOW *window )
{
register WINDOW *win; /* put window pointer in a register */
int at_top;
win = window;
entab_linebuff( );
if (un_copy_line( win->ll, win, TRUE ) == ERROR)
return( ERROR );
if (win->ll->len == EOF) {
if (win->rline > 1) {
at_top = FALSE;
if (win->cline == win->top_line + win->ruler) {
win->file_info->dirty = LOCAL;
at_top = TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -