📄 findrep.c
字号:
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; /* put window pointer in a register */
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 );
/*
* get the search pattern, using the previous as the default
*/
*pattern = '\0';
if (g_status.replace_defined == OK) {
assert( strlen( g_status.pattern ) < MAX_COLS );
strcpy( pattern, g_status.pattern );
}
/*
* string to find
*/
if (get_name( find9, win->bottom_line, pattern,
g_display.message_color ) != OK || *pattern == '\0')
return( ERROR );
assert( strlen( pattern ) < MAX_COLS );
strcpy( g_status.pattern, pattern );
/*
* get the replacement text, using the previous as the default
*/
*pattern = '\0';
if (g_status.replace_defined == OK) {
assert( strlen( g_status.subst ) < MAX_COLS );
strcpy( pattern, g_status.subst );
}
if (get_name( find10, win->bottom_line, pattern,
g_display.message_color ) != OK)
return( ERROR );
assert( strlen( pattern ) < MAX_COLS );
strcpy( g_status.subst, pattern );
sub_len = strlen( pattern );
strcpy( (char *)bm.pattern, g_status.pattern );
net_change = sub_len - strlen( g_status.pattern );
/*
* get the replace flags, Prompt or NoPrompt
*/
if (get_replacement_flags( win->bottom_line ) != OK)
return( ERROR );
build_boyer_array( );
dup_window_info( &wp, win );
update_line( win );
g_status.replace_defined = OK;
if (mode.inflate_tabs)
win->rcol = entab_adjust_rcol( win->ll->line, win->ll->len, win->rcol );
rc = OK;
visible = win->visible;
if (g_status.replace_flag == NOPROMPT) {
wp.visible = FALSE;
xygoto( win->ccol, win->cline );
show_search_message( REPLACING, g_display.diag_color );
}
wrapped_state = wrapped = FALSE;
finished = FALSE;
file_changed = FALSE;
use_prev_find = FALSE;
line_limit = 0;
rcol_limit = 0;
dup_window_info( &old_wp, &wp );
if (direction == FORWARD) {
if ((ll = forward_boyer_moore_search( &wp, &found_line, &rcol )) != NULL &&
!g_status.control_break) {
line_limit = found_line;
rcol_limit = rcol;
if (g_status.wrapped)
wrapped_state = wrapped = TRUE;
rc = replace_and_display( &wp, ll, found_line, rcol, &finished,
&file_changed, direction );
if (rc == ERROR && g_status.replace_flag == PROMPT && wrapped_state)
use_prev_find = TRUE;
} else {
/*
* string not found
*/
error( WARNING, win->bottom_line, find8 );
finished = TRUE;
rc = ERROR;
}
while (finished == FALSE) {
use_prev_find = wrapped_state = FALSE;
dup_window_info( &old_wp, &wp );
if (wp.visible == TRUE)
update_line( &wp );
if ((ll = forward_boyer_moore_search( &wp, &found_line, &rcol )) != NULL &&
!g_status.control_break) {
if (g_status.wrapped)
wrapped_state = wrapped = TRUE;
if (wrapped) {
if (found_line > line_limit) {
finished = TRUE;
use_prev_find = TRUE;
} else if (found_line == line_limit && rcol == rcol_limit) {
finished = TRUE;
use_prev_find = TRUE;
}
}
if (finished == FALSE) {
rc = replace_and_display( &wp, ll, found_line, rcol, &finished,
&file_changed, direction );
if (rc == OK && ll == win->ll && rcol < rcol_limit)
rcol_limit += net_change;
if (rc == ERROR && g_status.replace_flag == PROMPT &&
wrapped_state)
use_prev_find = TRUE;
}
} else {
if (g_status.control_break)
rc = getkey( );
/*
* string not found or control break
*/
if (g_status.control_break)
error( WARNING, win->bottom_line, cb );
else if (wp.visible)
error( WARNING, win->bottom_line, find8 );
finished = TRUE;
rc = ERROR;
}
}
} else {
if ((ll = backward_boyer_moore_search( &wp, &found_line, &rcol )) != NULL &&
!g_status.control_break) {
line_limit = found_line;
rcol_limit = rcol;
if (g_status.wrapped)
wrapped_state = wrapped = TRUE;
replace_and_display( &wp, ll, found_line, rcol, &finished, &file_changed,
direction );
if (rc == ERROR && g_status.replace_flag == PROMPT && wrapped_state)
use_prev_find = TRUE;
} else {
/*
* string not found
*/
error( WARNING, win->bottom_line, find8 );
finished = TRUE;
rc = ERROR;
}
while (finished == FALSE) {
use_prev_find = wrapped_state = FALSE;
dup_window_info( &old_wp, &wp );
if (wp.visible == TRUE)
update_line( &wp );
if ((ll = backward_boyer_moore_search( &wp, &found_line, &rcol )) != NULL &&
!g_status.control_break) {
if (g_status.wrapped)
wrapped_state = wrapped = TRUE;
if (wrapped) {
if (found_line < line_limit) {
finished = TRUE;
use_prev_find = TRUE;
} else if (found_line == line_limit && rcol == rcol_limit) {
finished = TRUE;
use_prev_find = TRUE;
}
}
if (finished == FALSE) {
rc = replace_and_display( &wp, ll, found_line, rcol, &finished,
&file_changed, direction );
if (rc == OK && found_line == line_limit && rcol < rcol_limit)
rcol_limit += net_change;
if (rc == ERROR && g_status.replace_flag == PROMPT &&
wrapped_state)
use_prev_find = TRUE;
}
} else {
if (g_status.control_break)
rc = getkey( );
/*
* string not found or control break
*/
if (g_status.control_break)
error( WARNING, win->bottom_line, cb );
else if (wp.visible)
error( WARNING, win->bottom_line, find8 );
finished = TRUE;
rc = ERROR;
}
}
}
if (g_status.replace_flag == PROMPT) {
if (use_prev_find)
dup_window_info( &wp, &old_wp );
dup_window_info( win, &wp );
} else {
show_search_message( CLR_SEARCH, g_display.mode_color );
g_status.wrapped = FALSE;
}
if (mode.inflate_tabs)
win->rcol = detab_adjust_rcol( win->ll->line, win->rcol );
win->visible = visible;
check_virtual_col( win, win->rcol, win->ccol );
if (win->file_info->dirty != LOCAL && win->file_info->dirty != GLOBAL)
show_curl_line( win );
if (file_changed)
win->file_info->modified = TRUE;
make_ruler( win );
show_ruler( win );
show_ruler_pointer( win );
return( rc );
}
/*
* Name: replace_and_display
* Purpose: To make room for replacement string
* Date: June 5, 1991
* Passed: window: pointer to current window
* ll: pointer to position of pattern in file
* rline: pointer to real line counter
* rcol: pointer to real column
* finished: stop replacing on this occurrence?
* modified: skip this replacement?
* direction: direction of search
* Notes: Show user where pattern_location is on screen if needed.
* Replace and display if needed. Always ask the user if he
* wants to do wrapped replacing.
*/
int replace_and_display( WINDOW *window, line_list_ptr ll, long rline,
int rcol, int *finished, int *modified, int direction )
{
register int rc;
file_infos *file;
register WINDOW *win; /* put window pointer in a register */
win = window;
file = win->file_info;
rc = OK;
if (g_status.wrapped) {
rc = ask_wrap_replace( win, finished );
g_status.wrapped = FALSE;
show_search_message( CLR_SEARCH, g_display.mode_color );
}
if (rc == OK) {
find_adjust( win, ll, rline, rcol );
if (win->visible == TRUE) {
make_ruler( win );
show_ruler( win );
show_ruler_pointer( win );
xygoto( win->ccol, win->cline );
if (file->dirty) {
display_current_window( win );
file->dirty = FALSE;
} else
show_curl_line( win );
}
if (g_status.replace_flag == PROMPT && rc == OK) {
show_line_col( win );
rc = ask_replace( win, finished );
}
if (rc == OK) {
do_replace( win, direction );
*modified = TRUE;
file->dirty = GLOBAL;
if (win->visible == TRUE) {
show_changed_line( win );
file->dirty = FALSE;
}
}
if (mode.inflate_tabs) {
if (win->rcol >= 0)
win->rcol = entab_adjust_rcol( ll->line, ll->len, win->rcol );
}
}
return( rc );
}
/*
* Name: scan_forward
* Purpose: To find the corresponding occurrence of target, ignoring
* embedded pairs of opp and target, searching forwards.
* Date: June 5, 1991
* Passed: rline: pointer to real line position
* rcol: pointer to real column position
* ll: pointer to current node in linked list
* opp: the opposite to target
* target: the string to be found
* rc: OK if found, ERROR otherwise
* Returns: the location of the corresponding target in the text buffer
* Notes: Every 8,000 characters, check pointer forward.
*/
line_list_ptr scan_forward( long *rline, int *rcol, line_list_ptr ll,
char opp, char target, int *rc )
{
text_ptr s;
int count = 0; /* number of unmatched opposites found */
int len;
register char c;
*rc = OK;
if (ll != NULL && ll->len != EOF) {
len = ll->len - *rcol - 1;
s = ll->line + *rcol + 1;
while (ll->len != EOF) {
while (len > 0) {
assert( s != NULL);
c = *s++;
--len;
if (opp == c)
count++;
else if (target == c) {
if (count == 0)
goto match;
--count;
}
}
++*rline;
ll = ll->next;
s = ll->line;
len = ll->len;
}
match:
if (ll->len != EOF) {
assert( s != NULL );
*rcol = (int)(s - ll->line - 1);
} else
*rc = ERROR;
} else
*rc = ERROR;
if (*rc == OK) {
assert( *rcol >= 0 );
assert( *rcol < ll->len );
}
return( ll );
}
/*
* Name: scan_backward
* Purpose: To find the corresponding occurrence of target, ignoring
* embedded pairs of opp and target, searching backwards.
* Date: June 5, 1991
* Passed: rline: pointer to real line position
* rcol: pointer to real column position
* ll: pointer to current node in linked list
* opp: the opposite to target
* target: the string to be found
* rc: OK if found, ERROR otherwise
* Returns: the location of the corresponding target in the text buffer
*/
line_list_ptr scan_backward( long *rline, int *rcol, line_list_ptr ll,
char opp, char target, int *rc )
{
text_ptr s;
int count = 0; /* number of unmatched opposites found */
register int len;
register char c;
*rc = OK;
if (ll != NULL && ll->len != EOF) {
s = ll->line + *rcol - 1;
len = *rcol;
while (ll != NULL) {
while (len > 0) {
assert( s != NULL );
c = *s--;
if (opp == c)
count++;
else if (target == c) {
if (count == 0)
goto match;
--count;
}
--len;
}
--*rline;
ll = ll->prev;
if (ll != NULL) {
len = ll->len;
s = ll->line + len - 1;
}
}
match:
if (ll != NULL) {
assert( s != NULL );
*rcol = (int)(s - ll->line + 1);
} else
*rc = ERROR;
} else
*rc = ERROR;
if (*rc == OK) {
assert( *rcol >= 0 );
assert( *rcol < ll->len );
}
return( ll );
}
/*
* Name: match_pair
* Purpose: To find the corresponding pair to the character under the
* cursor.
* Date: June 5, 1991
* Passed: window: pointer to current window
* Notes: Searching is very simple-minded, and does not cope with things
* like brackets embedded within quoted strings.
*/
int match_pair( WINDOW *window )
{
long rline;
char c;
register WINDOW *win; /* put window pointer in a register */
int rc;
int rcol;
line_list_ptr ll;
win = window;
entab_linebuff( );
rline = win->rline;
ll = win->ll;
if (un_copy_line( ll, win, TRUE ) == ERROR)
return( ERROR );
/*
* make sure the character under the cursor is one that has a
* matched pair
*/
if (ll->len == EOF || win->rcol >= ll->len)
return( ERROR );
rcol = win->rcol;
c = *(ll->line + rcol);
rc = OK;
/*
* find the matching pair
*/
switch (c) {
case '[':
ll = scan_forward( &rline, &rcol, ll, '[', ']', &rc );
break;
case '(':
ll = scan_forward( &rline, &rcol, ll, '(', ')', &rc );
break;
case '{':
ll = scan_forward( &rline, &rcol, ll, '{', '}', &rc );
break;
case ']':
ll = scan_backward( &rline, &rcol, ll, ']', '[', &rc );
break;
case ')':
ll = scan_backward( &rline, &rcol, ll, ')', '(', &rc );
break;
case '}':
ll = scan_backward( &rline, &rcol, ll, '}', '{', &rc );
break;
default :
rc = ERROR;
}
/*
* now show the user what we have found
*/
if (rc == OK) {
update_line( win );
bin_offset_adjust( win, rline );
find_adjust( win, ll, rline, rcol );
if (!win->file_info->dirty)
show_curl_line( win );
make_ruler( win );
show_ruler( win );
}
return( rc );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -