§2.5.7: Cpp_Lex_Data
struct Cpp_Lex_Data { /* non-public internals */ } ;
Description
Cpp_Lex_Data represents the state of the lexer so that the system may be resumable
and the user can manage the lexer state and decide when to resume lexing with it. To create
diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp
index 02b988b2..12b57f0d 100644
--- a/4coder_default_bindings.cpp
+++ b/4coder_default_bindings.cpp
@@ -390,6 +390,7 @@ default_keys(Bind_Helper *context){
bind(context, 'q', MDFR_CTRL, query_replace);
bind(context, 'r', MDFR_CTRL, reverse_search);
bind(context, 's', MDFR_CTRL, cmdid_save);
+ bind(context, 'T', MDFR_CTRL, list_all_locations_of_identifier);
bind(context, 'u', MDFR_CTRL, to_uppercase);
bind(context, 'U', MDFR_CTRL, rewrite_as_single_caps);
bind(context, 'v', MDFR_CTRL, paste_and_indent);
diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp
index fa7642fd..cbdfa21c 100644
--- a/4coder_default_include.cpp
+++ b/4coder_default_include.cpp
@@ -677,7 +677,7 @@ static Cpp_Token*
get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line,
int32_t *line_start_out = 0){
int32_t line_start = buffer_get_line_start(app, buffer, line);
- Cpp_Get_Token_Result get_token = cpp_get_token(&tokens, line_start);
+ Cpp_Get_Token_Result get_token = cpp_get_token(tokens, line_start);
if (get_token.in_whitespace){
get_token.token_index += 1;
@@ -1769,7 +1769,7 @@ buffer_seek_alphanumeric_or_camel_left(Application_Links *app, Buffer_Summary *b
static int32_t
seek_token_left(Cpp_Token_Array *tokens, int32_t pos){
- Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
+ Cpp_Get_Token_Result get = cpp_get_token(*tokens, pos);
if (get.token_index == -1){
get.token_index = 0;
}
@@ -1784,7 +1784,7 @@ seek_token_left(Cpp_Token_Array *tokens, int32_t pos){
static int32_t
seek_token_right(Cpp_Token_Array *tokens, int32_t pos){
- Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
+ Cpp_Get_Token_Result get = cpp_get_token(*tokens, pos);
if (get.in_whitespace){
++get.token_index;
}
@@ -2707,22 +2707,24 @@ CUSTOM_COMMAND_SIG(exit_4coder){
#include "4coder_jump_parsing.cpp"
static void
-generic_search_all_buffers(Application_Links *app, General_Memory *general, Partition *part,
- uint32_t match_flags){
-
- Query_Bar string;
+get_search_all_string(Application_Links *app, Query_Bar *bar){
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;
+ bar->prompt = make_lit_string("List Locations For: ");
+ bar->string = make_fixed_width_string(string_space);
+ if (!query_user_string(app, bar)){
+ bar->string.size = 0;
+ }
+}
+
+static void
+generic_search_all_buffers(Application_Links *app, General_Memory *general, Partition *part,
+ String string, uint32_t match_flags){
Search_Set set = {0};
Search_Iter iter = {0};
- search_iter_init(general, &iter, string.string.size);
- copy_ss(&iter.word, string.string);
+ search_iter_init(general, &iter, string.size);
+ copy_ss(&iter.word, string);
int32_t buffer_count = get_buffer_count(app);
search_set_init(general, &set, buffer_count);
@@ -2732,7 +2734,7 @@ generic_search_all_buffers(Application_Links *app, General_Memory *general, Part
String search_name = make_lit_string("*search*");
Buffer_Summary search_buffer = get_buffer_by_name(app, search_name.str, search_name.size,
- AccessAll);
+ AccessAll);
if (!search_buffer.exists){
search_buffer = create_buffer(app, search_name.str, search_name.size, BufferCreate_AlwaysNew);
buffer_set_setting(app, &search_buffer, BufferSetting_Unimportant, true);
@@ -2801,7 +2803,7 @@ generic_search_all_buffers(Application_Links *app, General_Memory *general, Part
if (spare == 0){
buffer_replace_range(app, &search_buffer,
- size, size, str, part_size);
+ size, size, str, part_size);
size += part_size;
end_temp_memory(temp);
@@ -2843,19 +2845,59 @@ generic_search_all_buffers(Application_Links *app, General_Memory *general, Part
}
CUSTOM_COMMAND_SIG(list_all_locations){
- generic_search_all_buffers(app, &global_general, &global_part, SearchFlag_MatchWholeWord);
+ Query_Bar bar;
+ get_search_all_string(app, &bar);
+ if (bar.string.size == 0) return;
+ generic_search_all_buffers(app, &global_general, &global_part,
+ bar.string, SearchFlag_MatchWholeWord);
}
CUSTOM_COMMAND_SIG(list_all_substring_locations){
- generic_search_all_buffers(app, &global_general, &global_part, SearchFlag_MatchSubstring);
+ Query_Bar bar;
+ get_search_all_string(app, &bar);
+ if (bar.string.size == 0) return;
+ generic_search_all_buffers(app, &global_general, &global_part,
+ bar.string, SearchFlag_MatchSubstring);
}
CUSTOM_COMMAND_SIG(list_all_locations_case_insensitive){
- generic_search_all_buffers(app, &global_general, &global_part, SearchFlag_CaseInsensitive | SearchFlag_MatchWholeWord);
+ Query_Bar bar;
+ get_search_all_string(app, &bar);
+ if (bar.string.size == 0) return;
+ generic_search_all_buffers(app, &global_general, &global_part,
+ bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchWholeWord);
}
CUSTOM_COMMAND_SIG(list_all_substring_locations_case_insensitive){
- generic_search_all_buffers(app, &global_general, &global_part, SearchFlag_CaseInsensitive | SearchFlag_MatchSubstring);
+ Query_Bar bar;
+ get_search_all_string(app, &bar);
+ if (bar.string.size == 0) return;
+ generic_search_all_buffers(app, &global_general, &global_part,
+ bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchSubstring);
+}
+
+CUSTOM_COMMAND_SIG(list_all_locations_of_identifier){
+ View_Summary view = get_active_view(app, AccessProtected);
+ Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
+
+ Cpp_Get_Token_Result get_result = {0};
+ bool32 success = buffer_get_token_index(app, &buffer, view.cursor.pos, &get_result);
+
+ if (success && !get_result.in_whitespace){
+ char space[128];
+ int32_t size = get_result.token_end - get_result.token_start;
+
+ if (size > 0 && size <= sizeof(space)){
+ success = buffer_read_range(app, &buffer, get_result.token_start,
+ get_result.token_end, space);
+ if (success){
+ String str = make_string(space, size);
+ exec_command(app, change_active_panel);
+ generic_search_all_buffers(app, &global_general, &global_part,
+ str, SearchFlag_MatchWholeWord);
+ }
+ }
+ }
}
struct Word_Complete_State{
diff --git a/4cpp_lexer.h b/4cpp_lexer.h
index 8116cab4..25020c72 100644
--- a/4cpp_lexer.h
+++ b/4cpp_lexer.h
@@ -151,8 +151,8 @@ static String_And_Flag keywords[] = {
FCPP_LINK Cpp_Get_Token_Result
-cpp_get_token(Cpp_Token_Array *token_array_in, int32_t pos)/*
-DOC_PARAM(token_array, The array of tokens from which to get a token.)
+cpp_get_token(Cpp_Token_Array array, int32_t pos)/*
+DOC_PARAM(array, The array of tokens from which to get a token.)
DOC_PARAM(pos, The position, measured in bytes, to get the token for.)
DOC_RETURN(A Cpp_Get_Token_Result struct is returned containing the index
of a token and a flag indicating whether the pos is contained in the token
@@ -167,10 +167,10 @@ index can be -1 if the position is before the first token.)
DOC_SEE(Cpp_Get_Token_Result)
*/{
Cpp_Get_Token_Result result = {};
- Cpp_Token *token_array = token_array_in->tokens;
+ Cpp_Token *token_array = array.tokens;
Cpp_Token *token = 0;
int32_t first = 0;
- int32_t count = token_array_in->count;
+ int32_t count = array.count;
int32_t last = count;
int32_t this_start = 0, next_start = 0;
@@ -217,6 +217,12 @@ DOC_SEE(Cpp_Get_Token_Result)
result.in_whitespace = 1;
}
+ if (result.token_index >= 0 && result.token_index < count){
+ token = array.tokens + result.token_index;
+ result.token_start = token->start;
+ result.token_end = token->start + token->size;
+ }
+
return(result);
}
@@ -1130,13 +1136,13 @@ The start and end points are based on the edited region of the file before the e
Cpp_Relex_Range range = {0};
Cpp_Get_Token_Result get_result = {0};
- get_result = cpp_get_token(array, start_pos);
+ get_result = cpp_get_token(*array, start_pos);
range.start_token_index = get_result.token_index-1;
if (range.start_token_index < 0){
range.start_token_index = 0;
}
- get_result = cpp_get_token(array, end_pos);
+ get_result = cpp_get_token(*array, end_pos);
range.end_token_index = get_result.token_index;
if (end_pos > array->tokens[range.end_token_index].start){
++range.end_token_index;
diff --git a/4cpp_lexer_types.h b/4cpp_lexer_types.h
index e5632174..c307c932 100644
--- a/4cpp_lexer_types.h
+++ b/4cpp_lexer_types.h
@@ -303,6 +303,14 @@ struct Cpp_Get_Token_Result{
/* DOC(The in_whitespace field is true when the query position was actually in whitespace
after the result token.) */
int32_t in_whitespace;
+
+ /* DOC(If the token_index refers to an actual token, this is the start value of the token.
+ Otherwise this is zero.) */
+ int32_t token_start;
+
+ /* DOC(If the token_index refers to an actual token, this is the start+size value of the token.
+ Otherwise this is zero.) */
+ int32_t token_end;
};
/* DOC(Cpp_Relex_Range is the return result of the cpp_get_relex_range call.)
diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp
index 078ac3f5..bb2e590b 100644
--- a/4ed_api_implementation.cpp
+++ b/4ed_api_implementation.cpp
@@ -899,7 +899,7 @@ DOC_SEE(cpp_get_token)
if (file && token_array.tokens && file->state.tokens_complete){
result = 1;
Cpp_Get_Token_Result get = {0};
- get = cpp_get_token(&token_array, pos);
+ get = cpp_get_token(token_array, pos);
*get_result = get;
}
diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp
index 7c365e64..9ede73c2 100644
--- a/4ed_file_view.cpp
+++ b/4ed_file_view.cpp
@@ -297,14 +297,12 @@ view_file_height(View *view){
inline i32
view_get_cursor_pos(View *view){
i32 result = 0;
-
if (view->file_data.show_temp_highlight){
result = view->file_data.temp_highlight.pos;
}
else if (view->edit_pos){
result = view->edit_pos->cursor.pos;
}
-
return(result);
}
@@ -499,13 +497,6 @@ view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){
return(result);
}
-inline i32
-view_wrapped_line_span(f32 line_width, f32 max_width){
- i32 line_count = CEIL32(line_width / max_width);
- if (line_count == 0) line_count = 1;
- return(line_count);
-}
-
inline i32
view_compute_max_target_y(i32 lowest_line, i32 line_height, f32 view_height){
f32 max_target_y = ((lowest_line+.5f)*line_height) - view_height*.5f;
@@ -881,14 +872,11 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add
i32 *new_lines = (i32*)general_memory_reallocate(
general, buffer->line_starts,
- sizeof(i32)*count, sizeof(i32)*max);
+ sizeof(i32)*count, sizeof(f32)*max);
- if (new_lines){
- buffer->line_starts = new_lines;
- buffer->line_max = max;
- }
if (new_lines){
result = GROW_SUCCESS;
+ buffer->line_starts = new_lines;
}
else{
result = GROW_FAILED;
@@ -1314,7 +1302,7 @@ file_relex_parallel(System_Functions *system,
if (!inline_lex){
Cpp_Token_Array *array = &file->state.token_array;
- Cpp_Get_Token_Result get_token_result = cpp_get_token(array, end_i);
+ Cpp_Get_Token_Result get_token_result = cpp_get_token(*array, end_i);
i32 end_token_i = get_token_result.token_index;
if (end_token_i < 0){
@@ -1929,7 +1917,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models,
i32 cursor_count = 0;
View *view = 0;
- Panel *panel, *used_panels = &layout->used_sentinel;
+ Panel *panel = 0, *used_panels = &layout->used_sentinel;
for (dll_items(panel, used_panels)){
view = panel->view;
if (view->file_data.file == file){
@@ -2047,7 +2035,6 @@ file_do_single_edit(System_Functions *system,
i32 new_line_count = buffer_count_newlines(&file->state.buffer, start, start+str_len);
i32 line_shift = new_line_count - replaced_line_count;
-
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
file_grow_starts_as_needed(general, buffer, line_shift);
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
@@ -2140,7 +2127,6 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
Buffer_Edit *first_edit = batch;
Buffer_Edit *last_edit = batch + batch_size - 1;
file_relex_parallel(system, mem, file, first_edit->start, last_edit->end, shift_total);
-
}
}break;
@@ -3235,9 +3221,9 @@ struct Single_Line_Mode{
internal Single_Line_Input_Step
app_single_line_input_core(System_Functions *system, Working_Set *working_set,
- Key_Event_Data key, Single_Line_Mode mode){
+ Key_Event_Data key, Single_Line_Mode mode){
Single_Line_Input_Step result = {0};
-
+
if (key.keycode == key_back){
result.hit_backspace = 1;
if (mode.string->size > 0){
@@ -3248,14 +3234,19 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set,
{
mode.string->str[mode.string->size] = 0;
}break;
-
+
case SINGLE_LINE_FILE:
{
- char end_character = mode.string->str[mode.string->size];
- if (char_is_slash(end_character)){
- mode.string->size = reverse_seek_slash(*mode.string) + 1;
- mode.string->str[mode.string->size] = 0;
- hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
+ if (!key.modifiers[MDFR_CONTROL_INDEX]){
+ char end_character = mode.string->str[mode.string->size];
+ if (char_is_slash(end_character)){
+ mode.string->size = reverse_seek_slash(*mode.string) + 1;
+ mode.string->str[mode.string->size] = 0;
+ hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
+ }
+ else{
+ mode.string->str[mode.string->size] = 0;
+ }
}
else{
mode.string->str[mode.string->size] = 0;
@@ -3264,20 +3255,19 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set,
}
}
}
-
+
else if (key.character == '\n' || key.character == '\t'){
// NOTE(allen): do nothing!
}
-
+
else if (key.keycode == key_esc){
result.hit_esc = 1;
result.made_a_change = 1;
}
-
+
else if (key.character){
result.hit_a_character = 1;
- if (!key.modifiers[MDFR_CONTROL_INDEX] &&
- !key.modifiers[MDFR_ALT_INDEX]){
+ if (!key.modifiers[MDFR_CONTROL_INDEX] && !key.modifiers[MDFR_ALT_INDEX]){
if (mode.string->size+1 < mode.string->memory_size){
u8 new_character = (u8)key.character;
mode.string->str[mode.string->size] = new_character;
@@ -3293,7 +3283,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set,
result.did_command = 1;
}
}
-
+
return result;
}
@@ -3309,12 +3299,11 @@ inline Single_Line_Input_Step
app_single_file_input_step(System_Functions *system,
Working_Set *working_set, Key_Event_Data key,
String *string, Hot_Directory *hot_directory,
- b32 fast_folder_select, b32 try_to_match, b32 case_sensitive){
+ b32 try_to_match, b32 case_sensitive){
Single_Line_Mode mode = {};
mode.type = SINGLE_LINE_FILE;
mode.string = string;
mode.hot_directory = hot_directory;
- mode.fast_folder_select = fast_folder_select;
mode.try_to_match = try_to_match;
mode.case_sensitive = case_sensitive;
return app_single_line_input_core(system, working_set, key, mode);
@@ -3798,11 +3787,11 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
switch (view->interaction){
case IInt_Sys_File_List:
{
- b32 use_item_in_list = 1;
+ b32 autocomplete_with_enter = 1;
b32 activate_directly = 0;
if (view->action == IAct_Save_As || view->action == IAct_New){
- use_item_in_list = 0;
+ autocomplete_with_enter = 0;
}
String message = {0};
@@ -3828,12 +3817,13 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
for (i = 0; i < keys.count; ++i){
key = get_single_key(&keys, i);
step = app_single_file_input_step(system, &models->working_set, key,
- &hdir->string, hdir, 1, 1, 0);
+ &hdir->string, hdir, 1, 0);
if (step.made_a_change){
view->list_i = 0;
result.consume_keys = 1;
}
- if (!use_item_in_list && (key.keycode == '\n' || key.keycode == '\t')){
+
+ if (!autocomplete_with_enter && key.keycode == '\n'){
activate_directly = 1;
result.consume_keys = 1;
}
@@ -3877,7 +3867,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
set_last_folder_sc(&hdir->string, file_info.info->filename, '/');
do_new_directory = 1;
}
- else if (use_item_in_list){
+
+ else if (autocomplete_with_enter){
complete = 1;
copy_ss(&comp_dest, loop.full_path);
}
@@ -4388,6 +4379,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
SHOW_GUI_BOOL(2, h_align, "show temp highlight", view_ptr->file_data.show_temp_highlight);
SHOW_GUI_INT (2, h_align, "start temp highlight", view_ptr->file_data.temp_highlight.pos);
SHOW_GUI_INT (2, h_align, "end temp highlight", view_ptr->file_data.temp_highlight_end_pos);
+
SHOW_GUI_BOOL(2, h_align, "show whitespace", view_ptr->file_data.show_whitespace);
SHOW_GUI_BOOL(2, h_align, "locked", view_ptr->file_data.file_locked);
@@ -4871,7 +4863,6 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
case RenderStatus_NeedLineShift: break;
}
}while(stop.status != RenderStatus_Finished);
-
}
i32 cursor_begin = 0, cursor_end = 0;
@@ -4893,7 +4884,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
u32 main_color = style->main.default_color;
u32 special_color = style->main.special_character_color;
if (tokens_use){
- Cpp_Get_Token_Result result = cpp_get_token(&token_array, items->index);
+ Cpp_Get_Token_Result result = cpp_get_token(token_array, items->index);
main_color = *style_get_color(style, token_array.tokens[result.token_index]);
token_i = result.token_index + 1;
}
diff --git a/4ed_gui.cpp b/4ed_gui.cpp
index 7514d4c1..dc1fab2a 100644
--- a/4ed_gui.cpp
+++ b/4ed_gui.cpp
@@ -1257,7 +1257,7 @@ gui_do_jump(GUI_Target *target, GUI_View_Jump jump, GUI_Scroll_Vars vars){
internal void
gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region,
- Key_Summary *keys, i32 *list_i, GUI_Item_Update *update){
+ Key_Summary *keys, i32 *list_i, GUI_Item_Update *update){
if (update->has_adjustment){
*list_i = update->adjustment_value;
diff --git a/TODO.txt b/TODO.txt
index 2d4643fa..7b028b0c 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -144,6 +144,7 @@
;
; [X] eliminate the need for the lexer state's spare array.
; [X] fix buffer render item capacity issue
+; [X] tab to complete folder names in the new file dialogue
; Arbitrary wrap positions
; [X] allow for arbitrary wrap positions independent of view width
@@ -151,6 +152,8 @@
; [X] get horizontal scrolling to work in line wrap mode
; [] command for setting wrap positions in views directly
; [] ability to see the wrap position as a number/line and adjust graphically
+; [] word level wrapping
+; [] code level wrapping
; buffer behavior cleanup
; [X] show all characters as \# if they can't be rendered
@@ -166,7 +169,6 @@
; [] user file bar string
; [] API docs as text file
; [] read only files
-; [] tab to complete folder names in the new file dialogue
; [] option to hide hidden files
; [] control over how mouse effects panel focus
; [] option to not open *messages* every startup
@@ -175,18 +177,25 @@
; [] option to break buffer name ties by adding parent directories instead of <#>
; [] undo groups
; [] cursor/scroll groups
-; [] word level wrapping ~ temporary measure really want to have totally formatted code presentation
; [] double binding warnings
;
;
; [] the "main_4coder" experiment
; [] real multi-line editing
; [] multi-cursor editing
+; [] matching brace/paren/#if#endif highlighting
+; [] word repetition highlighting
+
+; [] simple text based project file
+; [] system commands bound to in project file
+; [] find matches for current identifier
+; [] ability to save and reopen the window state
; [] API docs have duplicate ids?
; [] introduce custom command line arguments
; [] control the file opening/start hook relationship better
; [] get keyboard state on launch
+; [] never launch two 4coders unless special -R flag is used
; meta programming system
; [X] condense system into single meta compiler
@@ -224,8 +233,8 @@
; control schemes
; [] emacs style sub-maps
; [] vim style modes
+; [] sublime style editing
; [] "tap typing"
-; [] "thin cursor"
; [] command meta data
; [] macros
;
@@ -233,7 +242,7 @@
; code engine
; [X] lexer with multiple chunk input
; [X] more correct auto-indentation
-; [] switch over to gap buffer
+; [X] switch over to gap buffer
; [] preprocessor
; [] AST generator
;
@@ -257,7 +266,6 @@
;
; [] tutorials
; [] 4edT thing
-; [] unicode/UTF support
; [] console emulator
;
@@ -280,13 +288,11 @@
; HARD BUGS
; [X] reduce cpu consumption
; [X] repainting too slow for resize looks really dumb
-; [] fyoucon's segfaults with malloc on win10
+; [X] fill screen right away
+; [X] minimize and reopen problem (fixed by microsoft patch aparently)
; [] handling cursor in non-client part of window so it doesn't spaz
-; [] fill screen right away
-; [] history breaks when heavily used? (disk swaping?)
;
; [] a triangle rendered for a few frames? color of the dirty markers (not reproduced by me yet)
-; [] minimize and reopen problem (not reproduced by me yet)
;
;