struct Theme_Color {
Style_Tag tag;
diff --git a/4coder_custom_api.h b/4coder_custom_api.h
index 81a12a9c..07ac0fe0 100644
--- a/4coder_custom_api.h
+++ b/4coder_custom_api.h
@@ -11,6 +11,7 @@
#define BUFFER_BOUNDARY_SEEK_SIG(n) int32_t n(Application_Links *app, Buffer_Summary *buffer, int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)
#define BUFFER_READ_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *out)
#define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len)
+#define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)
#define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type)
#define BUFFER_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value)
#define BUFFER_AUTO_INDENT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, int32_t tab_width, Auto_Indent_Flag flags)
@@ -28,6 +29,7 @@
#define VIEW_SET_SPLIT_PROPORTION_SIG(n) bool32 n(Application_Links *app, View_Summary *view, float t)
#define VIEW_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out)
#define VIEW_SET_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x)
+#define VIEW_SET_SCROLL_SIG(n) bool32 n(Application_Links *app, View_Summary *view, GUI_Scroll_Vars scroll)
#define VIEW_SET_MARK_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek)
#define VIEW_SET_HIGHLIGHT_SIG(n) bool32 n(Application_Links *app, View_Summary *view, int32_t start, int32_t end, bool32 turn_on)
#define VIEW_SET_BUFFER_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_ID buffer_id, Set_Buffer_Flag flags)
@@ -66,6 +68,7 @@ extern "C"{
typedef BUFFER_BOUNDARY_SEEK_SIG(Buffer_Boundary_Seek_Function);
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
+ typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
typedef BUFFER_SET_SETTING_SIG(Buffer_Set_Setting_Function);
typedef BUFFER_AUTO_INDENT_SIG(Buffer_Auto_Indent_Function);
@@ -83,6 +86,7 @@ extern "C"{
typedef VIEW_SET_SPLIT_PROPORTION_SIG(View_Set_Split_Proportion_Function);
typedef VIEW_COMPUTE_CURSOR_SIG(View_Compute_Cursor_Function);
typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function);
+ typedef VIEW_SET_SCROLL_SIG(View_Set_Scroll_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);
@@ -124,6 +128,7 @@ struct Application_Links{
Buffer_Boundary_Seek_Function *buffer_boundary_seek;
Buffer_Read_Range_Function *buffer_read_range;
Buffer_Replace_Range_Function *buffer_replace_range;
+ Buffer_Compute_Cursor_Function *buffer_compute_cursor;
Buffer_Batch_Edit_Function *buffer_batch_edit;
Buffer_Set_Setting_Function *buffer_set_setting;
Buffer_Auto_Indent_Function *buffer_auto_indent;
@@ -141,6 +146,7 @@ struct Application_Links{
View_Set_Split_Proportion_Function *view_set_split_proportion;
View_Compute_Cursor_Function *view_compute_cursor;
View_Set_Cursor_Function *view_set_cursor;
+ View_Set_Scroll_Function *view_set_scroll;
View_Set_Mark_Function *view_set_mark;
View_Set_Highlight_Function *view_set_highlight;
View_Set_Buffer_Function *view_set_buffer;
@@ -184,6 +190,7 @@ app_links->get_buffer_by_name = Get_Buffer_By_Name;\
app_links->buffer_boundary_seek = Buffer_Boundary_Seek;\
app_links->buffer_read_range = Buffer_Read_Range;\
app_links->buffer_replace_range = Buffer_Replace_Range;\
+app_links->buffer_compute_cursor = Buffer_Compute_Cursor;\
app_links->buffer_batch_edit = Buffer_Batch_Edit;\
app_links->buffer_set_setting = Buffer_Set_Setting;\
app_links->buffer_auto_indent = Buffer_Auto_Indent;\
@@ -201,6 +208,7 @@ app_links->view_set_setting = View_Set_Setting;\
app_links->view_set_split_proportion = View_Set_Split_Proportion;\
app_links->view_compute_cursor = View_Compute_Cursor;\
app_links->view_set_cursor = View_Set_Cursor;\
+app_links->view_set_scroll = View_Set_Scroll;\
app_links->view_set_mark = View_Set_Mark;\
app_links->view_set_highlight = View_Set_Highlight;\
app_links->view_set_buffer = View_Set_Buffer;\
diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp
index 566f8bc0..f7f80774 100644
--- a/4coder_default_bindings.cpp
+++ b/4coder_default_bindings.cpp
@@ -5,6 +5,7 @@
#define FCODER_DEFAULT_BINDINGS
#include "4coder_default_include.cpp"
+#include "4coder_default_building.cpp"
// NOTE(allen|a3.3): All of your custom ids should be enumerated
// as shown here, they may start at 0, and you can only have
@@ -153,6 +154,19 @@ HOOK_SIG(my_start){
return(0);
}
+CUSTOM_COMMAND_SIG(newline_or_goto_position){
+ View_Summary view = app->get_active_view(app, AccessProtected);
+ Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessProtected);
+
+ if (buffer.lock_flags & AccessProtected){
+ exec_command(app, goto_postion_at_cursor);
+ }
+ else{
+ exec_command(app, write_character);
+ }
+}
+
+// TODO(allen): Eliminate this hook if you can.
OPEN_FILE_HOOK_SIG(my_file_settings){
// NOTE(allen|a4.0.8): The app->get_parameter_buffer was eliminated
// and instead the buffer is passed as an explicit parameter through
@@ -183,7 +197,6 @@ OPEN_FILE_HOOK_SIG(my_file_settings){
app->buffer_set_setting(app, &buffer, BufferSetting_WrapLine, wrap_lines);
app->buffer_set_setting(app, &buffer, BufferSetting_MapID, (treat_as_code)?((int)my_code_map):((int)mapid_file));
- // TODO(allen): Eliminate this hook if you can.
// no meaning for return
return(0);
}
@@ -192,6 +205,8 @@ OPEN_FILE_HOOK_SIG(my_file_settings){
// If this hook is not implemented a default behavior of calling the
// command is used. It is important to note that paste_next does not
// work without this hook.
+// NOTE(allen|a4.0.10): As of this version the word_complete command also
+// relies on this particular command caller hook.
COMMAND_CALLER_HOOK(my_command_caller){
View_Summary view = app->get_active_view(app, AccessAll);
@@ -261,6 +276,11 @@ default_keys(Bind_Helper *context){
bind(context, 'o', MDFR_ALT, open_in_other);
bind(context, 'w', MDFR_CTRL, save_as);
+ bind(context, '.', MDFR_ALT, change_to_build_panel);
+ bind(context, ',', MDFR_ALT, close_build_panel);
+ bind(context, 'n', MDFR_ALT, goto_next_error);
+ bind(context, 'N', MDFR_ALT, goto_prev_error);
+ bind(context, 'M', MDFR_ALT, goto_first_error);
bind(context, 'm', MDFR_ALT, build_search);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
bind(context, 'z', MDFR_ALT, execute_any_cli);
@@ -287,6 +307,7 @@ default_keys(Bind_Helper *context){
// and write character writes whichever character corresponds
// to the key that triggered the command.
bind(context, '\n', MDFR_NONE, write_and_auto_tab);
+ bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
bind(context, '}', MDFR_NONE, write_and_auto_tab);
bind(context, ')', MDFR_NONE, write_and_auto_tab);
bind(context, ']', MDFR_NONE, write_and_auto_tab);
@@ -297,7 +318,6 @@ default_keys(Bind_Helper *context){
bind(context, '\t', MDFR_CTRL, auto_tab_range);
bind(context, '\t', MDFR_SHIFT, auto_tab_line_at_cursor);
- bind(context, '=', MDFR_CTRL, write_increment);
bind(context, 't', MDFR_ALT, write_allen_todo);
bind(context, 'y', MDFR_ALT, write_allen_note);
bind(context, 'r', MDFR_ALT, write_allen_doc);
@@ -353,9 +373,10 @@ default_keys(Bind_Helper *context){
bind(context, 'a', MDFR_CTRL, replace_in_range);
bind(context, 'c', MDFR_CTRL, copy);
bind(context, 'd', MDFR_CTRL, delete_range);
- bind(context, 'e', MDFR_CTRL, cmdid_center_view);
- bind(context, 'E', MDFR_CTRL, cmdid_left_adjust_view);
+ bind(context, 'e', MDFR_CTRL, center_view);
+ bind(context, 'E', MDFR_CTRL, left_adjust_view);
bind(context, 'f', MDFR_CTRL, search);
+ bind(context, 'F', MDFR_CTRL, list_all_locations);
bind(context, 'g', MDFR_CTRL, goto_line);
bind(context, 'h', MDFR_CTRL, cmdid_history_backward);
bind(context, 'H', MDFR_CTRL, cmdid_history_forward);
@@ -377,13 +398,14 @@ default_keys(Bind_Helper *context){
bind(context, 'y', MDFR_CTRL, cmdid_redo);
bind(context, 'z', MDFR_CTRL, cmdid_undo);
-
+ bind(context, '=', MDFR_CTRL, goto_postion_at_cursor);
bind(context, '1', MDFR_CTRL, eol_dosify);
bind(context, '!', MDFR_CTRL, eol_nixify);
bind(context, '?', MDFR_CTRL, toggle_show_whitespace);
bind(context, '~', MDFR_CTRL, clean_all_lines);
- bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
+ bind(context, '\n', MDFR_NONE, newline_or_goto_position);
+ bind(context, '\n', MDFR_SHIFT, newline_or_goto_position);
bind(context, ' ', MDFR_SHIFT, write_character);
end_map(context);
diff --git a/power/4coder_default_building.cpp b/4coder_default_building.cpp
similarity index 81%
rename from power/4coder_default_building.cpp
rename to 4coder_default_building.cpp
index 4f295a53..481b3b42 100644
--- a/power/4coder_default_building.cpp
+++ b/4coder_default_building.cpp
@@ -185,40 +185,6 @@ CUSTOM_COMMAND_SIG(open_in_other_build){
// Jump to Error
//
-static int
-read_line(Application_Links *app,
- View_Summary *view,
- int line,
- String *str){
-
- Full_Cursor begin = {0};
- Full_Cursor end = {0};
-
- int success = false;
-
- if (app->view_compute_cursor(app, view,
- seek_line_char(line, 1), &begin)){
- if (app->view_compute_cursor(app, view,
- seek_line_char(line, 65536), &end)){
-
- Buffer_Summary buffer = app->get_buffer(app, view->buffer_id, AccessAll);
- if (begin.line == line){
- if (0 <= begin.pos && begin.pos <= end.pos && end.pos <= buffer.size){
- int size = (end.pos - begin.pos);
- if (size <= str->memory_size){
- success = true;
- app->buffer_read_range(app, &buffer, begin.pos, end.pos, str->str);
- str->size = size;
- }
- }
- }
-
- }
- }
-
- return(success);
-}
-
struct Jump_Location{
String file;
int line;
@@ -234,18 +200,9 @@ jump_to_location(Application_Links *app, View_Summary *view, Jump_Location *l){
static int
gcc_style_verify(String line, int colon_pos){
int result = false;
-
- String line_part = substr(line, colon_pos);
- if (match_part(line_part, ": error")){
+ if (colon_pos < line.size){
result = true;
}
- else if (match_part(line_part, ": warning")){
- result = true;
- }
- else if (match_part(line_part, ": fatal")){
- result = true;
- }
-
return(result);
}
@@ -298,7 +255,8 @@ parse_error(String line, Jump_Location *location,
if (line_number.size > 0){
- copy(&location->file, file);
+ //copy(&location->file, file);
+ location->file = file;
int comma_pos = find(line_number, 0, ',');
if (comma_pos < line_number.size){
@@ -327,6 +285,7 @@ parse_error(String line, Jump_Location *location,
int colon_pos1 = find(line, 0, ':');
int colon_pos2 = find(line, colon_pos1+1, ':');
int colon_pos3 = find(line, colon_pos2+1, ':');
+
if (gcc_style_verify(line, colon_pos3)){
String filename = substr(line, 0, colon_pos1);
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
@@ -335,13 +294,30 @@ parse_error(String line, Jump_Location *location,
if (filename.size > 0 &&
line_number.size > 0 &&
column_number.size > 0){
- copy(&location->file, filename);
+ //copy(&location->file, filename);
+ location->file = filename;
location->line = str_to_int(line_number);
location->column = str_to_int(column_number);
*colon_char = colon_pos3;
result = true;
}
}
+ else{
+ int colon_pos1 = find(line, 0, ':');
+ int colon_pos2 = find(line, colon_pos1+1, ':');
+
+ String filename = substr(line, 0, colon_pos1);
+ String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
+
+ if (filename.size > 0 && line_number.size > 0){
+ //copy(&location->file, filename);
+ location->file = filename;
+ location->line = str_to_int(line_number);
+ location->column = 0;
+ *colon_char = colon_pos2;
+ result = true;
+ }
+ }
}
return(result);
@@ -349,18 +325,19 @@ parse_error(String line, Jump_Location *location,
static int
next_error(Application_Links *app,
- View_Summary *comp_out, int *start_line,
- void *memory, int memory_size,
- Jump_Location *location,
- int direction,
- int skip_sub_errors,
- int *colon_char){
+ Partition *part,
+ View_Summary *comp_out, int *start_line,
+ Jump_Location *location,
+ int direction,
+ int skip_sub_errors,
+ int *colon_char){
int result = false;
int line = *start_line + direction;
- String line_str = make_string(memory, 0, memory_size);
+ String line_str = {0};
+ Buffer_Summary buffer = app->get_buffer(app, comp_out->buffer_id, AccessAll);
for (;;){
- if (read_line(app, comp_out, line, &line_str)){
+ if (read_line(app, part, &buffer, line, &line_str)){
if (parse_error(line_str, location, skip_sub_errors, colon_char)){
result = true;
break;
@@ -382,7 +359,27 @@ next_error(Application_Links *app,
}
static int
-goto_error(Application_Links *app, int direction, int skip_sub_errors, Jump_Location *loc){
+goto_error(Application_Links *app,
+ Partition *part,
+ View_Summary *view, int line,
+ Jump_Location *location,
+ int skip_sub_errors){
+
+ int result = false;
+ String line_str = {0};
+ Buffer_Summary buffer = app->get_buffer(app, view->buffer_id, AccessAll);
+ if (read_line(app, part, &buffer, line, &line_str)){
+ int colon_char = 0;
+ if (parse_error(line_str, location, skip_sub_errors, &colon_char)){
+ result = true;
+ }
+ }
+
+ return(result);
+}
+
+static int
+seek_error(Application_Links *app, Partition *part, int direction, int skip_sub_errors, Jump_Location *loc){
int result = false;
View_Summary active_view = app->get_active_view(app, AccessAll);
@@ -392,12 +389,8 @@ goto_error(Application_Links *app, int direction, int skip_sub_errors, Jump_Loca
View_Summary view = get_first_view_with_buffer(app, buffer.buffer_id);
int line = view.cursor.line;
- int ms = app->memory_size/2;
- location.file = make_string(app->memory, 0, ms);
- void *m = (char*)app->memory + ms;
-
int colon_char = 0;
- if (next_error(app, &view, &line, m, ms, &location,
+ if (next_error(app, part, &view, &line, &location,
skip_sub_errors, direction, &colon_char)){
jump_to_location(app, &active_view, &location);
app->view_set_cursor(app, &view, seek_line_char(line, colon_char+1), true);
@@ -435,11 +428,11 @@ skip_this_jump(Prev_Jump prev, Prev_Jump jump){
}
CUSTOM_COMMAND_SIG(goto_next_error){
+ Temp_Memory temp = begin_temp_memory(&global_part);
Jump_Location location = {0};
Prev_Jump jump = {0};
-
do{
- if (goto_error(app, true, 1, &location)){
+ if (seek_error(app, &global_part, true, 1, &location)){
jump = jump_location_store(app, location);
}
else{
@@ -447,14 +440,15 @@ CUSTOM_COMMAND_SIG(goto_next_error){
}
}while(skip_this_jump(prev_location, jump));
prev_location = jump;
+ end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(goto_prev_error){
+ Temp_Memory temp = begin_temp_memory(&global_part);
Jump_Location location = {0};
Prev_Jump jump = {0};
-
do{
- if (goto_error(app, true, -1, &location)){
+ if (seek_error(app, &global_part, true, -1, &location)){
jump = jump_location_store(app, location);
}
else{
@@ -462,17 +456,35 @@ CUSTOM_COMMAND_SIG(goto_prev_error){
}
}while(skip_this_jump(prev_location, jump));
prev_location = jump;
+ end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(goto_first_error){
+ Temp_Memory temp = begin_temp_memory(&global_part);
View_Summary active_view = app->get_active_view(app, AccessAll);
app->view_set_cursor(app, &active_view, seek_pos(0), true);
- Jump_Location location;
- goto_error(app, true, 1, &location);
+ Jump_Location location = {0};
+ seek_error(app, &global_part, true, 1, &location);
prev_location = jump_location_store(app, location);
+ end_temp_memory(temp);
}
+CUSTOM_COMMAND_SIG(goto_postion_at_cursor){
+ Temp_Memory temp = begin_temp_memory(&global_part);
+ View_Summary view = app->get_active_view(app, AccessProtected);
+
+ Jump_Location location = {0};
+ goto_error(app, &global_part,
+ &view, view.cursor.line,
+ &location, false);
+
+ exec_command(app, change_active_panel);
+
+ view = app->get_active_view(app, AccessAll);
+ jump_to_location(app, &view, &location);
+ end_temp_memory(temp);
+}
#endif
diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp
index bb47be5c..1ec09adc 100644
--- a/4coder_default_include.cpp
+++ b/4coder_default_include.cpp
@@ -15,8 +15,8 @@
// Memory
//
-static Partition part;
-static General_Memory general;
+static Partition global_part;
+static General_Memory global_general;
void
init_memory(Application_Links *app){
@@ -25,10 +25,10 @@ init_memory(Application_Links *app){
void *part_mem = app->memory_allocate(app, part_size);
- part = make_part(part_mem, part_size);
+ global_part = make_part(part_mem, part_size);
void *general_mem = app->memory_allocate(app, general_size);
- general_memory_open(&general, general_mem, general_size);
+ general_memory_open(&global_general, general_mem, general_size);
}
//
@@ -534,6 +534,30 @@ CUSTOM_COMMAND_SIG(delete_range){
// Basic Navigation
//
+CUSTOM_COMMAND_SIG(center_view){
+ View_Summary view = app->get_active_view(app, AccessProtected);
+
+ i32_Rect region = view.file_region;
+ GUI_Scroll_Vars scroll = view.scroll_vars;
+
+ float h = (float)(region.y1 - region.y0);
+ float y = get_view_y(view);
+ y = y - h*.5f;
+ scroll.target_y = (int32_t)(y + .5f);
+ app->view_set_scroll(app, &view, scroll);
+}
+
+CUSTOM_COMMAND_SIG(left_adjust_view){
+ View_Summary view = app->get_active_view(app, AccessProtected);
+
+ GUI_Scroll_Vars scroll = view.scroll_vars;
+
+ float x = get_view_x(view);
+ x = x - 30.f;
+ scroll.target_x = (int32_t)(x + .5f);
+ app->view_set_scroll(app, &view, scroll);
+}
+
int
get_relative_xy(View_Summary *view, int x, int y, float *x_out, float *y_out){
int result = false;
@@ -2183,6 +2207,115 @@ CUSTOM_COMMAND_SIG(eol_nixify){
#include "4coder_table.cpp"
#include "4coder_search.cpp"
+CUSTOM_COMMAND_SIG(list_all_locations){
+ Query_Bar string;
+ char string_space[1024];
+ string.prompt = make_lit_string("List Locations For: ");
+ string.string = make_fixed_width_string(string_space);
+
+ if (!query_user_string(app, &string)) return;
+ if (string.string.size == 0) return;
+
+ Search_Set set = {0};
+ Search_Iter iter = {0};
+
+ search_iter_init(&global_general, &iter, string.string.size);
+ copy(&iter.word, string.string);
+
+ int buffer_count = app->get_buffer_count(app);
+ search_set_init(&global_general, &set, buffer_count);
+
+ Search_Range *ranges = set.ranges;
+
+ {
+ View_Summary view = app->get_active_view(app, AccessProtected);
+ Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessProtected);
+
+ int j = 0;
+ if (buffer.exists){
+ ranges[0].type = SearchRange_FrontToBack;
+ ranges[0].flags = 0;
+ ranges[0].buffer = buffer.buffer_id;
+ ranges[0].start = 0;
+ ranges[0].size = buffer.size;
+ j = 1;
+ }
+
+ for (Buffer_Summary buffer_it = app->get_buffer_first(app, AccessAll);
+ buffer_it.exists;
+ app->get_buffer_next(app, &buffer_it, AccessAll)){
+ if (buffer.buffer_id != buffer_it.buffer_id){
+ ranges[j].type = SearchRange_FrontToBack;
+ ranges[j].flags = 0;
+ ranges[j].buffer = buffer_it.buffer_id;
+ ranges[j].start = 0;
+ ranges[j].size = buffer_it.size;
+ ++j;
+ }
+ }
+ set.count = j;
+ }
+
+ Buffer_Summary search_buffer = app->get_buffer_by_name(app, literal("*search*"), AccessAll);
+ if (!search_buffer.exists){
+ search_buffer = app->create_buffer(app, literal("*search*"), BufferCreate_AlwaysNew);
+ app->buffer_set_setting(app, &search_buffer, BufferSetting_Unimportant, true);
+ app->buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, true);
+ }
+ else{
+ app->buffer_replace_range(app, &search_buffer, 0, search_buffer.size, 0, 0);
+ }
+
+ Temp_Memory temp = begin_temp_memory(&global_part);
+ Partition line_part = partition_sub_part(&global_part, (4 << 10));
+ char *str = (char*)partition_current(&global_part);
+ int size = 0;
+ for (;;){
+ Search_Match match = search_next_match(app, &set, &iter);
+ if (match.found_match){
+ Partial_Cursor word_pos = {0};
+ if (app->buffer_compute_cursor(app, &match.buffer, seek_pos(match.start), &word_pos)){
+ int file_len = match.buffer.file_name_len;
+ int line_num_len = int_to_str_size(word_pos.line);
+ int column_num_len = int_to_str_size(word_pos.character);
+
+ Temp_Memory line_temp = begin_temp_memory(&line_part);
+ String line_str = {0};
+ read_line(app, &line_part, &match.buffer, word_pos.line, &line_str);
+ line_str = skip_chop_whitespace(line_str);
+
+ int str_len = file_len + 1 + line_num_len + 1 + column_num_len + 1 + 1 + line_str.size + 1;
+
+ char *spare = push_array(&global_part, char, str_len);
+ size += str_len;
+
+ String out_line = make_string(spare, 0, str_len);
+ append(&out_line, make_string(match.buffer.file_name, file_len));
+ append(&out_line, ':');
+ append_int_to_str(&out_line, word_pos.line);
+ append(&out_line, ':');
+ append_int_to_str(&out_line, word_pos.character);
+ append(&out_line, ':');
+ append(&out_line, ' ');
+ append(&out_line, line_str);
+ append(&out_line, '\n');
+
+ end_temp_memory(line_temp);
+ }
+ }
+ else{
+ break;
+ }
+ }
+
+ app->buffer_replace_range(app, &search_buffer, 0, 0, str, size);
+
+ View_Summary view = app->get_active_view(app, AccessAll);
+ app->view_set_buffer(app, &view, search_buffer.buffer_id, 0);
+
+ end_temp_memory(temp);
+}
+
struct Word_Complete_State{
Search_Set set;
Search_Iter iter;
@@ -2254,7 +2387,7 @@ CUSTOM_COMMAND_SIG(word_complete){
// NOTE(allen): Initialize the search iterator
// with the partial word.
complete_state.initialized = true;
- search_iter_init(app, &complete_state.iter, size);
+ search_iter_init(&global_general, &complete_state.iter, size);
app->buffer_read_range(app, &buffer, word_start, word_end,
complete_state.iter.word.str);
complete_state.iter.word.size = size;
@@ -2262,10 +2395,11 @@ CUSTOM_COMMAND_SIG(word_complete){
// NOTE(allen): Initialize the set of ranges
// to be searched.
int buffer_count = app->get_buffer_count(app);
- search_set_init(app, &complete_state.set, buffer_count);
+ search_set_init(&global_general, &complete_state.set, buffer_count);
Search_Range *ranges = complete_state.set.ranges;
ranges[0].type = SearchRange_Wave;
+ ranges[0].flags = SearchFlag_MatchStartOfIdentifier;
ranges[0].buffer = buffer.buffer_id;
ranges[0].start = 0;
ranges[0].size = buffer.size;
@@ -2278,6 +2412,7 @@ CUSTOM_COMMAND_SIG(word_complete){
app->get_buffer_next(app, &buffer_it, AccessAll)){
if (buffer.buffer_id != buffer_it.buffer_id){
ranges[j].type = SearchRange_FrontToBack;
+ ranges[j].flags = SearchFlag_MatchStartOfIdentifier;
ranges[j].buffer = buffer_it.buffer_id;
ranges[j].start = 0;
ranges[j].size = buffer_it.size;
@@ -2287,9 +2422,9 @@ CUSTOM_COMMAND_SIG(word_complete){
complete_state.set.count = j;
// NOTE(allen): Initialize the search hit table.
- search_hits_init(app, &complete_state.hits, &complete_state.str,
+ search_hits_init(&global_general, &complete_state.hits, &complete_state.str,
100, (4 << 10));
- search_hit_add(app, &complete_state.hits, &complete_state.str,
+ search_hit_add(&global_general, &complete_state.hits, &complete_state.str,
complete_state.iter.word.str,
complete_state.iter.word.size);
@@ -2312,13 +2447,13 @@ CUSTOM_COMMAND_SIG(word_complete){
if (match.found_match){
int match_size = match.end - match.start;
- Temp_Memory temp = begin_temp_memory(&part);
- char *spare = push_array(&part, char, match_size);
+ Temp_Memory temp = begin_temp_memory(&global_part);
+ char *spare = push_array(&global_part, char, match_size);
app->buffer_read_range(app, &match.buffer,
match.start, match.end, spare);
- if (search_hit_add(app, &complete_state.hits, &complete_state.str,
+ if (search_hit_add(&global_general, &complete_state.hits, &complete_state.str,
spare, match_size)){
app->buffer_replace_range(app, &buffer, word_start, word_end,
spare, match_size);
@@ -2337,9 +2472,9 @@ CUSTOM_COMMAND_SIG(word_complete){
complete_state.iter.pos = 0;
complete_state.iter.i = 0;
- search_hits_init(app, &complete_state.hits, &complete_state.str,
+ search_hits_init(&global_general, &complete_state.hits, &complete_state.str,
100, (4 << 10));
- search_hit_add(app, &complete_state.hits, &complete_state.str,
+ search_hit_add(&global_general, &complete_state.hits, &complete_state.str,
complete_state.iter.word.str,
complete_state.iter.word.size);
diff --git a/4coder_helper.h b/4coder_helper.h
index c11b5409..f7e5de5f 100644
--- a/4coder_helper.h
+++ b/4coder_helper.h
@@ -419,8 +419,11 @@ get_active_buffer(Application_Links *app, unsigned int access){
inline char
buffer_get_char(Application_Links *app, Buffer_Summary *buffer, int pos){
- char result = 0;
- app->buffer_read_range(app, buffer, pos, pos+1, &result);
+ char result = ' ';
+ *buffer = app->get_buffer(app, buffer->buffer_id, AccessAll);
+ if (pos >= 0 && pos < buffer->size){
+ app->buffer_read_range(app, buffer, pos, pos+1, &result);
+ }
return(result);
}
@@ -469,4 +472,38 @@ view_open_file(Application_Links *app, View_Summary *view,
return(result);
}
+static int
+read_line(Application_Links *app,
+ Partition *part,
+ Buffer_Summary *buffer,
+ int line,
+ String *str){
+
+ Partial_Cursor begin = {0};
+ Partial_Cursor end = {0};
+
+ int success = false;
+
+ if (app->buffer_compute_cursor(app, buffer,
+ seek_line_char(line, 1), &begin)){
+ if (app->buffer_compute_cursor(app, buffer,
+ seek_line_char(line, 65536), &end)){
+ if (begin.line == line){
+ if (0 <= begin.pos && begin.pos <= end.pos && end.pos <= buffer->size){
+ int size = (end.pos - begin.pos);
+ *str = make_string(push_array(part, char, size+1), size+1);
+ if (str->str){
+ success = true;
+ app->buffer_read_range(app, buffer, begin.pos, end.pos, str->str);
+ str->size = size;
+ terminate_with_null(str);
+ }
+ }
+ }
+ }
+ }
+
+ return(success);
+}
+
#endif
diff --git a/4coder_search.cpp b/4coder_search.cpp
index a0b92a10..4e411bd8 100644
--- a/4coder_search.cpp
+++ b/4coder_search.cpp
@@ -1,431 +1,460 @@
-
-#ifndef FCODER_SEARCH
-#define FCODER_SEARCH
-
-enum Search_Range_Type{
- SearchRange_FrontToBack,
- SearchRange_BackToFront,
- SearchRange_Wave,
-};
-
-struct Search_Range{
- int type;
- int buffer;
- int start;
- int size;
- int mid_start;
- int mid_size;
-};
-
-struct Search_Set{
- Search_Range *ranges;
- int count;
- int max;
-};
-
-struct Search_Iter{
- String word;
- int pos;
- int back_pos;
- int i;
- int range_initialized;
-};
-
-struct Search_Match{
- Buffer_Summary buffer;
- int start;
- int end;
- int found_match;
-};
-
-static void
-search_iter_init(Application_Links *app, Search_Iter *iter, int size){
- int str_max = size*2;
- if (iter->word.str == 0){
- iter->word.str = (char*)general_memory_allocate(&general, str_max);
- iter->word.memory_size = str_max;
- }
- else if (iter->word.memory_size < size){
- iter->word.str = (char*)general_memory_reallocate_nocopy(&general, iter->word.str, str_max);
- iter->word.memory_size = str_max;
- }
- iter->i = 0;
- iter->range_initialized = 0;
-}
-
-static void
-search_set_init(Application_Links *app, Search_Set *set, int range_count){
- int max = range_count*2;
-
- if (set->ranges == 0){
- set->ranges = (Search_Range*)general_memory_allocate(&general, sizeof(Search_Range)*max);
- set->max = max;
- }
- else if (set->max < range_count){
- set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
- &general, set->ranges, sizeof(Search_Range)*max);
- set->max = max;
- }
-
- set->count = range_count;
-}
-
-static void
-search_hits_table_alloc(Application_Links *app, Table *hits, int table_size){
- void *mem = 0;
- int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
- if (hits->hash_array == 0){
- mem = general_memory_allocate(&general, mem_size);
- }
- else{
- mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size);
- }
- table_init_memory(hits, mem, table_size, sizeof(Offset_String));
-}
-
-static void
-search_hits_init(Application_Links *app, Table *hits, String_Space *str, int table_size, int str_size){
- if (hits->hash_array == 0){
- search_hits_table_alloc(app, hits, table_size);
- }
- else{
- int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
- void *mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size);
- table_init_memory(hits, mem, table_size, sizeof(Offset_String));
- }
-
- if (str->space == 0){
- str->space = (char*)general_memory_allocate(&general, str_size);
- str->max = str_size;
- }
- else if (str->max < str_size){
- str->space = (char*)general_memory_reallocate_nocopy(&general, str->space, str_size);
- str->max = str_size;
- }
-
- str->pos = str->new_pos = 0;
- table_clear(hits);
-}
-
-static int
-search_hit_add(Application_Links *app, Table *hits, String_Space *space, char *str, int len){
- int result = false;
-
- assert(len != 0);
-
- Offset_String ostring = strspace_append(space, str, len);
- if (ostring.size == 0){
- int new_size = space->max*2;
- if (new_size < space->max + len){
- new_size = space->max + len;
- }
- space->space = (char*)general_memory_reallocate(
- &general, space->space, space->new_pos, new_size);
- ostring = strspace_append(space, str, len);
- }
-
- assert(ostring.size != 0);
-
- if (table_at_capacity(hits)){
- Table new_hits = {0};
- search_hits_table_alloc(app, &new_hits, hits->max*2);
- table_clear(&new_hits);
- table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
- general_memory_free(&general, hits->hash_array);
- *hits = new_hits;
- }
-
- if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
- result = true;
- strspace_keep_prev(space);
- }
- else{
- strspace_discard_prev(space);
- }
-
- return(result);
-}
-
-static int
-buffer_seek_alpha_numeric_end(Application_Links *app, Buffer_Summary *buffer, int pos){
- char space[1024];
- Stream_Chunk chunk = {0};
- if (init_stream_chunk(&chunk, app, buffer, pos, space, sizeof(space))){
- int still_looping = true;
- do{
- for (; pos < chunk.end; ++pos){
- char at_pos = chunk.data[pos];
- if (!char_is_alpha_numeric(at_pos)) goto double_break;
- }
- still_looping = forward_stream_chunk(&chunk);
- }while(still_looping);
- }
- double_break:;
- return(pos);
-}
-
-static void
-search_iter_next_range(Search_Iter *it){
- ++it->i;
- it->pos = 0;
- it->back_pos = 0;
- it->range_initialized = 0;
-}
-
-enum{
- FindResult_None,
- FindResult_FoundMatch,
- FindResult_PastEnd
-};
-
-static int
-search_front_to_back_step(Application_Links *app,
- Search_Range *range,
- String word,
- int *pos,
- Search_Match *result_ptr){
- int found_match = FindResult_None;
-
- Search_Match result = *result_ptr;
-
- int end_pos = range->start + range->size;
- if (*pos + word.size < end_pos){
- int start_pos = *pos;
- if (start_pos < range->start){
- start_pos = range->start;
- }
-
- result.buffer = app->get_buffer(app, range->buffer, AccessAll);
- buffer_seek_string_forward(app, &result.buffer,
- start_pos, end_pos,
- word.str, word.size,
- &result.start);
-
- if (result.start < end_pos){
- *pos = result.start + 1;
- char prev = ' ';
- if (result.start > 0){
- prev = buffer_get_char(app, &result.buffer, result.start - 1);
- }
- if (!char_is_alpha_numeric(prev)){
- result.end =
- buffer_seek_alpha_numeric_end(
- app, &result.buffer, result.start);
-
- if (result.end < end_pos){
- result.found_match = true;
- *pos = result.end;
- found_match = FindResult_FoundMatch;
- }
- }
- }
- else{
- found_match = FindResult_PastEnd;
- *pos = end_pos + 1;
- }
- }
- else{
- found_match = FindResult_PastEnd;
- *pos = end_pos + 1;
- }
-
- *result_ptr = result;
-
- return(found_match);
-}
-
-static int
-search_front_to_back(Application_Links *app,
- Search_Range *range,
- String word,
- int *pos,
- Search_Match *result_ptr){
- int found_match = FindResult_None;
- for (;found_match == FindResult_None;){
- found_match = search_front_to_back_step(app, range, word, pos, result_ptr);
- }
- return(found_match);
-}
-
-static int
-search_back_to_front_step(Application_Links *app,
- Search_Range *range,
- String word,
- int *pos,
- Search_Match *result_ptr){
- int found_match = FindResult_None;
-
- Search_Match result = *result_ptr;
-
- int end_pos = range->start + range->size;
- if (*pos > range->start){
- int start_pos = *pos;
-
- result.buffer = app->get_buffer(app, range->buffer, AccessAll);
- buffer_seek_string_backward(app, &result.buffer,
- start_pos, range->start,
- word.str, word.size,
- &result.start);
-
- if (result.start >= range->start){
- *pos = result.start - 1;
- char prev = ' ';
- if (result.start > 0){
- prev = buffer_get_char(app, &result.buffer, result.start - 1);
- }
- if (!char_is_alpha_numeric(prev)){
- result.end =
- buffer_seek_alpha_numeric_end(
- app, &result.buffer, result.start);
-
- if (result.end < end_pos){
- result.found_match = true;
- *pos = result.start - word.size;
- found_match = FindResult_FoundMatch;
- }
- }
- }
- else{
- found_match = FindResult_PastEnd;
- }
- }
- else{
- found_match = FindResult_PastEnd;
- }
-
- *result_ptr = result;
-
- return(found_match);
-}
-
-static int
-search_back_to_front(Application_Links *app,
- Search_Range *range,
- String word,
- int *pos,
- Search_Match *result_ptr){
- int found_match = FindResult_None;
- for (;found_match == FindResult_None;){
- found_match = search_back_to_front_step(app, range, word, pos, result_ptr);
- }
- return(found_match);
-}
-
-static Search_Match
-search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){
- Search_Match result = {0};
- Search_Iter iter = *it_ptr;
-
- int count = set->count;
- for (; iter.i < count;){
- Search_Range *range = set->ranges + iter.i;
-
- int find_result = FindResult_None;
-
- if (!iter.range_initialized){
- iter.range_initialized = true;
- switch (range->type){
- case SearchRange_BackToFront:
- {
- iter.back_pos = range->start+range->size-1;
- }break;
-
- case SearchRange_Wave:
- {
- iter.back_pos = range->mid_start-1;
- iter.pos = range->mid_start + range->mid_size;
- }break;
- }
- }
-
- switch (range->type){
- case SearchRange_FrontToBack:
- {
- find_result =
- search_front_to_back(app, range,
- iter.word,
- &iter.pos,
- &result);
- }break;
-
- case SearchRange_BackToFront:
- {
- find_result =
- search_back_to_front(app, range,
- iter.word,
- &iter.back_pos,
- &result);
- }break;
-
- case SearchRange_Wave:
- {
- Search_Match forward_match = {0};
- Search_Match backward_match = {0};
-
- int forward_result = FindResult_PastEnd;
- int backward_result = FindResult_PastEnd;
-
- if (iter.pos < range->start + range->size){
- forward_result = search_front_to_back(app, range,
- iter.word,
- &iter.pos,
- &forward_match);
- }
-
- if (iter.back_pos > range->start){
- backward_result = search_back_to_front(app, range,
- iter.word,
- &iter.back_pos,
- &backward_match);
- }
-
- if (forward_result == FindResult_FoundMatch){
- if (backward_result == FindResult_FoundMatch){
- find_result = FindResult_FoundMatch;
-
- int forward_start = range->mid_start + range->mid_size;
- int forward_distance = (forward_match.start - forward_start);
- int backward_distance = (range->mid_start - backward_match.end);
-
- if (backward_distance < forward_distance){
- iter.pos = forward_match.start;
- result = backward_match;
- }
- else{
- iter.back_pos = backward_match.start;
- result = forward_match;
- }
- }
- else{
- find_result = FindResult_FoundMatch;
- result = forward_match;
- }
- }
- else{
- if (backward_result == FindResult_FoundMatch){
- find_result = FindResult_FoundMatch;
- result = backward_match;
- --iter.pos;
- }
- else{
- find_result = FindResult_PastEnd;
- }
- }
- }break;
- }
-
- if (find_result == FindResult_FoundMatch){
- goto double_break;
- }
- else if (find_result == FindResult_PastEnd){
- search_iter_next_range(&iter);
- }
- }
- double_break:;
-
- *it_ptr = iter;
-
- return(result);
-}
-
-#endif
+
+#ifndef FCODER_SEARCH
+#define FCODER_SEARCH
+
+enum Search_Range_Type{
+ SearchRange_FrontToBack,
+ SearchRange_BackToFront,
+ SearchRange_Wave,
+};
+
+enum Search_Range_Flag{
+ SearchFlag_MatchStartOfIdentifier = 0x1,
+};
+
+struct Search_Range{
+ int type;
+ unsigned int flags;
+ int buffer;
+ int start;
+ int size;
+ int mid_start;
+ int mid_size;
+};
+
+struct Search_Set{
+ Search_Range *ranges;
+ int count;
+ int max;
+};
+
+struct Search_Iter{
+ String word;
+ int pos;
+ int back_pos;
+ int i;
+ int range_initialized;
+};
+
+struct Search_Match{
+ Buffer_Summary buffer;
+ int start;
+ int end;
+ int found_match;
+};
+
+static void
+search_iter_init(General_Memory *general, Search_Iter *iter, int size){
+ int str_max = size*2;
+ if (iter->word.str == 0){
+ iter->word.str = (char*)general_memory_allocate(general, str_max);
+ iter->word.memory_size = str_max;
+ }
+ else if (iter->word.memory_size < size){
+ iter->word.str = (char*)general_memory_reallocate_nocopy(general, iter->word.str, str_max);
+ iter->word.memory_size = str_max;
+ }
+ iter->i = 0;
+ iter->range_initialized = 0;
+}
+
+static void
+search_set_init(General_Memory *general, Search_Set *set, int range_count){
+ int max = range_count*2;
+
+ if (set->ranges == 0){
+ set->ranges = (Search_Range*)general_memory_allocate(general, sizeof(Search_Range)*max);
+ set->max = max;
+ }
+ else if (set->max < range_count){
+ set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
+ general, set->ranges, sizeof(Search_Range)*max);
+ set->max = max;
+ }
+
+ set->count = range_count;
+}
+
+static void
+search_hits_table_alloc(General_Memory *general, Table *hits, int table_size){
+ void *mem = 0;
+ int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
+ if (hits->hash_array == 0){
+ mem = general_memory_allocate(general, mem_size);
+ }
+ else{
+ mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
+ }
+ table_init_memory(hits, mem, table_size, sizeof(Offset_String));
+}
+
+static void
+search_hits_init(General_Memory *general, Table *hits, String_Space *str, int table_size, int str_size){
+ if (hits->hash_array == 0){
+ search_hits_table_alloc(general, hits, table_size);
+ }
+ else{
+ int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
+ void *mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
+ table_init_memory(hits, mem, table_size, sizeof(Offset_String));
+ }
+
+ if (str->space == 0){
+ str->space = (char*)general_memory_allocate(general, str_size);
+ str->max = str_size;
+ }
+ else if (str->max < str_size){
+ str->space = (char*)general_memory_reallocate_nocopy(general, str->space, str_size);
+ str->max = str_size;
+ }
+
+ str->pos = str->new_pos = 0;
+ table_clear(hits);
+}
+
+static int
+search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *str, int len){
+ int result = false;
+
+ assert(len != 0);
+
+ Offset_String ostring = strspace_append(space, str, len);
+ if (ostring.size == 0){
+ int new_size = space->max*2;
+ if (new_size < space->max + len){
+ new_size = space->max + len;
+ }
+ space->space = (char*)general_memory_reallocate(
+ general, space->space, space->new_pos, new_size);
+ ostring = strspace_append(space, str, len);
+ }
+
+ assert(ostring.size != 0);
+
+ if (table_at_capacity(hits)){
+ Table new_hits = {0};
+ search_hits_table_alloc(general, &new_hits, hits->max*2);
+ table_clear(&new_hits);
+ table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
+ general_memory_free(general, hits->hash_array);
+ *hits = new_hits;
+ }
+
+ if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
+ result = true;
+ strspace_keep_prev(space);
+ }
+ else{
+ strspace_discard_prev(space);
+ }
+
+ return(result);
+}
+
+static int
+buffer_seek_alpha_numeric_end(Application_Links *app, Buffer_Summary *buffer, int pos){
+ char space[1024];
+ Stream_Chunk chunk = {0};
+ if (init_stream_chunk(&chunk, app, buffer, pos, space, sizeof(space))){
+ int still_looping = true;
+ do{
+ for (; pos < chunk.end; ++pos){
+ char at_pos = chunk.data[pos];
+ if (!char_is_alpha_numeric(at_pos)) goto double_break;
+ }
+ still_looping = forward_stream_chunk(&chunk);
+ }while(still_looping);
+ }
+ double_break:;
+ return(pos);
+}
+
+static void
+search_iter_next_range(Search_Iter *it){
+ ++it->i;
+ it->pos = 0;
+ it->back_pos = 0;
+ it->range_initialized = 0;
+}
+
+enum{
+ FindResult_None,
+ FindResult_FoundMatch,
+ FindResult_PastEnd
+};
+
+static int
+match_check(Application_Links *app, Search_Range *range, int *pos, Search_Match *result_ptr, String word){
+ int found_match = FindResult_None;
+
+ Search_Match result = *result_ptr;
+ int end_pos = range->start + range->size;
+
+ if (range->flags & SearchFlag_MatchStartOfIdentifier){
+ char prev = buffer_get_char(app, &result.buffer, result.start - 1);
+ if (!char_is_alpha_numeric(prev)){
+ result.end =
+ buffer_seek_alpha_numeric_end(
+ app, &result.buffer, result.start);
+
+ if (result.end <= end_pos){
+ result.found_match = true;
+ found_match = FindResult_FoundMatch;
+ }
+ else{
+ found_match = FindResult_PastEnd;
+ }
+ }
+ }
+ else{
+ char prev = buffer_get_char(app, &result.buffer, result.start - 1);
+
+ if (!char_is_alpha_numeric(prev)){
+ result.end = result.start + word.size;
+ if (result.end <= end_pos){
+ char next = buffer_get_char(app, &result.buffer, result.end);
+ if (!char_is_alpha_numeric(next)){
+ result.found_match = true;
+ found_match = FindResult_FoundMatch;
+ }
+ }
+ else{
+ found_match = FindResult_PastEnd;
+ }
+ }
+ }
+
+ *result_ptr = result;
+
+ return(found_match);
+}
+
+static int
+search_front_to_back_step(Application_Links *app,
+ Search_Range *range,
+ String word,
+ int *pos,
+ Search_Match *result_ptr){
+ int found_match = FindResult_None;
+
+ Search_Match result = *result_ptr;
+
+ int end_pos = range->start + range->size;
+ if (*pos + word.size < end_pos){
+ int start_pos = *pos;
+ if (start_pos < range->start){
+ start_pos = range->start;
+ }
+
+ result.buffer = app->get_buffer(app, range->buffer, AccessAll);
+ buffer_seek_string_forward(app, &result.buffer,
+ start_pos, end_pos,
+ word.str, word.size,
+ &result.start);
+
+ if (result.start < end_pos){
+ *pos = result.start + 1;
+ found_match = match_check(app, range, pos, &result, word);
+ if (found_match == FindResult_FoundMatch){
+ *pos = result.end;
+ }
+ }
+ else{
+ found_match = FindResult_PastEnd;
+ *pos = end_pos + 1;
+ }
+ }
+ else{
+ found_match = FindResult_PastEnd;
+ *pos = end_pos + 1;
+ }
+
+ *result_ptr = result;
+
+ return(found_match);
+}
+
+static int
+search_front_to_back(Application_Links *app,
+ Search_Range *range,
+ String word,
+ int *pos,
+ Search_Match *result_ptr){
+ int found_match = FindResult_None;
+ for (;found_match == FindResult_None;){
+ found_match = search_front_to_back_step(app, range, word, pos, result_ptr);
+ }
+ return(found_match);
+}
+
+static int
+search_back_to_front_step(Application_Links *app,
+ Search_Range *range,
+ String word,
+ int *pos,
+ Search_Match *result_ptr){
+ int found_match = FindResult_None;
+
+ Search_Match result = *result_ptr;
+
+ if (*pos > range->start){
+ int start_pos = *pos;
+
+ result.buffer = app->get_buffer(app, range->buffer, AccessAll);
+ buffer_seek_string_backward(app, &result.buffer,
+ start_pos, range->start,
+ word.str, word.size,
+ &result.start);
+
+ // TODO(allen): deduplicate the match checking code.
+ if (result.start >= range->start){
+ *pos = result.start - 1;
+ found_match = match_check(app, range, pos, &result, word);
+ if (found_match == FindResult_FoundMatch){
+ *pos = result.start - word.size;
+ }
+ }
+ else{
+ found_match = FindResult_PastEnd;
+ }
+ }
+ else{
+ found_match = FindResult_PastEnd;
+ }
+
+ *result_ptr = result;
+
+ return(found_match);
+}
+
+static int
+search_back_to_front(Application_Links *app,
+ Search_Range *range,
+ String word,
+ int *pos,
+ Search_Match *result_ptr){
+ int found_match = FindResult_None;
+ for (;found_match == FindResult_None;){
+ found_match = search_back_to_front_step(app, range, word, pos, result_ptr);
+ }
+ return(found_match);
+}
+
+static Search_Match
+search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){
+ Search_Match result = {0};
+ Search_Iter iter = *it_ptr;
+
+ int count = set->count;
+ for (; iter.i < count;){
+ Search_Range *range = set->ranges + iter.i;
+
+ int find_result = FindResult_None;
+
+ if (!iter.range_initialized){
+ iter.range_initialized = true;
+ switch (range->type){
+ case SearchRange_BackToFront:
+ {
+ iter.back_pos = range->start+range->size-1;
+ }break;
+
+ case SearchRange_Wave:
+ {
+ iter.back_pos = range->mid_start-1;
+ iter.pos = range->mid_start + range->mid_size;
+ }break;
+ }
+ }
+
+ switch (range->type){
+ case SearchRange_FrontToBack:
+ {
+ find_result =
+ search_front_to_back(app, range,
+ iter.word,
+ &iter.pos,
+ &result);
+ }break;
+
+ case SearchRange_BackToFront:
+ {
+ find_result =
+ search_back_to_front(app, range,
+ iter.word,
+ &iter.back_pos,
+ &result);
+ }break;
+
+ case SearchRange_Wave:
+ {
+ Search_Match forward_match = {0};
+ Search_Match backward_match = {0};
+
+ int forward_result = FindResult_PastEnd;
+ int backward_result = FindResult_PastEnd;
+
+ if (iter.pos < range->start + range->size){
+ forward_result = search_front_to_back(app, range,
+ iter.word,
+ &iter.pos,
+ &forward_match);
+ }
+
+ if (iter.back_pos > range->start){
+ backward_result = search_back_to_front(app, range,
+ iter.word,
+ &iter.back_pos,
+ &backward_match);
+ }
+
+ if (forward_result == FindResult_FoundMatch){
+ if (backward_result == FindResult_FoundMatch){
+ find_result = FindResult_FoundMatch;
+
+ int forward_start = range->mid_start + range->mid_size;
+ int forward_distance = (forward_match.start - forward_start);
+ int backward_distance = (range->mid_start - backward_match.end);
+
+ if (backward_distance < forward_distance){
+ iter.pos = forward_match.start;
+ result = backward_match;
+ }
+ else{
+ iter.back_pos = backward_match.start;
+ result = forward_match;
+ }
+ }
+ else{
+ find_result = FindResult_FoundMatch;
+ result = forward_match;
+ }
+ }
+ else{
+ if (backward_result == FindResult_FoundMatch){
+ find_result = FindResult_FoundMatch;
+ result = backward_match;
+ --iter.pos;
+ }
+ else{
+ find_result = FindResult_PastEnd;
+ }
+ }
+ }break;
+ }
+
+ if (find_result == FindResult_FoundMatch){
+ goto double_break;
+ }
+ else if (find_result == FindResult_PastEnd){
+ search_iter_next_range(&iter);
+ }
+ }
+ double_break:;
+
+ *it_ptr = iter;
+
+ return(result);
+}
+
+#endif
diff --git a/4coder_types.h b/4coder_types.h
index d3e6f7ff..e69e7543 100644
--- a/4coder_types.h
+++ b/4coder_types.h
@@ -51,14 +51,6 @@ ENUM(uint64_t, Command_ID){
/* DOC(cmdid_null is set aside to always be zero and is not associated with any command.) */
cmdid_null,
- /* DOC(cmdid_center_view centers the view vertically on the cursor.) */
- cmdid_center_view,
- /* DOC(cmdid_left_adjust_view adjusts the view to be just left of the cursor's position.) */
- cmdid_left_adjust_view,
-
- /* DOC(cmdid_word_complete begins or continues cycling through completions for a partial word.) */
- cmdid_word_complete,
-
/* DOC(cmdid_undo performs a standard undo behavior.) */
cmdid_undo,
/* DOC(cmdid_redo reperforms an edit that was undone.) */
@@ -72,16 +64,17 @@ ENUM(uint64_t, Command_ID){
cmdid_interactive_new,
/* DOC(cmdid_interactive_open begins an interactive dialogue to open a file into a buffer.) */
cmdid_interactive_open,
- /* DOC(cmdid_reopen reloads the active buffer's associated file and discards the old buffer contents for the reloaded file.) */
- cmdid_reopen,
- /* DOC(cmdid_save saves the buffer's contents into the associated file.) */
- cmdid_save,
/* DOC(cmdid_save_as does not currently work and is likely to be removed rather that fixed.) */
cmdid_save_as,
/* DOC(cmdid_interactive_switch_buffer begins an interactive dialogue to choose an open buffer to swap into the active view.) */
cmdid_interactive_switch_buffer,
/* DOC(cmdid_interactive_kill_buffer begins an interactive dialogue to choose an open buffer to kill.) */
cmdid_interactive_kill_buffer,
+
+ /* DOC(cmdid_reopen reloads the active buffer's associated file and discards the old buffer contents for the reloaded file.) */
+ cmdid_reopen,
+ /* DOC(cmdid_save saves the buffer's contents into the associated file.) */
+ cmdid_save,
/* DOC(cmdid_kill_buffer tries to kill the active buffer.) */
cmdid_kill_buffer,
@@ -157,9 +150,18 @@ ENUM(int32_t, Buffer_Setting_ID){
active when a buffer is active.) */
BufferSetting_MapID,
- /* DOC(The BufferSetting_Eol setting spcifies how line ends should be saved to the backing file.
+ /* DOC(The BufferSetting_Eol setting specifies how line ends should be saved to the backing file.
A 1 indicates dos endings "\r\n" and a 0 indicates nix endings "\n".) */
BufferSetting_Eol,
+
+ /* DOC(The BufferSetting_Unimportant setting marks a buffer so that it's dirty state will be completely
+ ignored. This means the "dirty" star is hidden and the buffer can be closed without presenting an
+ "are you sure" dialogue screen.) */
+ BufferSetting_Unimportant,
+
+ /* DOC(The BufferSetting_ReadOnly setting marks a buffer so that it can only be returned from buffer
+ access calls that include an AccessProtected flag.) */
+ BufferSetting_ReadOnly,
};
/* DOC(A View_Setting_ID names a setting in a view.) */
@@ -185,7 +187,7 @@ ENUM(int32_t, View_Setting_ID){
FLAGENUM(Buffer_Create_Flag){
/* DOC(BufferCreate_Background is not currently implemented.) */
BufferCreate_Background = 0x1,
- /* DOC(When BufferCreate_AlwaysNew is et it indicates the buffer should be
+ /* DOC(When BufferCreate_AlwaysNew is set it indicates the buffer should be
cleared to empty even if it's associated file already has content.) */
BufferCreate_AlwaysNew = 0x2,
};
@@ -485,7 +487,8 @@ struct GUI_Scroll_Vars{
};
/* DOC(Full_Cursor describes the position of a cursor in every buffer
-coordinate system supported by 4coder.)
+coordinate system supported by 4coder. This cursor type requires that
+the buffer is associated with a view to give the x/y values meaning.)
DOC_SEE(4coder_Buffer_Positioning_System) */
struct Full_Cursor{
/* DOC(This field contains the cursor's position in absolute positioning.) */
@@ -504,6 +507,20 @@ struct Full_Cursor{
float wrapped_y;
};
+/* DOC(Partial_Cursor describes the position of a cursor in all of
+the coordinate systems that a invariant to the View. In other words
+the coordinate systems available here can be used on a buffer that is
+not currently associated with a View.)
+DOC_SEE(4coder_Buffer_Positioning_System) */
+struct Partial_Cursor{
+ /* DOC(This field contains the cursor's position in absolute positioning.) */
+ int32_t pos;
+ /* DOC(This field contains the number of the line where the cursor is located. This field is one based.) */
+ int32_t line;
+ /* DOC(This field contains the number of the column where the cursor is located. This field is one based.) */
+ int32_t character;
+};
+
/* DOC(Buffer_Seek describes the destination of a seek operation. There are helpers
for concisely creating Buffer_Seek structs. They can be found in 4coder_buffer_types.h.)
DOC_SEE(Buffer_Seek_Type)
@@ -596,7 +613,9 @@ struct Buffer_Summary{
};
/* DOC(View_Summary acts as a handle to a view and describes the state of the view.)
-DOC_SEE(Access_Flag)*/
+DOC_SEE(Access_Flag)
+DOC_SEE(Full_Cursor)
+*/
struct View_Summary{
/* DOC(
This field indicates whether the View_Summary describes a view that is open in 4coder.
@@ -617,12 +636,10 @@ struct View_Summary{
/*
DOC(If this is not a null summary, this describes the position of the cursor.)
- DOC_SEE(Full_Cursor)
*/
Full_Cursor cursor;
/*
DOC(If this is not a null summary, this describes the position of the mark.)
- DOC_SEE(Full_Cursor)
*/
Full_Cursor mark;
/* DOC(If this is not a null summary, this is the x position that is maintained in vertical navigation.) */
@@ -634,9 +651,9 @@ struct View_Summary{
/* DOC(If this is not a null summary, this indicates that the view is set to highlight white space.) */
bool32 show_whitespace;
- /* DOC(This feature is not fully implemented yet.) */
+ /* DOC(If this is not a null summary, this describes the screen position in which this view's buffer is displayed.) */
i32_Rect file_region;
- /* DOC(This feature is not fully implemented yet.) */
+ /* DOC(If this is not a null summary, this describes the scrolling position inside the view.) */
GUI_Scroll_Vars scroll_vars;
};
diff --git a/4ed.cpp b/4ed.cpp
index 6e9dacce..e040032c 100644
--- a/4ed.cpp
+++ b/4ed.cpp
@@ -34,15 +34,6 @@ struct CLI_List{
i32 count, max;
};
-struct Complete_State{
- Search_Set set;
- Search_Iter iter;
- Table hits;
- String_Space str;
- i32 word_start, word_end;
- b32 initialized;
-};
-
struct Command_Data{
Models *models;
struct App_Vars *vars;
@@ -169,7 +160,6 @@ struct App_Vars{
App_State state;
App_State_Resizing resizing;
- Complete_State complete_state;
Command_Data command_data;
@@ -281,223 +271,6 @@ COMMAND_DECL(null){
AllowLocal(command);
}
-internal i32
-seek_token_left(Cpp_Token_Stack *tokens, i32 pos){
- Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
- if (get.token_index == -1){
- get.token_index = 0;
- }
-
- Cpp_Token *token = tokens->tokens + get.token_index;
- if (token->start == pos && get.token_index > 0){
- --token;
- }
-
- return token->start;
-}
-
-internal i32
-seek_token_right(Cpp_Token_Stack *tokens, i32 pos){
- Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
- if (get.in_whitespace){
- ++get.token_index;
- }
- if (get.token_index >= tokens->count){
- get.token_index = tokens->count-1;
- }
-
- Cpp_Token *token = tokens->tokens + get.token_index;
- return token->start + token->size;
-}
-
-COMMAND_DECL(center_view){
- REQ_READABLE_VIEW(view);
- REQ_FILE(file, view);
-
- Assert(view->edit_pos);
-
- f32 h = view_file_height(view);
- f32 y = view->edit_pos->cursor.wrapped_y;
- if (view->file_data.unwrapped_lines){
- y = view->edit_pos->cursor.unwrapped_y;
- }
-
- y = clamp_bottom(0.f, y - h*.5f);
- view->edit_pos->scroll.target_y = ROUND32(y);
-}
-
-COMMAND_DECL(left_adjust_view){
- REQ_READABLE_VIEW(view);
- REQ_FILE(file, view);
-
- Assert(view->edit_pos);
-
- f32 x = view->edit_pos->cursor.wrapped_x;
- if (view->file_data.unwrapped_lines){
- x = view->edit_pos->cursor.unwrapped_x;
- }
-
- x = clamp_bottom(0.f, x - 30.f);
- view->edit_pos->scroll.target_x = ROUND32(x);
-}
-
-COMMAND_DECL(word_complete){
- USE_MODELS(models);
- USE_VARS(vars);
- REQ_OPEN_VIEW(view);
- REQ_FILE(file, view);
-
- Assert(view->edit_pos);
-
- Partition *part = &models->mem.part;
- General_Memory *general = &models->mem.general;
- Working_Set *working_set = &models->working_set;
- Complete_State *complete_state = &vars->complete_state;
- Search_Range *ranges = 0;
-
- Buffer_Type *buffer = &file->state.buffer;
- i32 size_of_buffer = buffer_size(buffer);
-
- i32 cursor_pos = 0;
- i32 word_start = 0;
- i32 word_end = 0;
- char c = 0;
-
- char *spare = 0;
- i32 size = 0;
-
- b32 do_init = false;
- if (view->mode.rewrite != 2){
- do_init = true;
- }
- view->next_mode.rewrite = 2;
- if (complete_state->initialized == 0){
- do_init = true;
- }
-
- if (do_init){
- word_end = view->edit_pos->cursor.pos;
- word_start = word_end;
- cursor_pos = word_end - 1;
-
- // TODO(allen): macros for these buffer loops and some method
- // of breaking out of them.
- for (Buffer_Backify_Type loop = buffer_backify_loop(buffer, cursor_pos, 0);
- buffer_backify_good(&loop);
- buffer_backify_next(&loop)){
- i32 end = loop.absolute_pos;
- char *data = loop.data - loop.absolute_pos;
- for (; cursor_pos >= end; --cursor_pos){
- c = data[cursor_pos];
- if (char_is_alpha(c)){
- word_start = cursor_pos;
- }
- else if (!char_is_numeric(c)){
- goto double_break;
- }
- }
- }
- double_break:;
-
- size = word_end - word_start;
-
- if (size == 0){
- complete_state->initialized = 0;
- return;
- }
-
- complete_state->initialized = 1;
- search_iter_init(general, &complete_state->iter, size);
- buffer_stringify(buffer, word_start, word_end, complete_state->iter.word.str);
- complete_state->iter.word.size = size;
-
- {
- File_Node *node, *used_nodes;
- Editing_File *file_ptr;
- i32 buffer_count, j;
-
- buffer_count = working_set->file_count;
- search_set_init(general, &complete_state->set, buffer_count + 1);
- ranges = complete_state->set.ranges;
- ranges[0].buffer = buffer;
- ranges[0].start = 0;
- ranges[0].size = word_start;
-
- ranges[1].buffer = buffer;
- ranges[1].start = word_end;
- ranges[1].size = size_of_buffer - word_end;
-
- used_nodes = &working_set->used_sentinel;
- j = 2;
- for (dll_items(node, used_nodes)){
- file_ptr = (Editing_File*)node;
- if (file_ptr != file){
- ranges[j].buffer = &file_ptr->state.buffer;
- ranges[j].start = 0;
- ranges[j].size = buffer_size(ranges[j].buffer);
- ++j;
- }
- }
- complete_state->set.count = j;
- }
-
- search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4));
- search_hit_add(general, &complete_state->hits, &complete_state->str,
- complete_state->iter.word.str, complete_state->iter.word.size);
-
- complete_state->word_start = word_start;
- complete_state->word_end = word_end;
- }
- else{
- word_start = complete_state->word_start;
- word_end = complete_state->word_end;
- size = complete_state->iter.word.size;
- }
-
- if (size > 0){
- for (;;){
- i32 match_size = 0;
- Search_Match match =
- search_next_match(part, &complete_state->set, &complete_state->iter);
-
- if (match.found_match){
- Temp_Memory temp = begin_temp_memory(part);
- match_size = match.end - match.start;
- spare = (char*)push_array(part, char, match_size);
- buffer_stringify(match.buffer, match.start, match.end, spare);
-
- if (search_hit_add(general, &complete_state->hits, &complete_state->str, spare, match_size)){
- view_replace_range(system, models, view, word_start, word_end, spare, match_size);
- view_cursor_move(view, word_start + match_size);
-
- complete_state->word_end = word_start + match_size;
- complete_state->set.ranges[1].start = word_start + match_size;
- end_temp_memory(temp);
- break;
- }
- end_temp_memory(temp);
- }
- else{
- complete_state->iter.pos = 0;
- complete_state->iter.i = 0;
-
- search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4));
- search_hit_add(general, &complete_state->hits, &complete_state->str,
- complete_state->iter.word.str, complete_state->iter.word.size);
-
- match_size = complete_state->iter.word.size;
- view_replace_range(system, models, view, word_start, word_end,
- complete_state->iter.word.str, match_size);
- view_cursor_move(view, word_start + match_size);
-
- complete_state->word_end = word_start + match_size;
- complete_state->set.ranges[1].start = word_start + match_size;
- break;
- }
- }
- }
-}
-
// TODO(allen): FIX THIS SHIT!
COMMAND_DECL(undo){
USE_MODELS(models);
@@ -1027,11 +800,6 @@ setup_command_table(){
#define SET(n) command_table[cmdid_##n] = command_##n
SET(null);
- SET(center_view);
- SET(left_adjust_view);
-
- SET(word_complete);
-
SET(undo);
SET(redo);
SET(history_backward);
diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp
index bada3b39..805a628b 100644
--- a/4ed_api_implementation.cpp
+++ b/4ed_api_implementation.cpp
@@ -447,6 +447,7 @@ This call begins a loop across all the buffers.
If the buffer returned does not exist, the loop is finished.
Buffers should not be killed durring a buffer loop.
)
+DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
DOC_SEE(get_buffer_next)
*/{
@@ -474,6 +475,7 @@ The global buffer order is kept roughly in the order of most recently used to le
If the buffer outputted does not exist, the loop is finished.
Buffers should not be killed or created durring a buffer loop.
)
+DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
DOC_SEE(get_buffer_first)
*/{
@@ -491,6 +493,7 @@ Get_Buffer(Application_Links *app, Buffer_ID buffer_id, Access_Flag access)/*
DOC_PARAM(buffer_id, The parameter buffer_id specifies which buffer to try to get.)
DOC_PARAM(access, The access parameter determines what levels of protection this call can access.)
DOC_RETURN(This call returns a summary that describes the indicated buffer if it exists and is accessible.)
+DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
DOC_SEE(Buffer_ID)
*/{
@@ -516,6 +519,7 @@ DOC_PARAM(name, The name parameter specifies the buffer name to try to get. The
DOC_PARAM(len, The len parameter specifies the length of the name string.)
DOC_PARAM(access, The access parameter determines what levels of protection this call can access.)
DOC_RETURN(This call returns a summary that describes the indicated buffer if it exists and is accessible.)
+DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
@@ -534,6 +538,35 @@ DOC_SEE(Access_Flag)
return(buffer);
}
+internal i32
+seek_token_left(Cpp_Token_Stack *tokens, i32 pos){
+ Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
+ if (get.token_index == -1){
+ get.token_index = 0;
+ }
+
+ Cpp_Token *token = tokens->tokens + get.token_index;
+ if (token->start == pos && get.token_index > 0){
+ --token;
+ }
+
+ return token->start;
+}
+
+internal i32
+seek_token_right(Cpp_Token_Stack *tokens, i32 pos){
+ Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
+ if (get.in_whitespace){
+ ++get.token_index;
+ }
+ if (get.token_index >= tokens->count){
+ get.token_index = tokens->count-1;
+ }
+
+ Cpp_Token *token = tokens->tokens + get.token_index;
+ return token->start + token->size;
+}
+
API_EXPORT int32_t
Buffer_Boundary_Seek(Application_Links *app, Buffer_Summary *buffer, int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)/*
DOC_PARAM(buffer, The buffer parameter specifies the buffer through which to seek.)
@@ -712,6 +745,32 @@ DOC_SEE(4coder_Buffer_Positioning_System)
return(result);
}
+API_EXPORT bool32
+Buffer_Compute_Cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)/*
+DOC_PARAM(buffer, The buffer parameter specifies the buffer on which to run the cursor computation.)
+DOC_PARAM(seek, The seek parameter specifies the target position for the seek.)
+DOC_PARAM(cursor_out, On success this struct is filled with the result of the seek.)
+DOC_RETURN(This call returns non-zero on success.)
+DOC(Computes a Partial_Cursor for the given seek position with no side effects.
+The seek position must be one of the types supported by Partial_Cursor. Those
+types are absolute position and line,column position.)
+DOC_SEE(Buffer_Seek)
+DOC_SEE(Partial_Cursor)
+*/{
+ Command_Data *cmd = (Command_Data*)app->cmd_context;
+ Editing_File *file = imp_get_file(cmd, buffer);
+ bool32 result = false;
+
+ if (file){
+ if (file_compute_cursor(file, seek, cursor_out)){
+ result = true;
+ fill_buffer_summary(buffer, file, cmd);
+ }
+ }
+
+ return(result);
+}
+
API_EXPORT bool32
Buffer_Batch_Edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type)/*
DOC_PARAM(str, This parameter provides all of the source string for the edits in the batch.)
@@ -844,6 +903,26 @@ DOC_SEE(Buffer_Setting_ID)
file->settings.dos_write_mode = value;
file->state.last_4ed_edit_time = system->now_time_stamp();
}break;
+
+ case BufferSetting_Unimportant:
+ {
+ if (value){
+ file->settings.unimportant = true;
+ }
+ else{
+ file->settings.unimportant = false;
+ }
+ }break;
+
+ case BufferSetting_ReadOnly:
+ {
+ if (value){
+ file->settings.read_only = true;
+ }
+ else{
+ file->settings.read_only = false;
+ }
+ }break;
}
fill_buffer_summary(buffer, file, cmd);
}
@@ -907,6 +986,7 @@ If the buffer does not exist a new buffer is created and named after the given f
the filename corresponds to a file on the disk that file is loaded and put into buffer, if
the filename does not correspond to a file on disk the buffer is created empty.
)
+DOC_SEE(Buffer_Summary)
DOC_SEE(Buffer_Create_Flag)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
@@ -1508,8 +1588,30 @@ DOC_SEE(Buffer_Seek)
seek.character = 1;
}
Full_Cursor cursor = view_compute_cursor(vptr, seek);
- view_set_cursor(vptr, cursor,
- set_preferred_x, vptr->file_data.unwrapped_lines);
+ view_set_cursor(vptr, cursor, set_preferred_x,
+ vptr->file_data.unwrapped_lines);
+ fill_view_summary(view, vptr, cmd);
+ }
+ }
+
+ return(result);
+}
+
+API_EXPORT bool32
+View_Set_Scroll(Application_Links *app, View_Summary *view, GUI_Scroll_Vars scroll)/*
+DOC(TODO)
+DOC_SEE(GUI_Scroll_Vars)
+*/{
+ Command_Data *cmd = (Command_Data*)app->cmd_context;
+ View *vptr = imp_get_view(cmd, view);
+ Editing_File *file = 0;
+ bool32 result = false;
+
+ if (vptr){
+ file = vptr->file_data.file;
+ if (file && !file->is_loading){
+ result = true;
+ view_set_scroll(vptr, scroll);
fill_view_summary(view, vptr, cmd);
}
}
diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp
index 1376751d..f1244c10 100644
--- a/4ed_file_view.cpp
+++ b/4ed_file_view.cpp
@@ -377,6 +377,40 @@ view_cursor_limits(View *view){
return(limits);
}
+inline Partial_Cursor
+file_compute_cursor_from_pos(Editing_File *file, i32 pos){
+ Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
+ return(result);
+}
+
+inline Partial_Cursor
+file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
+ Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
+ return(result);
+}
+
+inline b32
+file_compute_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
+ b32 result = true;
+ switch (seek.type){
+ case buffer_seek_pos:
+ {
+ *cursor = file_compute_cursor_from_pos(file, seek.pos);
+ }break;
+
+ case buffer_seek_line_char:
+ {
+ *cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
+ }break;
+
+ default:
+ {
+ result = false;
+ }break;
+ }
+ return(result);
+}
+
inline Full_Cursor
view_compute_cursor_from_pos(View *view, i32 pos){
Editing_File *file = view->file_data.file;
@@ -5982,196 +6016,6 @@ file_view_free_buffers(View *view){
view->gui_mem = 0;
}
-struct Search_Range{
- Buffer_Type *buffer;
- i32 start, size;
-};
-
-struct Search_Set{
- Search_Range *ranges;
- i32 count, max;
-};
-
-struct Search_Iter{
- String word;
- i32 pos;
- i32 i;
-};
-
-struct Search_Match{
- Buffer_Type *buffer;
- i32 start, end;
- b32 found_match;
-};
-
-internal void
-search_iter_init(General_Memory *general, Search_Iter *iter, i32 size){
- i32 str_max;
-
- if (iter->word.str == 0){
- str_max = size*2;
- iter->word.str = (char*)general_memory_allocate(general, str_max);
- iter->word.memory_size = str_max;
- }
- else if (iter->word.memory_size < size){
- str_max = size*2;
- iter->word.str = (char*)general_memory_reallocate_nocopy(general, iter->word.str, str_max);
- iter->word.memory_size = str_max;
- }
-
- iter->i = 0;
- iter->pos = 0;
-}
-
-internal void
-search_set_init(General_Memory *general, Search_Set *set, i32 set_count){
- i32 max;
-
- if (set->ranges == 0){
- max = set_count*2;
- set->ranges = (Search_Range*)general_memory_allocate(general, sizeof(Search_Range)*max);
- set->max = max;
- }
- else if (set->max < set_count){
- max = set_count*2;
- set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
- general, set->ranges, sizeof(Search_Range)*max);
- set->max = max;
- }
-
- set->count = set_count;
-}
-
-internal void
-search_hits_table_alloc(General_Memory *general, Table *hits, i32 table_size){
- void *mem;
- i32 mem_size;
-
- mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
- if (hits->hash_array == 0){
- mem = general_memory_allocate(general, mem_size);
- }
- else{
- mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
- }
- table_init_memory(hits, mem, table_size, sizeof(Offset_String));
-}
-
-internal void
-search_hits_init(General_Memory *general, Table *hits, String_Space *str, i32 table_size, i32 str_size){
- void *mem;
- i32 mem_size;
-
- if (hits->hash_array == 0){
- search_hits_table_alloc(general, hits, table_size);
- }
- else if (hits->max < table_size){
- mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
- mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
- table_init_memory(hits, mem, table_size, sizeof(Offset_String));
- }
-
- if (str->space == 0){
- str->space = (char*)general_memory_allocate(general, str_size);
- str->max = str_size;
- }
- else if (str->max < str_size){
- str->space = (char*)general_memory_reallocate_nocopy(general, str->space, str_size);
- str->max = str_size;
- }
-
- str->pos = str->new_pos = 0;
- table_clear(hits);
-}
-
-internal b32
-search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *str, i32 len){
- b32 result;
- i32 new_size;
- Offset_String ostring;
- Table new_hits;
-
- Assert(len != 0);
-
- ostring = strspace_append(space, str, len);
- if (ostring.size == 0){
- new_size = Max(space->max*2, space->max + len);
- space->space = (char*)general_memory_reallocate(general, space->space, space->new_pos, new_size);
- ostring = strspace_append(space, str, len);
- }
-
- Assert(ostring.size != 0);
-
- if (table_at_capacity(hits)){
- search_hits_table_alloc(general, &new_hits, hits->max*2);
- table_clear(&new_hits);
- table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
- general_memory_free(general, hits->hash_array);
- *hits = new_hits;
- }
-
- if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
- result = 1;
- strspace_keep_prev(space);
- }
- else{
- result = 0;
- strspace_discard_prev(space);
- }
-
- return(result);
-}
-
-internal Search_Match
-search_next_match(Partition *part, Search_Set *set, Search_Iter *iter_){
- Search_Match result = {};
- Search_Iter iter = *iter_;
- Search_Range *range;
- Temp_Memory temp;
- char *spare;
- i32 start_pos, end_pos, count;
-
- temp = begin_temp_memory(part);
- spare = push_array(part, char, iter.word.size);
-
- count = set->count;
- for (; iter.i < count;){
- range = set->ranges + iter.i;
-
- end_pos = range->start + range->size;
-
- if (iter.pos + iter.word.size < end_pos){
- start_pos = Max(iter.pos, range->start);
- result.start = buffer_find_string(
- range->buffer, start_pos, end_pos, iter.word.str, iter.word.size, spare);
-
- if (result.start < end_pos){
- iter.pos = result.start + 1;
- if (result.start == 0 || !char_is_alpha_numeric(buffer_get_char(range->buffer, result.start - 1))){
- result.end = buffer_seek_word_right_assume_on_word(range->buffer, result.start);
- if (result.end < end_pos){
- result.found_match = 1;
- result.buffer = range->buffer;
- iter.pos = result.end;
- break;
- }
- }
- }
- else{
- ++iter.i, iter.pos = 0;
- }
- }
- else{
- ++iter.i, iter.pos = 0;
- }
- }
- end_temp_memory(temp);
-
- *iter_ = iter;
-
- return(result);
-}
-
inline void
view_change_size(General_Memory *general, View *view){
if (view->file_data.file){
diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp
index fba80ba8..edf28bb0 100644
--- a/buffer/4coder_buffer_abstract.cpp
+++ b/buffer/4coder_buffer_abstract.cpp
@@ -1069,6 +1069,21 @@ buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width,
return(state.cursor);
}
+internal_4tech Partial_Cursor
+buffer_partial_from_pos(Buffer_Type *buffer, int pos){
+ Partial_Cursor result = {0};
+
+ if (pos > buffer->size) pos = buffer->size;
+ if (pos < 0) pos = 0;
+
+ int line_index = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count);
+ result.pos = pos;
+ result.line = line_index+1;
+ result.character = pos - buffer->line_starts[line_index] + 1;
+
+ return(result);
+}
+
internal_4tech Full_Cursor
buffer_cursor_from_pos(Buffer_Type *buffer, int pos, float *wraps,
float max_width, float font_height, float *advance_data){
@@ -1086,20 +1101,45 @@ buffer_cursor_from_pos(Buffer_Type *buffer, int pos, float *wraps,
return(result);
}
+internal_4tech Partial_Cursor
+buffer_partial_from_line_character(Buffer_Type *buffer, int line, int character){
+ Partial_Cursor result = {0};
+
+ int line_index = line - 1;
+ if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
+ if (line_index < 0) line_index = 0;
+
+ int this_start = buffer->line_starts[line_index];
+ int next_start = buffer->size;
+ if (line_index+1 < buffer->line_count){
+ next_start = buffer->line_starts[line_index+1];
+ }
+
+ int max_character = (next_start-this_start);
+
+ if (character <= 0) character = 1;
+ if (character > max_character) character = max_character;
+
+ result.pos = this_start + character - 1;
+ result.line = line_index+1;
+ result.character = character;
+
+ return(result);
+}
+
internal_4tech Full_Cursor
buffer_cursor_from_line_character(Buffer_Type *buffer, int line, int character, float *wraps,
float max_width, float font_height, float *advance_data){
- Full_Cursor result;
- int line_index;
-
- line_index = line - 1;
+ Full_Cursor result = {0};
+
+ int line_index = line - 1;
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
-
+
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_line_char(line, character),
max_width, font_height, advance_data, result);
-
+
return(result);
}
diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp
index f6a86390..99f09cf0 100644
--- a/power/4coder_experiments.cpp
+++ b/power/4coder_experiments.cpp
@@ -238,17 +238,12 @@ get_bindings(void *data, int size){
default_keys(context);
- // NOTE(allen|4.0.6): Command maps can be opened more than
+ // NOTE(allen|a4.0.6): Command maps can be opened more than
// once so that you can extend existing maps very easily.
// You can also use the helper "restart_map" instead of
// begin_map to clear everything that was in the map and
// bind new things instead.
begin_map(context, mapid_global);
- bind(context, '.', MDFR_ALT, change_to_build_panel);
- bind(context, ',', MDFR_ALT, close_build_panel);
- bind(context, 'n', MDFR_ALT, goto_next_error);
- bind(context, 'N', MDFR_ALT, goto_prev_error);
- bind(context, 'M', MDFR_ALT, goto_first_error);
end_map(context);
begin_map(context, mapid_file);