String seek bug fixed; cleaner isearch implementation

master
Allen Webster 2019-10-01 15:45:51 -07:00
parent 3e31e78d1f
commit 843ff44b6e
4 changed files with 146 additions and 164 deletions

View File

@ -288,13 +288,12 @@ Buffer_Seek_String(Application_Links *app, Buffer_ID buffer, String_Const_u8 nee
range = make_range_i64(adjusted_pos, size);
}
else{
i64 adjusted_pos = start_pos - 1;
i64 adjusted_pos = start_pos - 1 + needle.size;
start_pos = clamp_bot(0, adjusted_pos);
range = make_range_i64(0, adjusted_pos);
}
buffer_chunks_clamp(&chunks, range);
if (chunks.first != 0){
u64_Array jump_table = string_compute_needle_jump_table(scratch, needle, direction);
Character_Predicate dummy = {};
String_Match_List list = find_all_matches(scratch, 1,

View File

@ -204,6 +204,9 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count,
if (chunk_pos < 0){
last_boundary = i;
node = node->next;
if (node != 0){
chunk_pos = node->string.size - 1;
}
}
switch (jump_back_code){

View File

@ -798,65 +798,57 @@ isearch__update_highlight(Application_Links *app, View_ID view, Range_i64 range)
}
static void
isearch(Application_Links *app, b32 start_reversed, String_Const_u8 query_init, b32 on_the_query_init_string){
isearch(Application_Links *app, Scan_Direction start_scan, String_Const_u8 query_init){
View_ID view = get_active_view(app, AccessProtected);
Buffer_ID buffer = view_get_buffer(app, view, AccessProtected);
if (!buffer_exists(app, buffer)){
return;
}
i64 buffer_size = buffer_get_size(app, buffer);
Query_Bar bar = {};
if (start_query_bar(app, &bar, 0) == 0){
return;
}
b32 reverse = start_reversed;
Scan_Direction scan = start_scan;
i64 first_pos = view_get_cursor_pos(app, view);
i64 pos = first_pos;
if (query_init.size != 0){
pos += 2;
}
i64 start_pos = pos;
Range_i64 match = Ii64(pos);
u8 bar_string_space[256];
bar.string = SCu8(bar_string_space, query_init.size);
block_copy(bar.string.str, query_init.str, query_init.size);
String_Const_char isearch_str = string_litexpr("I-Search: ");
String_Const_char rsearch_str = string_litexpr("Reverse-I-Search: ");
String_Const_u8 isearch_str = string_u8_litexpr("I-Search: ");
String_Const_u8 rsearch_str = string_u8_litexpr("Reverse-I-Search: ");
b32 first_step = true;
// TODO(allen): rewrite
isearch__update_highlight(app, view, match);
umem match_size = bar.string.size;
cursor_is_hidden = true;
User_Input in = {};
for (;;){
// NOTE(allen): Change the bar's prompt to match the current direction.
if (reverse){
bar.prompt = SCu8(rsearch_str);
}
else{
bar.prompt = SCu8(isearch_str);
switch (scan){
case Scan_Forward:
{
bar.prompt = isearch_str;
}break;
case Scan_Backward:
{
bar.prompt = rsearch_str;
}break;
}
isearch__update_highlight(app, view, Ii64_size(pos, match_size));
b32 step_forward = false;
b32 step_backward = false;
b32 backspace = false;
b32 suppress_highligh_update = false;
if (!first_step){
in = get_user_input(app, EventOnAnyKey, EventOnEsc);
if (in.abort) break;
if (in.abort){
break;
}
u8 character[4];
u32 length = to_writable_character(in, character);
b32 made_change = false;
b32 string_change = false;
if (in.key.keycode == '\n' || in.key.keycode == '\t'){
if (in.key.modifiers[MDFR_CONTROL_INDEX]){
bar.string.size = cstring_length(previous_isearch_query);
@ -874,101 +866,89 @@ isearch(Application_Links *app, b32 start_reversed, String_Const_u8 query_init,
String_u8 string = Su8(bar.string, sizeof(bar_string_space));
string_append(&string, SCu8(character, length));
bar.string = string.string;
made_change = true;
string_change = true;
}
else if (in.key.keycode == key_back){
if (key_is_unmodified(&in.key)){
umem old_bar_string_size = bar.string.size;
bar.string = backspace_utf8(bar.string);
made_change = (bar.string.size < old_bar_string_size);
backspace = true;
string_change = (bar.string.size < old_bar_string_size);
}
else if (in.key.modifiers[MDFR_CONTROL_INDEX]){
if (bar.string.size > 0){
made_change = true;
string_change = true;
bar.string.size = 0;
backspace = true;
}
}
}
if ((in.command.command == search) || in.key.keycode == key_page_down || in.key.keycode == key_down){
step_forward = true;
b32 do_scan_action = false;
Scan_Direction change_scan = scan;
if (!string_change){
if (in.command.command == search ||
in.key.keycode == key_page_down ||
in.key.keycode == key_down){
change_scan = Scan_Forward;
do_scan_action = true;
}
if (in.command.command == reverse_search ||
in.key.keycode == key_page_up ||
in.key.keycode == key_up){
change_scan = Scan_Backward;
do_scan_action = true;
}
if (in.command.command == mouse_wheel_scroll){
mouse_wheel_scroll(app);
suppress_highligh_update = true;
}
}
if ((in.command.command == reverse_search) || in.key.keycode == key_page_up || in.key.keycode == key_up){
step_backward = true;
}
}
else{
if (query_init.size != 0 && on_the_query_init_string){
step_backward = true;
}
first_step = false;
}
start_pos = pos;
if (step_forward && reverse){
start_pos = match.start + 1;
pos = start_pos;
reverse = false;
step_forward = false;
}
if (step_backward && !reverse){
start_pos = match.start - 1;
pos = start_pos;
reverse = true;
step_backward = false;
}
if (!backspace){
if (reverse){
if (string_change){
switch (scan){
case Scan_Forward:
{
i64 new_pos = 0;
buffer_seek_string_insensitive_backward(app, buffer, start_pos + 1, 0, bar.string, &new_pos);
if (new_pos >= 0){
if (step_backward){
pos = new_pos;
start_pos = new_pos;
buffer_seek_string_insensitive_backward(app, buffer, start_pos + 1, 0, bar.string, &new_pos);
if (new_pos < 0){
new_pos = start_pos;
}
}
match.start = new_pos;
match.end = match.start + (i32)bar.string.size;
}
}
else{
i64 new_pos = 0;
buffer_seek_string_insensitive_forward(app, buffer, start_pos, 0, bar.string, &new_pos);
i64 buffer_size = buffer_get_size(app, buffer);
buffer_seek_string_insensitive_forward(app, buffer, pos - 1, 0, bar.string, &new_pos);
if (new_pos < buffer_size){
if (step_forward){
pos = new_pos;
start_pos = new_pos;
buffer_seek_string_insensitive_forward(app, buffer, start_pos, 0, bar.string, &new_pos);
if (new_pos >= buffer_size){
new_pos = start_pos;
}
}
match.start = new_pos;
match.end = match.start + (i32)bar.string.size;
}
}
}
else{
if (match.end > match.start + (i32)bar.string.size){
match.end = match.start + (i32)bar.string.size;
}
match_size = bar.string.size;
}
}break;
if (!suppress_highligh_update){
isearch__update_highlight(app, view, match);
case Scan_Backward:
{
i64 new_pos = 0;
buffer_seek_string_insensitive_backward(app, buffer, pos + 1, 0, bar.string, &new_pos);
if (new_pos >= 0){
pos = new_pos;
match_size = bar.string.size;
}
}break;
}
}
else if (do_scan_action){
scan = change_scan;
switch (scan){
case Scan_Forward:
{
i64 new_pos = 0;
buffer_seek_string_insensitive_forward(app, buffer, pos, 0, bar.string, &new_pos);
if (new_pos < buffer_size){
pos = new_pos;
match_size = bar.string.size;
}
}break;
case Scan_Backward:
{
i64 new_pos = 0;
buffer_seek_string_insensitive_backward(app, buffer, pos, 0, bar.string, &new_pos);
if (new_pos >= 0){
pos = new_pos;
match_size = bar.string.size;
}
}break;
}
}
}
@ -987,13 +967,13 @@ isearch(Application_Links *app, b32 start_reversed, String_Const_u8 query_init,
CUSTOM_COMMAND_SIG(search)
CUSTOM_DOC("Begins an incremental search down through the current buffer for a user specified string.")
{
isearch(app, false, SCu8(), false);
isearch(app, Scan_Forward, SCu8());
}
CUSTOM_COMMAND_SIG(reverse_search)
CUSTOM_DOC("Begins an incremental search up through the current buffer for a user specified string.")
{
isearch(app, true, SCu8(), false);
isearch(app, Scan_Backward, SCu8());
}
CUSTOM_COMMAND_SIG(search_identifier)
@ -1004,7 +984,7 @@ CUSTOM_DOC("Begins an incremental search down through the current buffer for the
i64 pos = view_get_cursor_pos(app, view);
Scratch_Block scratch(app);
String_Const_u8 query = push_enclose_range_at_pos(app, scratch, buffer_id, pos, enclose_alpha_numeric_underscore);
isearch(app, false, query, true);
isearch(app, Scan_Forward, query);
}
CUSTOM_COMMAND_SIG(reverse_search_identifier)
@ -1015,7 +995,7 @@ CUSTOM_DOC("Begins an incremental search up through the current buffer for the w
i64 pos = view_get_cursor_pos(app, view);
Scratch_Block scratch(app);
String_Const_u8 query = push_enclose_range_at_pos(app, scratch, buffer_id, pos, enclose_alpha_numeric_underscore);
isearch(app, true, query, true);
isearch(app, Scan_Backward, query);
}
struct String_Pair{

View File

@ -333,37 +333,37 @@ static Command_Metadata fcoder_metacmd_table[226] = {
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 760 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 768 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 776 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 987 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 993 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 999 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1010 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1061 },
{ PROC_LINKS(replace_in_buffer, 0), "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1070 },
{ PROC_LINKS(replace_in_all_buffers, 0), "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1079 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1167 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1187 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1203 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1238 },
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1263 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1301 },
{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1333 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1370 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1403 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1409 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1415 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1429 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1494 },
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1526 },
{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1539 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1551 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1587 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1595 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1605 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1832 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1845 },
{ PROC_LINKS(undo_all_buffers, 0), "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1859 },
{ PROC_LINKS(redo_all_buffers, 0), "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1930 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2031 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 967 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 973 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 979 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 990 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1041 },
{ PROC_LINKS(replace_in_buffer, 0), "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1050 },
{ PROC_LINKS(replace_in_all_buffers, 0), "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1059 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1147 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1167 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1183 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1218 },
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1243 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1281 },
{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1313 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1350 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1383 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1389 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1395 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1409 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1474 },
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1506 },
{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1519 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1531 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1567 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1575 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1585 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1812 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1825 },
{ PROC_LINKS(undo_all_buffers, 0), "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1839 },
{ PROC_LINKS(redo_all_buffers, 0), "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1910 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2011 },
{ PROC_LINKS(lister__quit, 0), "lister__quit", 12, "A lister mode command that quits the list without executing any actions.", 72, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 8 },
{ PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 15 },
{ PROC_LINKS(lister__write_character, 0), "lister__write_character", 23, "A lister mode command that dispatches to the lister's write character handler.", 78, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 30 },