📄 findrep.c
字号:
i = len - 1;
last_c = p[i];
if (mode.search_case == IGNORE) {
last_c = tolower( last_c );
for (i--; i >= 0 && last_c != tolower( p[i] ); i--)
++md2;
} else
for (i--; i >= 0 && last_c != p[i]; i--)
++md2;
assert( md2 >= 1 && md2 <= len );
return( md2 );
}
int calculate_backward_md2( char *p, int len )
{
int first_c;
register int i;
register int md2;
md2 = -1;
i = 1;
first_c = *p;
if (mode.search_case == IGNORE) {
first_c = tolower( first_c );
for (; i < len && first_c != tolower( p[i] ); i++)
--md2;
} else
for (; i < len && first_c != p[i]; i++)
--md2;
assert( md2 <= -1 && md2 >= -len );
return( md2 );
}
line_list_ptr forward_boyer_moore_search( WINDOW *window, long *rline,
int *rcol )
{
register int len;
int i;
int end;
register WINDOW *win;
line_list_ptr ll;
win = window;
i = win->rcol + 1;
len = win->ll->len;
if (i > len)
i = len;
if (i < 0)
i = 0;
*rcol = i;
assert( *rcol >= 0 );
*rline = win->rline;
ll = search_forward( win->ll, rline, (size_t *)rcol );
if (ll == NULL) {
end = 0;
if (win->ll->next != NULL) {
end = win->ll->next->len;
win->ll->next->len = EOF;
}
g_status.wrapped = TRUE;
*rcol = 0;
*rline = 1L;
ll = search_forward( win->file_info->line_list, rline, (size_t *)rcol );
if (ll == win->ll && *rcol >= win->rcol)
ll = NULL;
if (win->ll->next != NULL)
win->ll->next->len = end;
}
if (ll != NULL)
bin_offset_adjust( win, *rline );
return( ll );
}
line_list_ptr search_forward( line_list_ptr ll, long *rline, size_t *offset )
{
register int i;
text_ptr p;
text_ptr q;
int mini_delta2;
unsigned int mini_guard;
int guard;
int pat_len;
int len_s;
text_ptr s;
char *skip;
boyer_moore_type *bmp;
if (ll->len == EOF)
return( NULL );
else {
if (g_status.command == DefineGrep || g_status.command == RepeatGrep)
bmp = &sas_bm;
else
bmp = &bm;
pat_len = bmp->pattern_length;
mini_delta2 = bmp->forward_md2;
skip = bmp->skip_forward;
p = bmp->pattern;
i = pat_len - 1;
guard = -i;
mini_guard = *p;
if (mode.search_case != MATCH)
mini_guard = tolower( mini_guard );
s = ll->line;
s += *offset;
len_s = ll->len - *offset;
for (;;) {
for (s+=i, len_s-=i; len_s > 0 && (i = skip[(unsigned char)*s]);
s+=i, len_s-=i);
if (len_s > 0) {
if (mode.search_case == MATCH) {
if (s[guard] != mini_guard)
goto shift_func;
q = s + 1 - pat_len;
for (i=0; i < pat_len; i++)
if (q[i] != p[i])
goto shift_func;
} else {
if ((unsigned int)tolower( s[guard] ) != mini_guard)
goto shift_func;
q = s + 1 - pat_len;
for (i=0; i < pat_len; i++)
if (tolower( q[i] ) != tolower( p[i] ))
goto shift_func;
}
*offset = (size_t)(q - ll->line);
assert( *offset <= (unsigned)(ll->len - pat_len) );
return( ll );
}
shift_func:
if (len_s <= 0) {
++*rline;
ll = ll->next;
s = ll->line;
if (ll->len == EOF)
return( NULL );
len_s = ll->len;
i = pat_len - 1;
} else
i = mini_delta2;
}
}
}
line_list_ptr backward_boyer_moore_search( WINDOW *window, long *rline, int *rcol )
{
int i;
int len;
int end;
register WINDOW *win;
line_list_ptr ll;
win = window;
*rline = win->rline;
if (win->ll->len != EOF) {
ll = win->ll;
i = win->rcol - 1;
i += bm.pattern_length - 1;
len = ll->len;
if (i >= len)
i = len - 1;
} else {
ll = win->ll->prev;
--*rline;
i = 0;
if (ll != NULL)
i = ll->len - 1;
}
*rcol = i;
ll = search_backward( ll, rline, (size_t *)rcol );
if (ll == NULL && win->rline <= win->file_info->length) {
end = 0;
if (win->ll->prev != NULL) {
end = win->ll->prev->len;
win->ll->prev->len = EOF;
}
g_status.wrapped = TRUE;
ll = win->file_info->line_list_end;
if (ll->prev != NULL)
*rcol = ll->prev->len;
else
*rcol = 0;
*rline = win->file_info->length;
ll = search_backward( ll->prev, rline, (size_t *)rcol );
if (ll == win->ll && *rcol <= win->rcol)
ll = NULL;
if (win->ll->prev != NULL)
win->ll->prev->len = end;
}
if (ll != NULL)
bin_offset_adjust( win, *rline );
return( ll );
}
line_list_ptr search_backward( line_list_ptr ll, long *rline, size_t *offset )
{
register int i;
text_ptr p;
int mini_delta2;
int pat_len;
int len_s;
text_ptr s;
if (ll == NULL)
return( NULL );
if (ll->len == EOF)
return( NULL );
else {
mini_delta2 = bm.backward_md2;
pat_len = bm.pattern_length;
p = bm.pattern;
i = -bm.pattern_length + 1;
s = ll->line;
s += *offset;
len_s = *offset + 1;
for (;;) {
for (s+=i, len_s+=i; len_s > 0 &&
(i = bm.skip_backward[(unsigned char)*s]); s+=i, len_s+=i);
if (len_s > 0) {
if (mode.search_case == MATCH) {
for (i=0; i < pat_len; i++)
if (s[i] != p[i])
goto shift_func;
} else {
for (i=0; i < pat_len; i++)
if (tolower( s[i] ) != tolower( p[i] ))
goto shift_func;
}
*offset =(size_t)(s - ll->line);
assert( *offset <= (unsigned)(ll->len - pat_len) );
return( ll );
}
shift_func:
if (len_s <= 0) {
--*rline;
ll = ll->prev;
if (ll == NULL)
return( NULL );
if (ll->len == EOF)
return( NULL );
len_s = ll->len;
s = ll->line + len_s - 1;
i = 1 - pat_len;
} else
i = mini_delta2;
}
}
}
void show_search_message( int i, int color )
{
assert( i >= 0 && i <= 4);
s_output( find7[i], g_display.mode_line, 67, color );
}
void bin_offset_adjust( WINDOW *window, long rline )
{
line_list_ptr node;
long found_distance;
assert( rline >= 1L && rline <= window->file_info->length );
found_distance = window->rline - rline;
node = window->ll;
if (found_distance < 0) {
while (found_distance++ < 0) {
window->bin_offset += node->len;
node = node->next;
}
} else if (found_distance > 0) {
while (found_distance-- > 0) {
node = node->prev;
window->bin_offset -= node->len;
}
}
assert( window->bin_offset >= 0 );
}
void find_adjust( WINDOW *window, line_list_ptr ll, long rline, int rcol )
{
int cmd;
long test_line;
file_infos *file;
register WINDOW *win;
win = window;
file = win->file_info;
if (mode.inflate_tabs)
rcol = detab_adjust_rcol( ll->line, rcol );
if (win->rline < rline) {
test_line = rline - win->rline;
if ((long)win->cline + test_line <= (long)win->bottom_line)
win->cline += (int)test_line;
else
file->dirty = LOCAL;
} else if (win->rline > rline) {
test_line = win->rline - rline;
if ((long)win->cline - test_line > (long)(win->top_line+win->ruler-1))
win->cline -= (int)test_line;
else
file->dirty = LOCAL;
if (rline < (long)(win->cline - (win->top_line+win->ruler-1)))
win->cline = (int)rline + win->top_line+win->ruler - 1;
}
win->rline = rline;
win->ll = ll;
if (file->dirty == LOCAL && (win->cline == win->bottom_line ||
win->cline == win->top_line + win->ruler)) {
cmd = g_status.command;
if (cmd == RepeatFindForward1 || cmd == RepeatFindBackward1 ||
cmd == DefineDiff || cmd == RepeatDiff ||
cmd == FindRegX || cmd == RepeatFindRegX ||
cmd == DefineGrep || cmd == RepeatGrep) {
center_window( win );
} else if (cmd == ReplaceString) {
if (win->visible)
center_window( win );
}
}
check_virtual_col( win, rcol, rcol );
}
int replace_string( WINDOW *window )
{
int direction;
char pattern[MAX_COLS];
int net_change;
int sub_len;
int file_changed;
int finished;
int use_prev_find;
int rc;
int rcol;
int rcol_limit;
int wrapped;
int wrapped_state;
long found_line;
long line_limit;
line_list_ptr ll;
WINDOW wp;
WINDOW old_wp;
register WINDOW *win;
int visible;
win = window;
direction = get_replace_direction( win );
if (direction == ERROR)
return( ERROR );
entab_linebuff( );
if (un_copy_line( win->ll, win, TRUE ) == ERROR)
return( ERROR );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -