upgraded 4coder_casey.cpp, misc tweaks
parent
e02ab24488
commit
1634a65b17
|
@ -159,7 +159,7 @@ CUSTOM_COMMAND_SIG(newline_or_goto_position){
|
|||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessProtected);
|
||||
|
||||
if (buffer.lock_flags & AccessProtected){
|
||||
exec_command(app, goto_postion_at_cursor);
|
||||
exec_command(app, goto_jump_at_cursor);
|
||||
}
|
||||
else{
|
||||
exec_command(app, write_character);
|
||||
|
@ -201,25 +201,6 @@ OPEN_FILE_HOOK_SIG(my_file_settings){
|
|||
return(0);
|
||||
}
|
||||
|
||||
// NOTE(allen|a4.0.9): All command calls can now go through this hook
|
||||
// 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);
|
||||
|
||||
view_paste_index[view.view_id].next_rewrite = false;
|
||||
|
||||
exec_command(app, cmd);
|
||||
|
||||
view_paste_index[view.view_id].rewrite =
|
||||
view_paste_index[view.view_id].next_rewrite;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// NOTE(allen|a4.0.9): The input filter allows you to modify the input
|
||||
// to a frame before 4coder starts processing it at all.
|
||||
//
|
||||
|
@ -403,7 +384,6 @@ 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);
|
||||
|
||||
|
@ -428,7 +408,7 @@ get_bindings(void *data, int size){
|
|||
set_hook(context, hook_start, my_start);
|
||||
|
||||
set_open_file_hook(context, my_file_settings);
|
||||
set_command_caller(context, my_command_caller);
|
||||
set_command_caller(context, default_command_caller);
|
||||
set_input_filter(context, my_suppress_mouse_filter);
|
||||
set_scroll_rule(context, smooth_scroll_rule);
|
||||
|
||||
|
|
|
@ -8,20 +8,12 @@
|
|||
#include "4coder_string.h"
|
||||
|
||||
#include "4coder_helper.h"
|
||||
|
||||
#include "4coder_jump_parsing.cpp"
|
||||
|
||||
//
|
||||
// Basic Build Behavior
|
||||
//
|
||||
|
||||
struct Prev_Jump{
|
||||
int buffer_id;
|
||||
int line;
|
||||
};
|
||||
|
||||
static Prev_Jump null_location = {0};
|
||||
static Prev_Jump prev_location = {0};
|
||||
|
||||
CUSTOM_COMMAND_SIG(build_in_build_panel){
|
||||
Buffer_Summary buffer =
|
||||
app->get_buffer_by_name(app, literal("*compilation*"), AccessAll);
|
||||
|
@ -181,319 +173,5 @@ CUSTOM_COMMAND_SIG(open_in_other_build){
|
|||
# define open_in_other open_in_other_build
|
||||
#endif
|
||||
|
||||
//
|
||||
// Jump to Error
|
||||
//
|
||||
|
||||
struct Jump_Location{
|
||||
String file;
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
|
||||
static void
|
||||
jump_to_location(Application_Links *app, View_Summary *view, Jump_Location *l){
|
||||
view_open_file(app, view, l->file.str, l->file.size, false);
|
||||
app->view_set_cursor(app, view, seek_line_char(l->line, l->column), true);
|
||||
}
|
||||
|
||||
static int
|
||||
gcc_style_verify(String line, int colon_pos){
|
||||
int result = false;
|
||||
if (colon_pos < line.size){
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
ms_style_verify(String line, int paren_pos){
|
||||
int result = false;
|
||||
|
||||
String line_part = substr(line, paren_pos);
|
||||
if (match_part(line_part, ") : error")){
|
||||
result = true;
|
||||
}
|
||||
else if (match_part(line_part, ") : warning")){
|
||||
result = true;
|
||||
}
|
||||
else if (match_part(line_part, ") : error")){
|
||||
result = true;
|
||||
}
|
||||
else if (match_part(line_part, ") : warning")){
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_error(String line, Jump_Location *location,
|
||||
int skip_sub_errors, int *colon_char){
|
||||
int result = false;
|
||||
|
||||
int colon_pos = find(line, 0, ')');
|
||||
if (ms_style_verify(line, colon_pos)){
|
||||
colon_pos = find(line, colon_pos, ':');
|
||||
if (colon_pos < line.size){
|
||||
String location_str = substr(line, 0, colon_pos);
|
||||
|
||||
if (!(skip_sub_errors && location_str.str[0] == ' ')){
|
||||
location_str = skip_chop_whitespace(location_str);
|
||||
|
||||
int paren_pos = find(location_str, 0, '(');
|
||||
if (paren_pos < location_str.size){
|
||||
String file = substr(location_str, 0, paren_pos);
|
||||
file = skip_chop_whitespace(file);
|
||||
|
||||
int close_pos = find(location_str, 0, ')') + 1;
|
||||
if (close_pos == location_str.size && file.size > 0){
|
||||
String line_number = substr(location_str,
|
||||
paren_pos+1,
|
||||
close_pos-paren_pos-2);
|
||||
line_number = skip_chop_whitespace(line_number);
|
||||
|
||||
|
||||
if (line_number.size > 0){
|
||||
//copy(&location->file, file);
|
||||
location->file = file;
|
||||
|
||||
int comma_pos = find(line_number, 0, ',');
|
||||
if (comma_pos < line_number.size){
|
||||
int start = comma_pos+1;
|
||||
String column_number = substr(line_number, start, line_number.size-start);
|
||||
line_number = substr(line_number, 0, comma_pos);
|
||||
|
||||
location->line = str_to_int(line_number);
|
||||
location->column = str_to_int(column_number);
|
||||
}
|
||||
else{
|
||||
location->line = str_to_int(line_number);
|
||||
location->column = 1;
|
||||
}
|
||||
|
||||
*colon_char = colon_pos;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else{
|
||||
int colon_pos1 = find(line, 0, ':');
|
||||
if (colon_pos1 == 1){
|
||||
if (line.size > colon_pos1+1){
|
||||
if (char_is_slash(line.str[colon_pos1+1])){
|
||||
colon_pos1 = find(line, colon_pos1+1, ':');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
String column_number = substr(line, colon_pos2+1, colon_pos3 - colon_pos2 - 1);
|
||||
|
||||
if (filename.size > 0 &&
|
||||
line_number.size > 0 &&
|
||||
column_number.size > 0){
|
||||
//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);
|
||||
}
|
||||
|
||||
static int
|
||||
next_error(Application_Links *app,
|
||||
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 = {0};
|
||||
Buffer_Summary buffer = app->get_buffer(app, comp_out->buffer_id, AccessAll);
|
||||
for (;;){
|
||||
if (read_line(app, part, &buffer, line, &line_str)){
|
||||
if (parse_error(line_str, location, skip_sub_errors, colon_char)){
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
line += direction;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (line < 0){
|
||||
line = 0;
|
||||
}
|
||||
|
||||
*start_line = line;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
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);
|
||||
|
||||
Jump_Location location = {0};
|
||||
Buffer_Summary buffer = app->get_buffer_by_name(app, literal("*compilation*"), AccessAll);
|
||||
if (buffer.exists){
|
||||
View_Summary view = get_first_view_with_buffer(app, buffer.buffer_id);
|
||||
int line = view.cursor.line;
|
||||
|
||||
int colon_char = 0;
|
||||
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);
|
||||
result = true;
|
||||
if (loc){
|
||||
*loc = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Prev_Jump
|
||||
jump_location_store(Application_Links *app, Jump_Location loc){
|
||||
Prev_Jump result = {0};
|
||||
Buffer_Summary buffer =
|
||||
app->get_buffer_by_name(app, loc.file.str, loc.file.size, AccessAll);
|
||||
|
||||
if (buffer.exists){
|
||||
result.buffer_id = buffer.buffer_id;
|
||||
result.line = loc.line;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
skip_this_jump(Prev_Jump prev, Prev_Jump jump){
|
||||
int result = false;
|
||||
if (prev.buffer_id != 0 && prev.buffer_id == jump.buffer_id &&
|
||||
prev.line == jump.line){
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(goto_next_error){
|
||||
Temp_Memory temp = begin_temp_memory(&global_part);
|
||||
Jump_Location location = {0};
|
||||
Prev_Jump jump = {0};
|
||||
do{
|
||||
if (seek_error(app, &global_part, true, 1, &location)){
|
||||
jump = jump_location_store(app, location);
|
||||
}
|
||||
else{
|
||||
jump.buffer_id = 0;
|
||||
}
|
||||
}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 (seek_error(app, &global_part, true, -1, &location)){
|
||||
jump = jump_location_store(app, location);
|
||||
}
|
||||
else{
|
||||
jump.buffer_id = 0;
|
||||
}
|
||||
}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 = {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
|
||||
|
||||
|
|
|
@ -1901,6 +1901,9 @@ CUSTOM_COMMAND_SIG(write_and_auto_tab){
|
|||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(clean_all_lines){
|
||||
// TODO(allen): This command always iterates accross the entire
|
||||
// buffer, so streaming it is actually the wrong call. Rewrite this
|
||||
// to minimize calls to app->buffer_read_range.
|
||||
View_Summary view = app->get_active_view(app, AccessOpen);
|
||||
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessOpen);
|
||||
|
||||
|
@ -1931,8 +1934,8 @@ CUSTOM_COMMAND_SIG(clean_all_lines){
|
|||
edit->start = last_hard+1;
|
||||
edit->end = i;
|
||||
++edit;
|
||||
last_hard = buffer_size;
|
||||
}
|
||||
last_hard = buffer_size;
|
||||
}
|
||||
else if (char_is_whitespace(at_pos)){
|
||||
// NOTE(allen): do nothing
|
||||
|
@ -2261,6 +2264,7 @@ CUSTOM_COMMAND_SIG(list_all_locations){
|
|||
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);
|
||||
app->buffer_set_setting(app, &search_buffer, BufferSetting_WrapLine, false);
|
||||
}
|
||||
else{
|
||||
app->buffer_replace_range(app, &search_buffer, 0, search_buffer.size, 0, 0);
|
||||
|
@ -2624,4 +2628,23 @@ SCROLL_RULE_SIG(smooth_scroll_rule){
|
|||
return(result);
|
||||
}
|
||||
|
||||
// NOTE(allen|a4.0.9): All command calls can now go through this hook
|
||||
// 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(default_command_caller){
|
||||
View_Summary view = app->get_active_view(app, AccessAll);
|
||||
|
||||
view_paste_index[view.view_id].next_rewrite = false;
|
||||
|
||||
exec_command(app, cmd);
|
||||
|
||||
view_paste_index[view.view_id].rewrite =
|
||||
view_paste_index[view.view_id].next_rewrite;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,325 @@
|
|||
|
||||
#ifndef FCODER_JUMP_PARSING
|
||||
#define FCODER_JUMP_PARSING
|
||||
|
||||
struct Jump_Location{
|
||||
String file;
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
|
||||
static void
|
||||
jump_to_location(Application_Links *app, View_Summary *view, Jump_Location *l){
|
||||
view_open_file(app, view, l->file.str, l->file.size, false);
|
||||
app->view_set_cursor(app, view, seek_line_char(l->line, l->column), true);
|
||||
}
|
||||
|
||||
static int
|
||||
gcc_style_verify(String line, int colon_pos){
|
||||
int result = false;
|
||||
if (colon_pos < line.size){
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
ms_style_verify(String line, int paren_pos){
|
||||
int result = false;
|
||||
|
||||
String line_part = substr(line, paren_pos);
|
||||
if (match_part(line_part, ") : ")){
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_error(String line, Jump_Location *location,
|
||||
int skip_sub_errors, int *colon_char){
|
||||
int result = false;
|
||||
|
||||
int colon_pos = find(line, 0, ')');
|
||||
if (ms_style_verify(line, colon_pos)){
|
||||
colon_pos = find(line, colon_pos, ':');
|
||||
if (colon_pos < line.size){
|
||||
String location_str = substr(line, 0, colon_pos);
|
||||
|
||||
if (!(skip_sub_errors && location_str.str[0] == ' ')){
|
||||
location_str = skip_chop_whitespace(location_str);
|
||||
|
||||
int paren_pos = find(location_str, 0, '(');
|
||||
if (paren_pos < location_str.size){
|
||||
String file = substr(location_str, 0, paren_pos);
|
||||
file = skip_chop_whitespace(file);
|
||||
|
||||
int close_pos = find(location_str, 0, ')') + 1;
|
||||
if (close_pos == location_str.size && file.size > 0){
|
||||
String line_number = substr(location_str,
|
||||
paren_pos+1,
|
||||
close_pos-paren_pos-2);
|
||||
line_number = skip_chop_whitespace(line_number);
|
||||
|
||||
|
||||
if (line_number.size > 0){
|
||||
//copy(&location->file, file);
|
||||
location->file = file;
|
||||
|
||||
int comma_pos = find(line_number, 0, ',');
|
||||
if (comma_pos < line_number.size){
|
||||
int start = comma_pos+1;
|
||||
String column_number = substr(line_number, start, line_number.size-start);
|
||||
line_number = substr(line_number, 0, comma_pos);
|
||||
|
||||
location->line = str_to_int(line_number);
|
||||
location->column = str_to_int(column_number);
|
||||
}
|
||||
else{
|
||||
location->line = str_to_int(line_number);
|
||||
location->column = 1;
|
||||
}
|
||||
|
||||
*colon_char = colon_pos;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else{
|
||||
int colon_pos1 = find(line, 0, ':');
|
||||
if (colon_pos1 == 1){
|
||||
if (line.size > colon_pos1+1){
|
||||
if (char_is_slash(line.str[colon_pos1+1])){
|
||||
colon_pos1 = find(line, colon_pos1+1, ':');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
String column_number = substr(line, colon_pos2+1, colon_pos3 - colon_pos2 - 1);
|
||||
|
||||
if (filename.size > 0 &&
|
||||
line_number.size > 0 &&
|
||||
column_number.size > 0){
|
||||
//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);
|
||||
}
|
||||
|
||||
static int
|
||||
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);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(goto_jump_at_cursor){
|
||||
Temp_Memory temp = begin_temp_memory(&global_part);
|
||||
View_Summary view = app->get_active_view(app, AccessProtected);
|
||||
|
||||
Jump_Location location = {0};
|
||||
if (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);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Error Jumping
|
||||
//
|
||||
|
||||
struct Prev_Jump{
|
||||
int buffer_id;
|
||||
int line;
|
||||
};
|
||||
|
||||
static Prev_Jump null_location = {0};
|
||||
static Prev_Jump prev_location = {0};
|
||||
|
||||
static int
|
||||
next_error(Application_Links *app,
|
||||
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 = {0};
|
||||
Buffer_Summary buffer = app->get_buffer(app, comp_out->buffer_id, AccessAll);
|
||||
for (;;){
|
||||
if (read_line(app, part, &buffer, line, &line_str)){
|
||||
if (parse_error(line_str, location, skip_sub_errors, colon_char)){
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
line += direction;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (line < 0){
|
||||
line = 0;
|
||||
}
|
||||
|
||||
*start_line = line;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
seek_error(Application_Links *app, Partition *part, int direction, int skip_sub_errors, Jump_Location *loc){
|
||||
int result = false;
|
||||
|
||||
Jump_Location location = {0};
|
||||
Buffer_Summary buffer = app->get_buffer_by_name(app, literal("*compilation*"), AccessAll);
|
||||
if (buffer.exists){
|
||||
View_Summary view = get_first_view_with_buffer(app, buffer.buffer_id);
|
||||
int line = view.cursor.line;
|
||||
|
||||
int colon_char = 0;
|
||||
if (next_error(app, part, &view, &line, &location,
|
||||
skip_sub_errors, direction, &colon_char)){
|
||||
|
||||
View_Summary active_view = app->get_active_view(app, AccessAll);
|
||||
if (active_view.view_id == view.view_id){
|
||||
exec_command(app, change_active_panel_regular);
|
||||
active_view = app->get_active_view(app, AccessAll);
|
||||
}
|
||||
|
||||
jump_to_location(app, &active_view, &location);
|
||||
app->view_set_cursor(app, &view, seek_line_char(line, colon_char+1), true);
|
||||
result = true;
|
||||
if (loc){
|
||||
*loc = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Prev_Jump
|
||||
jump_location_store(Application_Links *app, Jump_Location loc){
|
||||
Prev_Jump result = {0};
|
||||
Buffer_Summary buffer =
|
||||
app->get_buffer_by_name(app, loc.file.str, loc.file.size, AccessAll);
|
||||
|
||||
if (buffer.exists){
|
||||
result.buffer_id = buffer.buffer_id;
|
||||
result.line = loc.line;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
skip_this_jump(Prev_Jump prev, Prev_Jump jump){
|
||||
int result = false;
|
||||
if (prev.buffer_id != 0 && prev.buffer_id == jump.buffer_id &&
|
||||
prev.line == jump.line){
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int
|
||||
seek_error_skip_repeats(Application_Links *app, Partition *part,
|
||||
int skip_sub_error, int dir){
|
||||
int result = true;
|
||||
Jump_Location location = {0};
|
||||
Prev_Jump jump = {0};
|
||||
do{
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
if (seek_error(app, part, skip_sub_error, dir, &location)){
|
||||
jump = jump_location_store(app, location);
|
||||
result = true;
|
||||
}
|
||||
else{
|
||||
jump.buffer_id = 0;
|
||||
result = false;
|
||||
}
|
||||
end_temp_memory(temp);
|
||||
}while(skip_this_jump(prev_location, jump));
|
||||
prev_location = jump;
|
||||
return(result);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(goto_next_error){
|
||||
seek_error_skip_repeats(app, &global_part, true, 1);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(goto_prev_error){
|
||||
seek_error_skip_repeats(app, &global_part, true, -1);
|
||||
}
|
||||
|
||||
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 = {0};
|
||||
seek_error(app, &global_part, true, 1, &location);
|
||||
prev_location = jump_location_store(app, location);
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
2
4ed.cpp
2
4ed.cpp
|
@ -262,7 +262,7 @@ panel_make_empty(System_Functions *system, App_Vars *vars, Panel *panel){
|
|||
Assert(panel->view == 0);
|
||||
new_view = live_set_alloc_view(&vars->live_set, panel, models);
|
||||
view_set_file(new_view.view, models->scratch_buffer, models);
|
||||
new_view.view->map = get_map(models, mapid_global);
|
||||
new_view.view->map = get_map(models, mapid_file);
|
||||
|
||||
return(new_view.view);
|
||||
}
|
||||
|
|
37
TODO.txt
37
TODO.txt
|
@ -100,19 +100,21 @@
|
|||
; [X] feedback message API
|
||||
; [X] kill rect
|
||||
; [X] add high DPI support
|
||||
;
|
||||
; [] generate documentation for custom API
|
||||
; [X] error parsing and jump to error
|
||||
; [X] manipulate scroll target API
|
||||
; [X] generate documentation for custom API
|
||||
;
|
||||
; [] OS font rendering
|
||||
; [] support full length unicode file names
|
||||
; [] switch based word complete
|
||||
;
|
||||
; [] undo groups
|
||||
; [] cursor/scroll grouping
|
||||
; [] file status in custom API
|
||||
; [] user file bar string
|
||||
; [] simple multi-line editing
|
||||
; [] allow for arbitrary wrap positions independent of view width
|
||||
; [] word level wrapping ~ temporary measure really want to have totally formatted code
|
||||
; [] manipulate scroll target API
|
||||
; [] error parsing and jump to error
|
||||
; [] additional hooks
|
||||
; [X] new file
|
||||
; [] file out of sync
|
||||
|
@ -127,9 +129,10 @@
|
|||
; search related tech
|
||||
; [X] replace word (incremental and/or in range)
|
||||
; [X] caps insensitivety
|
||||
; [X] improved custom API for text "streams"
|
||||
; [X] wave search
|
||||
; [] optimize search
|
||||
; [] allow search wrap around beginning/end
|
||||
; [] improved custom API for text "streams"
|
||||
; [] smarter isearch behavior
|
||||
;
|
||||
; theme related business
|
||||
; [] fix the versioning system for themes
|
||||
|
@ -146,12 +149,12 @@
|
|||
;
|
||||
; code engine
|
||||
; [X] lexer with multiple chunk input
|
||||
; [X] more correct auto-indentation
|
||||
; [] switch over to gap buffer
|
||||
; [] more correct auto-indentation
|
||||
; [] preprocessor
|
||||
; [] AST generator
|
||||
;
|
||||
; [] cuber's return to previous buffer idea
|
||||
; [X] cuber's return to previous buffer idea
|
||||
; [] miblo's various number editors
|
||||
;
|
||||
; [] keep copy of unedited orignal, somewhere (compressed? restore by history?)
|
||||
|
@ -161,7 +164,6 @@
|
|||
; [] regex
|
||||
; [] explicit panel layout
|
||||
; [] polish for hot directories
|
||||
; [] undo groups
|
||||
;
|
||||
; "virtual text"
|
||||
; [] line numbers
|
||||
|
@ -222,14 +224,13 @@
|
|||
; [X] window size and position / full screen
|
||||
; [X] file(s) to open initially
|
||||
; [X] position in file to open
|
||||
; [X] invoking special tools
|
||||
; [X] transition Win32 layer to using system_shared stuff
|
||||
; [X] event driven file synchronization
|
||||
; [] user settings file
|
||||
; [] system fonts
|
||||
; [] file drag and drop
|
||||
; [] low latency stuff
|
||||
; [] actually write the port
|
||||
; [X] actually write the port
|
||||
; [X] 4coder code compiling
|
||||
; [X] opengl window up
|
||||
; [X] basic versions of system functions
|
||||
|
@ -243,5 +244,19 @@
|
|||
; [] system fonts
|
||||
; [] file drag and drop
|
||||
; [] allow for multiple clipboards
|
||||
; [] OS X port
|
||||
; [] 4coder code compiling
|
||||
; [] opengl window up
|
||||
; [] basic versions of system functions
|
||||
; [] get 4coder to render to window
|
||||
; [] keyboard and mouse input
|
||||
; [] file exchange
|
||||
; [] clipboard
|
||||
; [] background threads
|
||||
; [] cli stuff
|
||||
; [] event diven file synchronization
|
||||
; [] system fonts
|
||||
; [] file drag and drop
|
||||
; [] allow for multiple clipboards
|
||||
;
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "4coder_default_include.cpp"
|
||||
#include "4coder_jump_parsing.cpp"
|
||||
|
||||
#ifndef Assert
|
||||
#define internal static
|
||||
|
@ -360,15 +361,27 @@ CUSTOM_COMMAND_SIG(casey_open_in_other)
|
|||
|
||||
CUSTOM_COMMAND_SIG(casey_clean_and_save)
|
||||
{
|
||||
exec_command(app, cmdid_clean_all_lines);
|
||||
exec_command(app, clean_all_lines);
|
||||
exec_command(app, eol_nixify);
|
||||
exec_command(app, cmdid_save);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_newline_and_indent)
|
||||
{
|
||||
exec_command(app, write_character);
|
||||
exec_command(app, auto_tab_line_at_cursor);
|
||||
// NOTE(allen): The idea here is that if the current buffer is
|
||||
// read-only, it cannot be edited anyway. So instead let the return
|
||||
// key indicate an attempt to interpret the line as a location to jump to.
|
||||
|
||||
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_jump_at_cursor);
|
||||
}
|
||||
else{
|
||||
exec_command(app, write_character);
|
||||
exec_command(app, auto_tab_line_at_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_open_file_other_window)
|
||||
|
@ -539,6 +552,12 @@ CUSTOM_COMMAND_SIG(casey_build_search)
|
|||
memcpy(BuildDirectory, dir.str, dir.size);
|
||||
BuildDirectory[dir.size] = 0;
|
||||
|
||||
// TODO(allen): There are ways this could be boiled down
|
||||
// to one print message which would be better.
|
||||
app->print_message(app, literal("Building with: "));
|
||||
app->print_message(app, BuildDirectory, dir.size);
|
||||
app->print_message(app, literal("build.bat\n"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -547,10 +566,9 @@ CUSTOM_COMMAND_SIG(casey_build_search)
|
|||
if (app->directory_cd(app, dir.str, &dir.size, dir.memory_size, literal("..")) == 0)
|
||||
{
|
||||
keep_going = 0;
|
||||
app->print_message(app, literal("Did not find a build.bat\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(casey): How do I print out that it found or didn't find something?
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_find_corresponding_file)
|
||||
|
@ -625,9 +643,9 @@ CUSTOM_COMMAND_SIG(casey_find_corresponding_file_other_window)
|
|||
CUSTOM_COMMAND_SIG(casey_save_and_make_without_asking)
|
||||
{
|
||||
exec_command(app, change_active_panel);
|
||||
|
||||
|
||||
Buffer_Summary buffer = {};
|
||||
|
||||
|
||||
unsigned int access = AccessAll;
|
||||
for(buffer = app->get_buffer_first(app, access);
|
||||
buffer.exists;
|
||||
|
@ -671,6 +689,7 @@ CUSTOM_COMMAND_SIG(casey_save_and_make_without_asking)
|
|||
exec_command(app, change_active_panel);
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal bool
|
||||
casey_errors_are_the_same(Parsed_Error a, Parsed_Error b)
|
||||
{
|
||||
|
@ -818,15 +837,18 @@ casey_seek_error_dy(Application_Links *app, int dy)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_goto_previous_error)
|
||||
{
|
||||
casey_seek_error_dy(app, -1);
|
||||
// casey_seek_error_dy(app, -1);
|
||||
seek_error_skip_repeats(app, &global_part, false, -1);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_goto_next_error)
|
||||
{
|
||||
casey_seek_error_dy(app, 1);
|
||||
// casey_seek_error_dy(app, 1);
|
||||
seek_error_skip_repeats(app, &global_part, false, 1);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(casey_imenu)
|
||||
|
@ -1202,12 +1224,10 @@ CUSTOM_COMMAND_SIG(binding_name) \
|
|||
#define DEFINE_BIMODAL_KEY(binding_name,edit_code,normal_code) DEFINE_FULL_BIMODAL_KEY(binding_name,exec_command(app,edit_code),exec_command(app,normal_code))
|
||||
#define DEFINE_MODAL_KEY(binding_name,edit_code) DEFINE_BIMODAL_KEY(binding_name,edit_code,write_character)
|
||||
|
||||
// cmdid_paste_next ?
|
||||
// cmdid_timeline_scrub ?
|
||||
// paste_next ?
|
||||
// cmdid_history_backward,
|
||||
// cmdid_history_forward,
|
||||
// cmdid_toggle_line_wrap,
|
||||
// cmdid_close_minor_view,
|
||||
// toggle_line_wrap,
|
||||
|
||||
DEFINE_MODAL_KEY(modal_space, set_mark);
|
||||
DEFINE_MODAL_KEY(modal_back_slash, casey_clean_and_save);
|
||||
|
@ -1222,7 +1242,7 @@ DEFINE_MODAL_KEY(modal_a, write_character); // TODO(casey): Arbitrary command +
|
|||
DEFINE_MODAL_KEY(modal_b, cmdid_interactive_switch_buffer);
|
||||
DEFINE_MODAL_KEY(modal_c, casey_find_corresponding_file);
|
||||
DEFINE_MODAL_KEY(modal_d, casey_kill_to_end_of_line);
|
||||
DEFINE_MODAL_KEY(modal_e, write_character); // TODO(casey): Available
|
||||
DEFINE_MODAL_KEY(modal_e, list_all_locations); // TODO(casey): Available // NOTE(allen): I put list_all_locations here for testing.
|
||||
DEFINE_MODAL_KEY(modal_f, casey_paste_and_tab);
|
||||
DEFINE_MODAL_KEY(modal_g, goto_line);
|
||||
DEFINE_MODAL_KEY(modal_h, auto_tab_range);
|
||||
|
@ -1235,7 +1255,7 @@ DEFINE_MODAL_KEY(modal_n, casey_goto_next_error);
|
|||
DEFINE_MODAL_KEY(modal_o, query_replace);
|
||||
DEFINE_MODAL_KEY(modal_p, replace_in_range);
|
||||
DEFINE_MODAL_KEY(modal_q, copy);
|
||||
DEFINE_MODAL_KEY(modal_r, reverse_search); // NOTE(allen): I've modified my default search so you can use it now.
|
||||
DEFINE_MODAL_KEY(modal_r, reverse_search);
|
||||
DEFINE_MODAL_KEY(modal_s, search);
|
||||
DEFINE_MODAL_KEY(modal_t, casey_load_todo);
|
||||
DEFINE_MODAL_KEY(modal_u, cmdid_undo);
|
||||
|
@ -1268,7 +1288,7 @@ DEFINE_BIMODAL_KEY(modal_home, casey_seek_beginning_of_line, casey_seek_beginnin
|
|||
DEFINE_BIMODAL_KEY(modal_end, seek_end_of_line, seek_end_of_line);
|
||||
DEFINE_BIMODAL_KEY(modal_page_up, page_up, seek_whitespace_up);
|
||||
DEFINE_BIMODAL_KEY(modal_page_down, page_down, seek_whitespace_down);
|
||||
DEFINE_BIMODAL_KEY(modal_tab, cmdid_word_complete, cmdid_word_complete);
|
||||
DEFINE_BIMODAL_KEY(modal_tab, word_complete, word_complete);
|
||||
|
||||
OPEN_FILE_HOOK_SIG(casey_file_settings)
|
||||
{
|
||||
|
@ -1352,7 +1372,7 @@ struct Casey_Scroll_Velocity
|
|||
};
|
||||
|
||||
Casey_Scroll_Velocity casey_scroll_velocity_[16] = {0};
|
||||
Casey_Scroll_Velocity *casey_scroll_velocity = casey_scroll_velocity_;
|
||||
Casey_Scroll_Velocity *casey_scroll_velocity = casey_scroll_velocity_ - 1;
|
||||
|
||||
SCROLL_RULE_SIG(casey_smooth_scroll_rule){
|
||||
Casey_Scroll_Velocity *velocity = casey_scroll_velocity + view_id;
|
||||
|
@ -1442,6 +1462,12 @@ win32_toggle_fullscreen(void)
|
|||
|
||||
HOOK_SIG(casey_start)
|
||||
{
|
||||
// NOTE(allen): This initializes a couple of global memory
|
||||
// management structs on the custom side that are used in
|
||||
// some of the new 4coder features including building and
|
||||
// custom-side word complete.
|
||||
init_memory(app);
|
||||
|
||||
exec_command(app, hide_scrollbar);
|
||||
exec_command(app, open_panel_vsplit);
|
||||
exec_command(app, hide_scrollbar);
|
||||
|
@ -1495,6 +1521,7 @@ extern "C" GET_BINDING_DATA(get_bindings)
|
|||
Bind_Helper *context = &context_actual;
|
||||
|
||||
set_hook(context, hook_start, casey_start);
|
||||
set_command_caller(context, default_command_caller);
|
||||
set_open_file_hook(context, casey_file_settings);
|
||||
set_scroll_rule(context, casey_smooth_scroll_rule);
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ get_bindings(void *data, int size){
|
|||
set_hook(context, hook_start, experimental_start_hook);
|
||||
set_open_file_hook(context, my_file_settings);
|
||||
set_input_filter(context, my_suppress_mouse_filter);
|
||||
set_command_caller(context, my_command_caller);
|
||||
set_command_caller(context, default_command_caller);
|
||||
|
||||
set_scroll_rule(context, smooth_scroll_rule);
|
||||
|
||||
|
|
Loading…
Reference in New Issue