Skip to content

Commit

Permalink
Fix the kill-line, backward-kill-line and kill-whole-line commands to…
Browse files Browse the repository at this point in the history
… work correctly with multiline editing

darcs-hash:20061012132732-ac50b-03fe641cf32ace645c88174528e849ab0d1ecb4b.gz
  • Loading branch information
liljencrantz committed Oct 12, 2006
1 parent 97f7c20 commit b70b966
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 29 deletions.
58 changes: 58 additions & 0 deletions kill.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,64 @@ void kill_add( wchar_t *str )
}
}

/**
Remove the specified node from the circular list
*/
static void kill_remove_node( ll_node_t *n )
{
if( n->prev == n )
{
kill_last=kill_current = 0;
}
else
{
ll_node_t *nxt = n->prev;
while( nxt->prev != n )
{
nxt=nxt->prev;
}
nxt->prev = n->prev;
if( kill_last == n )
{
kill_last = n->prev;
}
kill_current=kill_last;
free( n->data );
free( n );
}
}

/**
Remove first match for specified string from circular list
*/
static void kill_remove( wchar_t *s )
{
ll_node_t *n, *next;

if( !kill_last )
{
return;
}

for( n=kill_last;
n!=kill_last || next == 0 ;
n=n->prev )
{
if( wcscmp( (wchar_t *)n->data, s ) == 0 )
{
kill_remove_node( n );
}
next = n;
}
}



void kill_replace( wchar_t *old, wchar_t *new )
{
kill_remove( old );
kill_add( new );
}

wchar_t *kill_yank_rotate()
{
Expand Down
6 changes: 6 additions & 0 deletions kill.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

#include <wchar.h>

/**
Replace the specified string in the killring
*/
void kill_replace( wchar_t *old, wchar_t *new );


/**
Add a string to the top of the killring
*/
Expand Down
157 changes: 128 additions & 29 deletions reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ commence.
*/
#define READAHEAD_MAX 256

#define KILL_APPEND 0
#define KILL_PREPEND 1

/**
A struct describing the state of the interactive reader. These
states can be stacked, in case reader_readline is called from
Expand Down Expand Up @@ -241,6 +244,8 @@ typedef struct reader_data
*/
int prev_end_loop;

string_buffer_t kill_item;

/**
Pointer to previous reader_data
*/
Expand Down Expand Up @@ -366,6 +371,35 @@ int reader_exit_forced()
return exit_forced;
}

static void reader_kill( wchar_t *begin, int length, int mode, int new )
{
if( new )
{
sb_clear( &data->kill_item );
sb_append_substring( &data->kill_item, begin, length );
kill_add( (wchar_t *)data->kill_item.buff );
}
else
{

wchar_t *old = wcsdup( (wchar_t *)data->kill_item.buff);

if( mode == KILL_APPEND )
{
sb_append_substring( &data->kill_item, begin, length );
}
else
{
sb_clear( &data->kill_item );
sb_append_substring( &data->kill_item, begin, length );
sb_append( &data->kill_item, old );
}


kill_replace( old, (wchar_t *)data->kill_item.buff );
free( old );
}
}

/**
string_buffer used as temporary storage for the reader_readline function
Expand Down Expand Up @@ -725,6 +759,10 @@ static int insert_str(wchar_t *str)
int len = wcslen( str );
int old_len = data->buff_len;

assert( data->buff_pos >= 0 );
assert( data->buff_pos <= data->buff_len );
assert( len >= 0 );

data->buff_len += len;
check_size();

Expand Down Expand Up @@ -1150,9 +1188,7 @@ static int handle_completions( array_list_t *comp )
get_param( data->buff, data->buff_pos, &quote, 0, 0, 0 );
is_quoted = (quote != L'\0');

writech(L'\n');


write(1, "\n", 1 );

run_pager( prefix, is_quoted, comp );

Expand Down Expand Up @@ -1718,6 +1754,7 @@ void reader_push( wchar_t *name )
reader_data_t *n = calloc( 1, sizeof( reader_data_t ) );
n->name = wcsdup( name );
n->next = data;
sb_init( &n->kill_item );

data=n;

Expand Down Expand Up @@ -1761,6 +1798,7 @@ void reader_pop()
free( n->color );
free( n->indent );
free( n->search_buff );
sb_destroy( &n->kill_item );

s_destroy( &n->screen );
sb_destroy( &n->prompt_buff );
Expand Down Expand Up @@ -2135,51 +2173,112 @@ wchar_t *reader_readline()
break;
}

/* kill*/
/* kill */
case R_KILL_LINE:
{
kill_add( &data->buff[data->buff_pos] );
data->buff_len = data->buff_pos;
data->buff[data->buff_len]=L'\0';


repaint();
wchar_t *begin = &data->buff[data->buff_pos];
wchar_t *end = begin;
int len;

while( *end && *end != L'\n' )
end++;

if( end==begin && *end )
end++;

len = end-begin;

if( len )
{

reader_kill( begin, len, KILL_APPEND, last_char!=R_KILL_LINE );

memmove( begin, end, sizeof( wchar_t )*(wcslen( end )+1) );
data->buff_len -= len;

reader_super_highlight_me_plenty( data->color, data->buff_pos, 0 );
repaint();
}

break;
}

case R_BACKWARD_KILL_LINE:
{
wchar_t *str = wcsndup( data->buff, data->buff_pos );
if( !str )
DIE_MEM();

kill_add( str );
free( str );

data->buff_len = wcslen(data->buff +data->buff_pos);
memmove( data->buff, data->buff +data->buff_pos, sizeof(wchar_t)*data->buff_len );
data->buff[data->buff_len]=L'\0';
data->buff_pos=0;
reader_super_highlight_me_plenty( data->color, data->buff_pos, 0 );
if( data->buff_pos > 0 )
{
wchar_t *end = &data->buff[data->buff_pos];
wchar_t *begin = end;
int len;

while( begin > data->buff && *begin != L'\n' )
begin--;

if( *begin == L'\n' )
begin++;

len = maxi( end-begin, 1 );
begin = end - len;

reader_kill( begin, len, KILL_PREPEND, last_char!=R_BACKWARD_KILL_LINE );

memmove( begin, end, sizeof( wchar_t )*(wcslen( end )+1) );
data->buff_pos -= len;
data->buff_len -= len;


repaint();
reader_super_highlight_me_plenty( data->color, data->buff_pos, 0 );
repaint();

}
break;

}

case R_KILL_WHOLE_LINE:
{
kill_add( data->buff );
data->buff_len = data->buff_pos = 0;
data->buff[data->buff_len]=L'\0';
reader_super_highlight_me_plenty( data->color, data->buff_pos, 0 );
wchar_t *end = &data->buff[data->buff_pos];
wchar_t *begin = end;
int len;
//debug( 0, L"WOOOOOT" );

while( begin > data->buff && *begin != L'\n' )
begin--;

if( *begin == L'\n' )
begin++;

len = maxi( end-begin, 0 );
begin = end - len;

repaint();
while( *end && *end != L'\n' )
end++;

if( begin == end && *end )
end++;

len = end-begin;

if( len )
{

reader_kill( begin, len, KILL_APPEND, last_char!=R_KILL_WHOLE_LINE );

memmove( begin, end, sizeof( wchar_t )*(wcslen( end )+1) );
data->buff_pos = begin - data->buff;
data->buff_len -= len;

reader_super_highlight_me_plenty( data->color, data->buff_pos, 0 );
repaint();
}

break;
}

/* yank*/
case R_YANK:
{ yank_str = kill_yank();
{
yank_str = kill_yank();
insert_str( yank_str );
yank = wcslen( yank_str );
break;
Expand Down

0 comments on commit b70b966

Please sign in to comment.