search in custom.cpp

This commit is contained in:
Allen Webster 2016-02-27 14:33:42 -05:00
parent 7774bd6da0
commit 60846a4783
9 changed files with 350 additions and 162 deletions

View File

@ -307,14 +307,20 @@ CUSTOM_COMMAND_SIG(goto_line){
char string_space[256];
int line_number;
bar.prompt = make_lit_string("Goto Line: ");
bar.string = make_fixed_width_string(string_space);
// NOTE(allen): It will not cause an *error* if we continue on after failing to.
// NOTE(allen|a3.4.4): It will not cause an *error* if we continue on after failing to.
// start a query bar, but it will be unusual behavior from the point of view of the
// user, if this command starts intercepting input even though no prompt is shown.
// This will only happen if you have a lot of bars open already or if the current view
// doesn't support query bars.
if (app->start_query_bar(app, &bar, 0) == 0) return;
// NOTE(allen|a3.4.4): The application side is storing a pointer straight to your Query_Bar
// any change you make to it will be reflected in what the application renders. The application
// also makes sure that it destroys all query bars whenever a command exists or an abort
// mesasge is sent to it.
bar.prompt = make_lit_string("Goto Line: ");
bar.string = make_fixed_width_string(string_space);
while (1){
in = app->get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton);
if (in.abort) break;
@ -336,12 +342,110 @@ CUSTOM_COMMAND_SIG(goto_line){
active_view_to_line(app, line_number);
}
CUSTOM_COMMAND_SIG(search){
CUSTOM_COMMAND_SIG(search);
CUSTOM_COMMAND_SIG(reverse_search);
static void
isearch(Application_Links *app, int start_reversed){
File_View_Summary view;
Buffer_Summary buffer;
User_Input in;
Query_Bar bar;
if (app->start_query_bar(app, &bar, 0) == 0) return;
Range match;
int reverse = start_reversed;
int pos;
view = app->get_active_file_view(app);
buffer = app->get_buffer(app, view.buffer_id);
pos = view.cursor.pos;
match = make_range(pos, pos);
char bar_string_space[256];
bar.string = make_fixed_width_string(bar_string_space);
String isearch = make_lit_string("I-Search: ");
String rsearch = make_lit_string("Reverse-I-Search: ");
while (1){
if (reverse) bar.prompt = rsearch;
else bar.prompt = isearch;
in = app->get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton);
if (in.abort) break;
int made_change = 0;
if (in.key.keycode == '\n' || in.key.keycode == '\t'){
break;
}
else if (in.key.character && key_is_unmodified(&in.key)){
append(&bar.string, in.key.character);
made_change = 1;
}
else if (in.key.keycode == key_back){
--bar.string.size;
made_change = 1;
}
int step_forward = 0;
int step_backward = 0;
if (CommandEqual(in.command, search)) step_forward = 1;
if (CommandEqual(in.command, reverse_search)) step_backward = 1;
int start_pos = pos;
if (step_forward && reverse){
start_pos = match.start + 1;
pos = start_pos;
reverse = 0;
step_forward = 0;
}
if (step_backward && !reverse){
start_pos = match.start - 1;
pos = start_pos;
reverse = 1;
step_backward = 0;
}
if (in.key.keycode != key_back){
int new_pos;
if (reverse){
app->buffer_seek_string(app, &buffer, start_pos - 1, bar.string, 0, &new_pos);
if (step_backward){
pos = new_pos;
start_pos = new_pos;
app->buffer_seek_string(app, &buffer, start_pos - 1, bar.string, 0, &new_pos);
}
}
else{
app->buffer_seek_string(app, &buffer, start_pos + 1, bar.string, 1, &new_pos);
if (step_forward){
pos = new_pos;
start_pos = new_pos;
app->buffer_seek_string(app, &buffer, start_pos + 1, bar.string, 1, &new_pos);
}
}
match.start = new_pos;
match.end = match.start + bar.string.size;
}
app->view_set_highlight(app, &view, match.start, match.end, 1);
}
app->view_set_highlight(app, &view, 0, 0, 0);
if (in.abort) return;
app->view_set_cursor(app, &view, seek_pos(match.min), 1);
}
CUSTOM_COMMAND_SIG(search){
isearch(app, 0);
}
CUSTOM_COMMAND_SIG(reverse_search){
isearch(app, 1);
}
CUSTOM_COMMAND_SIG(open_in_other){

View File

@ -187,6 +187,7 @@ struct Application_Links;
#define REFRESH_BUFFER_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer)
#define BUFFER_SEEK_DELIMITER_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out)
#define BUFFER_SEEK_STRING_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, String string, int seek_forward, int *out)
#define BUFFER_READ_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *out)
#define BUFFER_REPLACE_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *str, int len)
#define BUFFER_SAVE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, char *filename, int len)
@ -199,6 +200,7 @@ struct Application_Links;
#define REFRESH_FILE_VIEW_SIG(name) int name(Application_Links *context, File_View_Summary *view)
#define VIEW_SET_CURSOR_SIG(name) int name(Application_Links *context, File_View_Summary *view, Buffer_Seek seek, int set_preferred_x)
#define VIEW_SET_MARK_SIG(name) int name(Application_Links *context, File_View_Summary *view, Buffer_Seek seek)
#define VIEW_SET_HIGHLIGHT_SIG(name) int name(Application_Links *context, File_View_Summary *view, int start, int end, int turn_on)
#define VIEW_SET_BUFFER_SIG(name) int name(Application_Links *context, File_View_Summary *view, int buffer_id)
// Directly get user input
@ -240,6 +242,7 @@ extern "C"{
typedef REFRESH_BUFFER_SIG(Refresh_Buffer_Function);
typedef BUFFER_SEEK_DELIMITER_SIG(Buffer_Seek_Delimiter_Function);
typedef BUFFER_SEEK_STRING_SIG(Buffer_Seek_String_Function);
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
typedef BUFFER_SAVE_SIG(Buffer_Save_Function);
@ -252,6 +255,7 @@ extern "C"{
typedef REFRESH_FILE_VIEW_SIG(Refresh_File_View_Function);
typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function);
typedef VIEW_SET_MARK_SIG(View_Set_Mark_Function);
typedef VIEW_SET_HIGHLIGHT_SIG(View_Set_Highlight_Function);
typedef VIEW_SET_BUFFER_SIG(View_Set_Buffer_Function);
// Directly get user input
@ -285,6 +289,7 @@ struct Application_Links{
Refresh_Buffer_Function *refresh_buffer;
Buffer_Seek_Delimiter_Function *buffer_seek_delimiter;
Buffer_Seek_String_Function *buffer_seek_string;
Buffer_Read_Range_Function *buffer_read_range;
Buffer_Replace_Range_Function *buffer_replace_range;
Buffer_Save_Function *buffer_save;
@ -297,6 +302,7 @@ struct Application_Links{
Refresh_File_View_Function *refresh_file_view;
View_Set_Cursor_Function *view_set_cursor;
View_Set_Mark_Function *view_set_mark;
View_Set_Highlight_Function *view_set_highlight;
View_Set_Buffer_Function *view_set_buffer;
// Directly get user input

View File

@ -243,3 +243,10 @@ active_view_to_line(Application_Links *app, int line_number){
app->view_set_cursor(app, &view, seek_line_char(line_number, 0), 1);
}
inline int
key_is_unmodified(Key_Event_Data *key){
char *mods = key->modifiers;
int unmodified = !mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX];
return(unmodified);
}

85
4ed.cpp
View File

@ -999,7 +999,7 @@ COMMAND_DECL(save){
USE_DELAY(delay);
USE_PANEL(panel);
delayed_action(delay, DACT_SAVE, file->name.source_path, panel);
delayed_save(delay, file->name.source_path, panel);
}
COMMAND_DECL(interactive_save_as){
@ -1091,7 +1091,7 @@ COMMAND_DECL(kill_buffer){
REQ_FILE(file, view);
USE_DELAY(delay);
delayed_action(delay, DACT_TRY_KILL, file->name.live_name, view->view_base.panel);
delayed_try_kill(delay, file->name.live_name, view->view_base.panel);
}
COMMAND_DECL(toggle_line_wrap){
@ -2094,7 +2094,7 @@ extern "C"{
file = working_set->files + buffer->buffer_id;
if (!file->state.is_dummy && file_is_ready(file)){
size = buffer_size(&file->state.buffer);
if (start < size){
if (start >= 0 && start < size){
result = 1;
if (seek_forward){
*out = buffer_seek_delimiter(&file->state.buffer, start, delim);
@ -2112,6 +2112,43 @@ extern "C"{
return(result);
}
BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){
Command_Data *cmd = (Command_Data*)context->data;
Editing_File *file;
Working_Set *working_set;
Temp_Memory temp;
Partition *part;
char *spare;
int result = 0;
int size;
if (buffer->exists){
working_set = cmd->working_set;
file = working_set->files + buffer->buffer_id;
if (!file->state.is_dummy && file_is_ready(file)){
size = buffer_size(&file->state.buffer);
if (start >= 0 && start < size){
part = &cmd->mem->part;
temp = begin_temp_memory(part);
spare = push_array(part, char, string.size);
result = 1;
if (seek_forward){
*out = buffer_find_string(&file->state.buffer, start, size, string.str, string.size, spare);
}
else{
*out = buffer_rfind_string(&file->state.buffer, start, string.str, string.size, spare);
}
if (*out < 0) *out = 0;
if (*out > size) *out = size;
end_temp_memory(temp);
}
fill_buffer_summary(buffer, file, working_set);
}
}
return(result);
}
BUFFER_READ_RANGE_SIG(external_buffer_read_range){
Command_Data *cmd = (Command_Data*)context->data;
Editing_File *file;
@ -2180,15 +2217,19 @@ extern "C"{
Editing_File *file;
Working_Set *working_set;
Delay *delay;
int result = 0;
if (buffer->exists){
delay = cmd->delay;
working_set = cmd->working_set;
file = working_set->files + buffer->buffer_id;
if (!file->state.is_dummy && file_is_ready(file) && buffer_needs_save(file)){
delayed_save(delay, file->name.source_path, file);
result = 1;
}
}
}
}
return(result);
}
GET_VIEW_MAX_INDEX_SIG(external_get_view_max_index){
@ -2289,6 +2330,32 @@ extern "C"{
return(result);
}
VIEW_SET_HIGHLIGHT_SIG(external_view_set_highlight){
Command_Data *cmd = (Command_Data*)context->data;
Live_Views *live_set;
View *vptr;
File_View *file_view;
int result = 0;
if (view->exists){
live_set = cmd->live_set;
vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id);
file_view = view_to_file_view(vptr);
if (file_view){
result = 1;
if (turn_on){
view_set_temp_highlight(file_view, start, end);
}
else{
file_view->show_temp_highlight = 0;
}
fill_view_summary(view, file_view, cmd->live_set, cmd->working_set);
}
}
return(result);
}
VIEW_SET_BUFFER_SIG(external_view_set_buffer){
Command_Data *cmd = (Command_Data*)context->data;
Live_Views *live_set;
@ -2396,6 +2463,7 @@ app_links_init(System_Functions *system){
app_links.refresh_buffer = external_refresh_buffer;
app_links.buffer_seek_delimiter = external_buffer_seek_delimiter;
app_links.buffer_seek_string = external_buffer_seek_string;
app_links.buffer_read_range = external_buffer_read_range;
app_links.buffer_replace_range = external_buffer_replace_range;
app_links.buffer_save = external_buffer_save;
@ -2407,6 +2475,7 @@ app_links_init(System_Functions *system){
app_links.refresh_file_view = external_refresh_file_view;
app_links.view_set_cursor = external_view_set_cursor;
app_links.view_set_mark = external_view_set_mark;
app_links.view_set_highlight = external_view_set_highlight;
app_links.view_set_buffer = external_view_set_buffer;
app_links.get_user_input = external_get_user_input;
@ -3197,7 +3266,9 @@ App_Init_Sig(app_init){
}
// NOTE(allen): delay setup
vars->delay.max = ArrayCount(vars->delay.acts);
vars->delay.max = 128;
vars->delay.acts = (Delayed_Action*)general_memory_allocate(
&vars->mem.general, vars->delay.max*sizeof(Delayed_Action), 0);
// NOTE(allen): style setup
app_hardcode_styles(vars);
@ -3580,6 +3651,7 @@ App_Step_Sig(app_step){
}
}
if (pass_in){
cmd->current_coroutine = vars->command_coroutine;
vars->command_coroutine = system->resume_coroutine(command_coroutine, &user_in,
vars->command_coroutine_flags);
@ -3594,6 +3666,7 @@ App_Step_Sig(app_step){
}
}
}
}
ProfileEnd(command_coroutine);
ProfileStart(resizing);

View File

@ -26,7 +26,7 @@ struct Delay{
};
inline Delayed_Action*
delayed_action(Delay *delay, Action_Type type){
delayed_action_(Delay *delay, Action_Type type){
Delayed_Action *result;
Assert(delay->count < delay->max);
result = delay->acts + delay->count++;
@ -36,39 +36,39 @@ delayed_action(Delay *delay, Action_Type type){
}
inline Delayed_Action*
delayed_action(Delay *delay, Action_Type type, Panel* panel){
delayed_action_(Delay *delay, Action_Type type, Panel* panel){
Delayed_Action *result;
result = delayed_action(delay, type);
result = delayed_action_(delay, type);
result->panel = panel;
return(result);
}
inline Delayed_Action*
delayed_action(Delay *delay, Action_Type type, String string, Panel* panel){
delayed_action_(Delay *delay, Action_Type type, String string, Panel* panel){
Delayed_Action *result;
result = delayed_action(delay, type);
result = delayed_action_(delay, type);
result->string = string;
result->panel = panel;
return(result);
}
inline Delayed_Action*
delayed_action(Delay *delay, Action_Type type, String string, Editing_File* file){
delayed_action_(Delay *delay, Action_Type type, String string, Editing_File* file){
Delayed_Action *result;
result = delayed_action(delay, type);
result = delayed_action_(delay, type);
result->string = string;
result->file = file;
return(result);
}
#define delayed_open(delay, ...) delayed_action(delay, DACT_OPEN, __VA_ARGS__)
#define delayed_save_as(delay, ...) delayed_action(delay, DACT_SAVE_AS, __VA_ARGS__)
#define delayed_save(delay, ...) delayed_action(delay, DACT_SAVE, __VA_ARGS__)
#define delayed_new(delay, ...) delayed_action(delay, DACT_NEW, __VA_ARGS__)
#define delayed_switch(delay, ...) delayed_action(delay, DACT_SWITCH, __VA_ARGS__)
#define delayed_try_kill(delay, ...) delayed_action(delay, DACT_TRY_KILL, __VA_ARGS__)
#define delayed_kill(delay, ...) delayed_action(delay, DACT_KILL, __VA_ARGS__)
#define delayed_close_minor(delay, ...) delayed_action(delay, DACT_CLOSE_MINOR, __VA_ARGS__)
#define delayed_close_major(delay, ...) delayed_action(delay, DACT_CLOSE_MAJOR, __VA_ARGS__)
#define delayed_theme_options(delay, ...) delayed_action(delay, DACT_THEME_OPTIONS, __VA_ARGS__)
#define delayed_keyboard_options(delay, ...) delayed_action(delay, DACT_KEYBOARD_OPTIONS, __VA_ARGS__)
#define delayed_open(delay, ...) delayed_action_(delay, DACT_OPEN, __VA_ARGS__)
#define delayed_save_as(delay, ...) delayed_action_(delay, DACT_SAVE_AS, __VA_ARGS__)
#define delayed_save(delay, ...) delayed_action_(delay, DACT_SAVE, __VA_ARGS__)
#define delayed_new(delay, ...) delayed_action_(delay, DACT_NEW, __VA_ARGS__)
#define delayed_switch(delay, ...) delayed_action_(delay, DACT_SWITCH, __VA_ARGS__)
#define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__)
#define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__)
#define delayed_close_minor(delay, ...) delayed_action_(delay, DACT_CLOSE_MINOR, __VA_ARGS__)
#define delayed_close_major(delay, ...) delayed_action_(delay, DACT_CLOSE_MAJOR, __VA_ARGS__)
#define delayed_theme_options(delay, ...) delayed_action_(delay, DACT_THEME_OPTIONS, __VA_ARGS__)
#define delayed_keyboard_options(delay, ...) delayed_action_(delay, DACT_KEYBOARD_OPTIONS, __VA_ARGS__)

View File

@ -3339,7 +3339,6 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
case FWIDG_SEARCH:
{
#if BUFFER_EXPERIMENT_SCALPEL <= 3
String *string = &file_view->isearch.str;
Single_Line_Input_Step result =
app_single_line_input_step(system, key, string);
@ -3420,7 +3419,6 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
file_view->show_temp_highlight = 0;
view_set_widget(file_view, FWIDG_NONE);
}
#endif
}break;
case FWIDG_GOTO_LINE:

View File

@ -64,32 +64,32 @@ interactive_view_complete(Interactive_View *view){
break;
case INTV_NEW:
delayed_action(view->delay, DACT_NEW, view->hot_directory->string, panel);
delayed_new(view->delay, view->hot_directory->string, panel);
break;
case INTV_SWITCH:
delayed_action(view->delay, DACT_SWITCH, view->dest, panel);
delayed_switch(view->delay, view->dest, panel);
break;
case INTV_KILL:
delayed_action(view->delay, DACT_TRY_KILL, view->dest, panel);
delayed_try_kill(view->delay, view->dest, panel);
break;
case INTV_SURE_TO_KILL:
switch (view->user_action){
case 0:
delayed_action(view->delay, DACT_KILL, view->dest, panel);
delayed_action(view->delay, DACT_CLOSE_MINOR, {}, panel);
delayed_kill(view->delay, view->dest, panel);
delayed_close_minor(view->delay, {}, panel);
break;
case 1:
delayed_action(view->delay, DACT_CLOSE_MINOR, {}, panel);
delayed_close_minor(view->delay, {}, panel);
break;
case 2:
delayed_action(view->delay, DACT_SAVE, view->dest, panel);
delayed_action(view->delay, DACT_KILL, view->dest, panel);
delayed_action(view->delay, DACT_CLOSE_MINOR, {}, panel);
delayed_save(view->delay, view->dest, panel);
delayed_kill(view->delay, view->dest, panel);
delayed_close_minor(view->delay, {}, panel);
break;
}
break;

View File

@ -44,11 +44,11 @@ step_draw_menu_view(Menu_View *view, Render_Target *target, i32_Rect rect,
do_label(&state, &layout, literal("Menu"), 2.f);
if (do_list_option(++id, &state, &layout, make_lit_string("Theme Options"))){
delayed_action(view->delay, DACT_THEME_OPTIONS, {}, view->view_base.panel);
delayed_theme_options(view->delay, {}, view->view_base.panel);
}
if (do_list_option(++id, &state, &layout, make_lit_string("Keyboard Layout Options"))){
delayed_action(view->delay, DACT_KEYBOARD_OPTIONS, {}, view->view_base.panel);
delayed_keyboard_options(view->delay, {}, view->view_base.panel);
}
if (ui_finish_frame(&view->state, &state, &layout, rect, 0, 0)){

View File

@ -155,7 +155,7 @@ Struct_Field delay_fields[] = {
// TODO(allen): Make delay buffer expandable (general memory probably)
char delayed_action_function_top[] =
"inline Delayed_Action*\n"
"delayed_action(Delay *delay, Action_Type type";
"delayed_action_(Delay *delay, Action_Type type";
char delayed_action_function_bottom[] =
"){\n"
@ -172,7 +172,7 @@ char delayed_action_special_param[] = ", %s %s";
char delayed_action_specialized_middle[] =
"){\n"
" Delayed_Action *result;\n"
" result = delayed_action(delay, type);\n";
" result = delayed_action_(delay, type);\n";
char delayed_action_special_line[] =
" result->%s = %s;\n";
@ -182,7 +182,7 @@ char delayed_action_specialized_bottom[] =
"}\n\n";
char delayed_action_macro[] =
"#define delayed_%s(delay, ...) delayed_action(delay, DACT_%s, __VA_ARGS__)\n";
"#define delayed_%s(delay, ...) delayed_action_(delay, DACT_%s, __VA_ARGS__)\n";
char* generate_delayed_action(){
FILE *file;