commands run in coroutines

This commit is contained in:
Allen Webster 2016-02-26 12:40:51 -05:00
parent 19e7c96c55
commit 0fe6447102
15 changed files with 747 additions and 702 deletions

View File

@ -12,14 +12,25 @@
#ifndef FRED_BUFFER_TYPES_H
#define FRED_BUFFER_TYPES_H
typedef union Range{
struct{
int min, max;
};
struct{
int start, end;
};
} Range;
typedef unsigned char Code;
typedef enum{
MDFR_SHIFT_INDEX,
MDFR_CONTROL_INDEX,
MDFR_ALT_INDEX,
MDFR_CAPS_INDEX,
// always last
MDFR_INDEX_COUNT
} Key_Control;
typedef struct Key_Event_Data{
Code keycode;
Code character;
Code character_no_caps_lock;
char modifiers[MDFR_INDEX_COUNT];
} Key_Event_Data;
typedef struct Full_Cursor{
int pos;
@ -91,6 +102,97 @@ seek_line_char(int line, int character){
return(result);
}
typedef union Range{
struct{
int min, max;
};
struct{
int start, end;
};
} Range;
inline Range
make_range(int p1, int p2){
Range range;
if (p1 < p2){
range.min = p1;
range.max = p2;
}
else{
range.max = p2;
range.min = p1;
}
return(range);
}
enum Dynamic_Type{
dynamic_type_int,
dynamic_type_string,
// never below this
dynamic_type_count
};
struct Dynamic{
int type;
union{
struct{
int str_len;
char *str_value;
};
int int_value;
};
};
inline Dynamic
dynamic_int(int x){
Dynamic result;
result.type = dynamic_type_int;
result.int_value = x;
return result;
}
inline Dynamic
dynamic_string(const char *string, int len){
Dynamic result;
result.type = dynamic_type_string;
result.str_len = len;
result.str_value = (char*)(string);
return result;
}
inline int
dynamic_to_int(Dynamic *dynamic){
int result = 0;
if (dynamic->type == dynamic_type_int){
result = dynamic->int_value;
}
return result;
}
inline char*
dynamic_to_string(Dynamic *dynamic, int *len){
char *result = 0;
if (dynamic->type == dynamic_type_string){
result = dynamic->str_value;
*len = dynamic->str_len;
}
return result;
}
inline int
dynamic_to_bool(Dynamic *dynamic){
int result = 0;
if (dynamic->type == dynamic_type_int){
result = (dynamic->int_value != 0);
}
else{
result = 1;
}
return result;
}
#endif
// BOTTOM

View File

@ -85,14 +85,14 @@ CUSTOM_COMMAND_SIG(write_increment){
char text[] = "++";
int size = sizeof(text) - 1;
Buffer_Summary buffer = app->get_active_buffer(app);
app->buffer_replace_range(app, &buffer, buffer.file_cursor_pos, buffer.file_cursor_pos, text, size);
app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, text, size);
}
CUSTOM_COMMAND_SIG(write_decrement){
char text[] = "--";
int size = sizeof(text) - 1;
Buffer_Summary buffer = app->get_active_buffer(app);
app->buffer_replace_range(app, &buffer, buffer.file_cursor_pos, buffer.file_cursor_pos, text, size);
app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, text, size);
}
CUSTOM_COMMAND_SIG(open_long_braces){
@ -103,12 +103,11 @@ CUSTOM_COMMAND_SIG(open_long_braces){
int pos;
view = app->get_active_file_view(app);
buffer = app->get_buffer(app, view.file_id);
buffer = app->get_buffer(app, view.buffer_id);
pos = view.cursor.pos;
app->buffer_replace_range(app, &buffer, pos, pos, text, size);
app->view_set_cursor(app, &view, seek_pos(pos + 2), 1);
app->view_set_mark(app, &view, seek_pos(pos + 4));
push_parameter(app, par_range_start, pos);
push_parameter(app, par_range_end, pos + size);
@ -116,7 +115,27 @@ CUSTOM_COMMAND_SIG(open_long_braces){
exec_command(app, cmdid_auto_tab_range);
}
CUSTOM_COMMAND_SIG(ifdef_off){
CUSTOM_COMMAND_SIG(open_long_braces_semicolon){
File_View_Summary view;
Buffer_Summary buffer;
char text[] = "{\n\n};";
int size = sizeof(text) - 1;
int pos;
view = app->get_active_file_view(app);
buffer = app->get_buffer(app, view.buffer_id);
pos = view.cursor.pos;
app->buffer_replace_range(app, &buffer, pos, pos, text, size);
app->view_set_cursor(app, &view, seek_pos(pos + 2), 1);
push_parameter(app, par_range_start, pos);
push_parameter(app, par_range_end, pos + size);
push_parameter(app, par_clear_blank_lines, 0);
exec_command(app, cmdid_auto_tab_range);
}
CUSTOM_COMMAND_SIG(if0_off){
File_View_Summary view;
Buffer_Summary buffer;
@ -164,7 +183,7 @@ CUSTOM_COMMAND_SIG(backspace_word){
app->refresh_file_view(app, &view);
pos1 = view.cursor.pos;
buffer = app->get_buffer(app, view.file_id);
buffer = app->get_buffer(app, view.buffer_id);
app->buffer_replace_range(app, &buffer, pos1, pos2, 0, 0);
}
@ -182,7 +201,7 @@ CUSTOM_COMMAND_SIG(switch_to_compilation){
view = app->get_active_file_view(app);
buffer = app->get_buffer_by_name(app, make_string(name, name_size));
app->view_set_file(app, &view, buffer.file_id);
app->view_set_buffer(app, &view, buffer.buffer_id);
}
CUSTOM_COMMAND_SIG(move_up_10){
@ -231,7 +250,7 @@ CUSTOM_COMMAND_SIG(switch_to_file_in_quotes){
view = app->get_active_file_view(app);
if (view.exists){
buffer = app->get_buffer(app, view.file_id);
buffer = app->get_buffer(app, view.buffer_id);
if (buffer.ready){
pos = view.cursor.pos;
app->buffer_seek_delimiter(app, &buffer, pos, '"', 1, &end);
@ -250,19 +269,34 @@ CUSTOM_COMMAND_SIG(switch_to_file_in_quotes){
truncate_to_path_of_directory(&file_name);
append(&file_name, make_string(short_file_name, size));
buffer = app->get_buffer_by_name(app, file_name);
exec_command(app, cmdid_change_active_panel);
view = app->get_active_file_view(app);
if (buffer.exists){
app->view_set_file(app, &view, buffer.file_id);
}
else{
push_parameter(app, par_name, expand_str(file_name));
exec_command(app, cmdid_interactive_open);
}
}
}
}
CUSTOM_COMMAND_SIG(goto_line){
User_Input in;
Query bar;
int line_number = 0;
in = {};
bar = app->create_query(app, make_lit_string("Line Number: "), QueryBar);
while (1){
in = app->get_user_input(app, AbortOnEsc | AbortOnClick);
if (in.abort) break;
if (in.key.character >= '0' && in.key.character <= '9' || in.key.character == 0){
app->update_query(app, &bar, in.key);
if (bar.complete) break;
}
}
app->close_query(app, &bar);
if (in.abort) return;
line_number = str_to_int(bar.string);
active_view_to_line(app, line_number);
}
CUSTOM_COMMAND_SIG(open_in_other){
@ -432,7 +466,8 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, '=', MDFR_CTRL, write_increment);
bind(context, '-', MDFR_CTRL, write_decrement);
bind(context, '[', MDFR_CTRL, open_long_braces);
bind(context, 'i', MDFR_ALT, ifdef_off);
bind(context, '{', MDFR_CTRL, open_long_braces);
bind(context, 'i', MDFR_ALT, if0_off);
bind(context, '1', MDFR_ALT, switch_to_file_in_quotes);
end_map(context);
@ -440,10 +475,10 @@ extern "C" GET_BINDING_DATA(get_bindings){
begin_map(context, mapid_file);
// NOTE(allen|a3.1): Binding this essentially binds all key combos that
// NOTE(allen|a3.4.4): Binding this essentially binds all key combos that
// would normally insert a character into a buffer.
// Or apply this rule (which always works): if the code for the key
// is not in the codes struct, it is a vanilla key.
// Or apply this rule: if the code for the key is not an enum value
// such as key_left or key_back then it is a vanilla key.
// It is possible to override this binding for individual keys.
bind_vanilla_keys(context, cmdid_write_character);
@ -477,9 +512,6 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, 'Z', MDFR_CTRL, cmdid_timeline_scrub);
bind(context, 'z', MDFR_CTRL, cmdid_undo);
bind(context, 'y', MDFR_CTRL, cmdid_redo);
bind(context, key_left, MDFR_ALT, cmdid_increase_rewind_speed);
bind(context, key_right, MDFR_ALT, cmdid_increase_fastforward_speed);
bind(context, key_down, MDFR_ALT, cmdid_stop_rewind_fastforward);
bind(context, 'h', MDFR_CTRL, cmdid_history_backward);
bind(context, 'H', MDFR_CTRL, cmdid_history_forward);
bind(context, 'd', MDFR_CTRL, cmdid_delete_range);
@ -495,7 +527,7 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, 'f', MDFR_CTRL, cmdid_search);
bind(context, 'r', MDFR_CTRL, cmdid_reverse_search);
bind(context, 'g', MDFR_CTRL, cmdid_goto_line);
bind(context, 'g', MDFR_CTRL, goto_line);
bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer);
bind(context, 'O', MDFR_CTRL, cmdid_reopen);

View File

@ -7,8 +7,6 @@
#define MDFR_ALT 2
#define MDFR_SHIFT 4
typedef unsigned char Code;
enum Command_ID{
cmdid_null,
cmdid_write_character,
@ -27,7 +25,7 @@ enum Command_ID{
cmdid_search,
cmdid_reverse_search,
cmdid_word_complete,
cmdid_goto_line,
//cmdid_goto_line,
cmdid_set_mark,
cmdid_copy,
cmdid_cut,
@ -37,9 +35,6 @@ enum Command_ID{
cmdid_timeline_scrub,
cmdid_undo,
cmdid_redo,
cmdid_increase_rewind_speed,
cmdid_increase_fastforward_speed,
cmdid_stop_rewind_fastforward,
cmdid_history_backward,
cmdid_history_forward,
cmdid_interactive_new,
@ -108,79 +103,13 @@ enum Hook_ID{
hook_type_count
};
enum Dynamic_Type{
dynamic_type_int,
dynamic_type_string,
// never below this
dynamic_type_count
};
struct Dynamic{
int type;
union{
struct{
int str_len;
char *str_value;
};
int int_value;
};
};
inline Dynamic
dynamic_int(int x){
Dynamic result;
result.type = dynamic_type_int;
result.int_value = x;
return result;
}
inline Dynamic
dynamic_string(const char *string, int len){
Dynamic result;
result.type = dynamic_type_string;
result.str_len = len;
result.str_value = (char*)(string);
return result;
}
inline int
dynamic_to_int(Dynamic *dynamic){
int result = 0;
if (dynamic->type == dynamic_type_int){
result = dynamic->int_value;
}
return result;
}
inline char*
dynamic_to_string(Dynamic *dynamic, int *len){
char *result = 0;
if (dynamic->type == dynamic_type_string){
result = dynamic->str_value;
*len = dynamic->str_len;
}
return result;
}
inline int
dynamic_to_bool(Dynamic *dynamic){
int result = 0;
if (dynamic->type == dynamic_type_int){
result = (dynamic->int_value != 0);
}
else{
result = 1;
}
return result;
}
// NOTE(allen): None of the members of *_Summary structs nor any of the
// data pointed to by the members should be modified, I would have made
// them all const... but that causes a lot problems for C++ reasons.
struct Buffer_Summary{
int exists;
int ready;
int file_id;
int buffer_id;
int size;
@ -189,7 +118,7 @@ struct Buffer_Summary{
char *file_name;
char *buffer_name;
int file_cursor_pos;
int buffer_cursor_pos;
int is_lexed;
int map_id;
};
@ -197,7 +126,7 @@ struct Buffer_Summary{
struct File_View_Summary{
int exists;
int view_id;
int file_id;
int buffer_id;
Full_Cursor cursor;
Full_Cursor mark;
@ -206,6 +135,19 @@ struct File_View_Summary{
int unwrapped_lines;
};
struct User_Input{
Key_Event_Data key;
int abort;
};
struct Query{
int query_id;
int complete;
int type;
String prompt;
String string;
};
#ifndef FRED_STRING_STRUCT
#define FRED_STRING_STRUCT
struct String{
@ -249,7 +191,7 @@ struct Application_Links;
#define BUFFER_SEEK_DELIMITER_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out)
#define BUFFER_READ_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *out)
#define BUFFER_REPLACE_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *str, int len)
// TODO(allen): buffer save
#define BUFFER_SAVE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, char *filename, int len)
// File view manipulation
#define GET_VIEW_MAX_INDEX_SIG(name) int name(Application_Links *context)
@ -259,7 +201,23 @@ struct Application_Links;
#define REFRESH_FILE_VIEW_SIG(name) int name(Application_Links *context, File_View_Summary *view)
#define VIEW_SET_CURSOR_SIG(name) int name(Application_Links *context, File_View_Summary *view, Buffer_Seek seek, int set_preferred_x)
#define VIEW_SET_MARK_SIG(name) int name(Application_Links *context, File_View_Summary *view, Buffer_Seek seek)
#define VIEW_SET_FILE_SIG(name) int name(Application_Links *context, File_View_Summary *view, int file_id)
#define VIEW_SET_BUFFER_SIG(name) int name(Application_Links *context, File_View_Summary *view, int buffer_id)
// Directly get user input
#define AbortOnEsc 0x1
#define AbortOnClick 0x2
#define GET_USER_INPUT_SIG(name) User_Input name(Application_Links *context, unsigned int flags)
// Queries
#define QueryForFile 0x1
#define QueryForBuffer 0x2
#define QueryBar 0x0
#define QueryScreen 0x010000
#define CREATE_QUERY_SIG(name) Query name(Application_Links *context, String prompt, unsigned int flags)
#define UPDATE_QUERY_SIG(name) void name(Application_Links *context, Query *query, Key_Event_Data key)
#define CLOSE_QUERY_SIG(name) void name(Application_Links *context, Query *query)
extern "C"{
// Command exectuion
@ -283,6 +241,7 @@ extern "C"{
typedef BUFFER_SEEK_DELIMITER_SIG(Buffer_Seek_Delimiter_Function);
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
typedef BUFFER_SAVE_SIG(Buffer_Save_Function);
// View manipulation
typedef GET_VIEW_MAX_INDEX_SIG(Get_View_Max_Index_Function);
@ -292,10 +251,21 @@ extern "C"{
typedef REFRESH_FILE_VIEW_SIG(Refresh_File_View_Function);
typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function);
typedef VIEW_SET_MARK_SIG(View_Set_Mark_Function);
typedef VIEW_SET_FILE_SIG(View_Set_File_Function);
typedef VIEW_SET_BUFFER_SIG(View_Set_Buffer_Function);
// Directly get user input
typedef GET_USER_INPUT_SIG(Get_User_Input_Function);
// Queries
typedef CREATE_QUERY_SIG(Create_Query_Function);
typedef UPDATE_QUERY_SIG(Update_Query_Function);
typedef CLOSE_QUERY_SIG(Close_Query_Function);
}
struct Application_Links{
// Application data ptr
void *data;
// Command exectuion
Exec_Command_Function *exec_command_keep_stack;
Push_Parameter_Function *push_parameter;
@ -317,6 +287,7 @@ struct Application_Links{
Buffer_Seek_Delimiter_Function *buffer_seek_delimiter;
Buffer_Read_Range_Function *buffer_read_range;
Buffer_Replace_Range_Function *buffer_replace_range;
Buffer_Save_Function *buffer_save;
// View manipulation
Get_View_Max_Index_Function *get_view_max_index;
@ -326,10 +297,15 @@ struct Application_Links{
Refresh_File_View_Function *refresh_file_view;
View_Set_Cursor_Function *view_set_cursor;
View_Set_Mark_Function *view_set_mark;
View_Set_File_Function *view_set_file;
View_Set_Buffer_Function *view_set_buffer;
// Application data ptr
void *data;
// Directly get user input
Get_User_Input_Function* get_user_input;
// Queries
Create_Query_Function* create_query;
Update_Query_Function* update_query;
Close_Query_Function* close_query;
};
struct Custom_API{

View File

@ -213,19 +213,10 @@ push_directory(Application_Links *app){
return(result);
}
#define expand_string(d) ((d).str), ((d).size)
inline Range
get_range(File_View_Summary *view){
Range range;
if (view->cursor.pos < view->mark.pos){
range.min = view->cursor.pos;
range.max = view->mark.pos;
}
else{
range.max = view->cursor.pos;
range.min = view->mark.pos;
}
range = make_range(view->cursor.pos, view->mark.pos);
return(range);
}
@ -241,3 +232,14 @@ exec_command(Application_Links *app, Custom_Command_Function *func){
app->clear_parameters(app);
}
inline void
active_view_to_line(Application_Links *app, int line_number){
File_View_Summary view;
view = app->get_active_file_view(app);
// NOTE(allen|a3.4.4): We don't have to worry about whether this is a valid line number.
// When the position specified isn't possible for whatever reason it will set the cursor to
// a nearby valid position.
app->view_set_cursor(app, &view, seek_line_char(line_number, 0), 1);
}

View File

@ -22,6 +22,8 @@ NOTES ON USE:
// TODO(allen):
// - comments
// - memcpy / memmove replacements (different file for optimization options?)
// - examples and docs
// - finish a full set of tools for file name handling
//
#include "4coder_config.h"

137
4ed.cpp
View File

@ -81,6 +81,7 @@ struct App_Vars{
i32 *map_id_table;
i32 user_map_count;
Command_Binding prev_command;
Coroutine *command_coroutine;
Sys_App_Binding *sys_app_bindings;
i32 sys_app_count, sys_app_max;
@ -381,50 +382,43 @@ COMMAND_DECL(seek_white_or_token_left){
}
COMMAND_DECL(seek_alphanumeric_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 pos = buffer_seek_alphanumeric_right(&file->state.buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
COMMAND_DECL(seek_alphanumeric_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 pos = buffer_seek_alphanumeric_left(&file->state.buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
COMMAND_DECL(seek_alphanumeric_or_camel_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 pos = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
COMMAND_DECL(seek_alphanumeric_or_camel_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
COMMAND_DECL(search){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(fixed, view);
@ -434,9 +428,11 @@ COMMAND_DECL(search){
view->isearch.str = vars->mini_str;
view->isearch.reverse = 0;
view->isearch.pos = view->cursor.pos - 1;
#endif
}
COMMAND_DECL(reverse_search){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(fixed, view);
@ -446,6 +442,7 @@ COMMAND_DECL(reverse_search){
view->isearch.str = vars->mini_str;
view->isearch.reverse = 1;
view->isearch.pos = view->cursor.pos + 1;
#endif
}
COMMAND_DECL(word_complete){
@ -515,7 +512,6 @@ COMMAND_DECL(word_complete){
}
}
}
// TODO(allen): figure out how labels are scoped.
double_break:;
size = word_end - word_start;
@ -604,18 +600,6 @@ COMMAND_DECL(word_complete){
}
}
COMMAND_DECL(goto_line){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_GOTO_LINE);
view->isearch.str = vars->mini_str;
view->isearch.reverse = 1;
view->isearch.pos = view->cursor.pos;
}
COMMAND_DECL(set_mark){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
@ -652,7 +636,7 @@ COMMAND_DECL(copy){
}
}
Range range = get_range(view->cursor.pos, view->mark);
Range range = make_range(view->cursor.pos, view->mark);
if (start_set) range.start = r_start;
if (end_set) range.end = r_end;
if (range.start < range.end){
@ -689,7 +673,7 @@ COMMAND_DECL(cut){
}
}
Range range = get_range(view->cursor.pos, view->mark);
Range range = make_range(view->cursor.pos, view->mark);
if (start_set) range.start = r_start;
if (end_set) range.end = r_end;
if (range.start < range.end){
@ -754,7 +738,7 @@ COMMAND_DECL(paste_next){
if (working_set->clipboard_size > 0 && view->mode.rewrite){
view->next_mode.rewrite = 1;
Range range = get_range(view->mark, view->cursor.pos);
Range range = make_range(view->mark, view->cursor.pos);
String *src = working_set_clipboard_roll_down(working_set);
i32 next_cursor_pos = range.start+src->size;
view_replace_range(system,
@ -789,7 +773,7 @@ COMMAND_DECL(delete_range){
USE_LAYOUT(layout);
USE_MEM(mem);
Range range = get_range(view->cursor.pos, view->mark);
Range range = make_range(view->cursor.pos, view->mark);
if (range.start < range.end){
i32 next_cursor_pos = range.start;
view_replace_range(system, mem, view, layout, range.start, range.end,
@ -829,42 +813,6 @@ COMMAND_DECL(redo){
view_redo(system, mem, layout, view);
}
COMMAND_DECL(increase_rewind_speed){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
i32 rewind_speed = ROUND32(view->rewind_speed * 4.f);
if (rewind_speed > 1) rewind_speed >>= 1;
else if (rewind_speed == 1) rewind_speed = 0;
else if (rewind_speed == 0) rewind_speed = -1;
else rewind_speed *= 2;
view->rewind_speed = rewind_speed * 0.25f;
}
COMMAND_DECL(increase_fastforward_speed){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
i32 neg_rewind_speed = -ROUND32(view->rewind_speed * 4.f);
if (neg_rewind_speed > 1) neg_rewind_speed >>= 1;
else if (neg_rewind_speed == 1) neg_rewind_speed = 0;
else if (neg_rewind_speed == 0) neg_rewind_speed = -1;
else neg_rewind_speed *= 2;
view->rewind_speed = -neg_rewind_speed * 0.25f;
}
COMMAND_DECL(stop_rewind_fastforward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
view->rewind_speed = 0;
}
COMMAND_DECL(history_backward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
@ -1233,7 +1181,7 @@ case_change_range(System_Functions *system,
Mem_Options *mem, File_View *view, Editing_File *file,
u8 a, u8 z, u8 char_delta){
#if BUFFER_EXPERIMENT_SCALPEL <= 0
Range range = get_range(view->cursor.pos, view->mark);
Range range = make_range(view->cursor.pos, view->mark);
if (range.start < range.end){
Edit_Step step = {};
step.type = ED_NORMAL;
@ -1337,7 +1285,7 @@ COMMAND_DECL(auto_tab_range){
}
if (file->state.token_stack.tokens && file->state.tokens_complete){
Range range = get_range(view->cursor.pos, view->mark);
Range range = make_range(view->cursor.pos, view->mark);
if (start_set) range.start = r_start;
if (end_set) range.end = r_end;
view_auto_tab_tokens(system, mem, view, layout, range.start, range.end, clear_blank_lines);
@ -2040,9 +1988,9 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor
buffer->exists = 1;
buffer->ready = file_is_ready(file);
buffer->is_lexed = file->settings.tokens_exist;
buffer->file_id = (int)(file - working_set->files);
buffer->buffer_id = (int)(file - working_set->files);
buffer->size = file->state.buffer.size;
buffer->file_cursor_pos = file->state.cursor_pos;
buffer->buffer_cursor_pos = file->state.cursor_pos;
buffer->file_name_len = file->name.source_path.size;
buffer->buffer_name_len = file->name.live_name.size;
@ -2057,7 +2005,7 @@ fill_view_summary(File_View_Summary *view, File_View *file_view, Live_Views *liv
view->exists = 1;
view->view_id = (int)((char*)file_view - (char*)live_set->views) / live_set->stride;
if (file_view->file){
view->file_id = (int)(file_view->file - working_set->files);
view->buffer_id = (int)(file_view->file - working_set->files);
view->mark = view_compute_cursor_from_pos(file_view, file_view->mark);
view->cursor = file_view->cursor;
view->preferred_x = file_view->preferred_x;
@ -2181,7 +2129,7 @@ extern "C"{
REFRESH_BUFFER_SIG(external_refresh_buffer){
int result;
*buffer = external_get_buffer(context, buffer->file_id);
*buffer = external_get_buffer(context, buffer->buffer_id);
result = buffer->exists;
return(result);
}
@ -2195,7 +2143,7 @@ extern "C"{
if (buffer->exists){
working_set = cmd->working_set;
file = working_set->files + buffer->file_id;
file = working_set->files + buffer->buffer_id;
if (!file->state.is_dummy && file_is_ready(file)){
size = buffer_size(&file->state.buffer);
if (start < size){
@ -2225,7 +2173,7 @@ extern "C"{
if (buffer->exists){
working_set = cmd->working_set;
file = working_set->files + buffer->file_id;
file = working_set->files + buffer->buffer_id;
if (!file->state.is_dummy && file_is_ready(file)){
size = buffer_size(&file->state.buffer);
if (0 <= start && start <= end && end <= size){
@ -2254,7 +2202,7 @@ extern "C"{
if (buffer->exists){
working_set = cmd->working_set;
file = working_set->files + buffer->file_id;
file = working_set->files + buffer->buffer_id;
if (!file->state.is_dummy && file_is_ready(file)){
size = buffer_size(&file->state.buffer);
if (0 <= start && start <= end && end <= size){
@ -2377,7 +2325,7 @@ extern "C"{
return(result);
}
VIEW_SET_FILE_SIG(external_view_set_file){
VIEW_SET_BUFFER_SIG(external_view_set_buffer){
Command_Data *cmd = (Command_Data*)context->data;
Live_Views *live_set;
View *vptr;
@ -2393,8 +2341,8 @@ extern "C"{
if (file_view){
working_set = cmd->working_set;
max = working_set->file_index_count;
if (file_id >= 0 && file_id < max){
file = working_set->files + file_id;
if (buffer_id >= 0 && buffer_id < max){
file = working_set->files + buffer_id;
if (!file->state.is_dummy){
view_set_file(cmd->system, file_view, file, cmd->vars->font_set, cmd->style,
cmd->vars->hooks[hook_open_file], cmd, &app_links);
@ -2409,7 +2357,18 @@ extern "C"{
}
}
inline void
struct Command_In{
Command_Data *cmd;
Command_Binding bind;
};
internal void
command_caller(Coroutine *coroutine){
Command_In *cmd = (Command_In*)coroutine->in;
cmd->bind.function(cmd->cmd->system, cmd->cmd, cmd->bind);
}
internal void
app_links_init(System_Functions *system){
app_links.exec_command_keep_stack = external_exec_command_keep_stack;
app_links.push_parameter = external_push_parameter;
@ -2429,6 +2388,7 @@ app_links_init(System_Functions *system){
app_links.buffer_seek_delimiter = external_buffer_seek_delimiter;
app_links.buffer_read_range = external_buffer_read_range;
app_links.buffer_replace_range = external_buffer_replace_range;
app_links.buffer_save = 0;//external_buffer_save;
app_links.get_view_max_index = external_get_view_max_index;
app_links.get_file_view = external_get_file_view;
@ -2437,7 +2397,13 @@ app_links_init(System_Functions *system){
app_links.refresh_file_view = external_refresh_file_view;
app_links.view_set_cursor = external_view_set_cursor;
app_links.view_set_mark = external_view_set_mark;
app_links.view_set_file = external_view_set_file;
app_links.view_set_buffer = external_view_set_buffer;
app_links.get_user_input = 0;//external_get_user_input;
app_links.create_query = 0;//external_create_query;
app_links.update_query = 0;//external_update_query;
app_links.close_query = 0;//external_close_query;
}
#if FRED_INTERNAL
@ -2502,7 +2468,6 @@ setup_command_table(){
SET(search);
SET(reverse_search);
SET(word_complete);
SET(goto_line);
SET(set_mark);
SET(copy);
SET(cut);
@ -2512,9 +2477,6 @@ setup_command_table(){
SET(timeline_scrub);
SET(undo);
SET(redo);
SET(increase_rewind_speed);
SET(increase_fastforward_speed);
SET(stop_rewind_fastforward);
SET(history_backward);
SET(history_forward);
SET(interactive_new);
@ -3705,6 +3667,22 @@ App_Step_Sig(app_step){
switch (vars->state){
case APP_STATE_EDIT:
{
if (cmd_bind.function){
Command_In cmd_in;
cmd_in.cmd = cmd;
cmd_in.bind = cmd_bind;
vars->command_coroutine = system->launch_coroutine(command_caller, &cmd_in, 0);
app_result.redraw = 1;
}
#if 0
if (cmd_bind.function){
cmd_bind.function(system, cmd, cmd_bind);
app_result.redraw = 1;
}
#endif
#if 0
Handle_Command_Function *handle_command = 0;
if (view) handle_command = view->handle_command;
if (handle_command){
@ -3718,6 +3696,7 @@ App_Step_Sig(app_step){
}
}
vars->prev_command = cmd_bind;
#endif
}break;
case APP_STATE_RESIZING:

17
4ed.h
View File

@ -22,23 +22,6 @@ struct Application_Memory{
#define KEY_INPUT_BUFFER_SIZE 4
#define KEY_INPUT_BUFFER_DSIZE (KEY_INPUT_BUFFER_SIZE << 1)
enum Key_Control{
CONTROL_KEY_SHIFT,
CONTROL_KEY_CONTROL,
CONTROL_KEY_ALT,
CONTROL_KEY_CAPS,
// always last
CONTROL_KEY_COUNT
};
struct Key_Event_Data{
u8 keycode;
u8 character;
u8 character_no_caps_lock;
b8 modifiers[CONTROL_KEY_COUNT];
};
struct Key_Input_Data{
Key_Event_Data press[KEY_INPUT_BUFFER_SIZE];
Key_Event_Data hold[KEY_INPUT_BUFFER_SIZE];

View File

@ -9,7 +9,7 @@
// TOP
#define VERSION_NUMBER "alpha 3.4.3"
#define VERSION_NUMBER "alpha 3.4.4"
#ifdef FRED_SUPER
#define VERSION_TYPE " super!"

View File

@ -129,9 +129,9 @@ internal Command_Binding
map_extract(Command_Map *map, Key_Event_Data key){
Command_Binding bind = {};
b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
b32 alt = key.modifiers[CONTROL_KEY_ALT];
b32 shift = key.modifiers[CONTROL_KEY_SHIFT];
b32 ctrl = key.modifiers[MDFR_CONTROL_INDEX];
b32 alt = key.modifiers[MDFR_ALT_INDEX];
b32 shift = key.modifiers[MDFR_SHIFT_INDEX];
u16 code;
u8 command = MDFR_NONE;

View File

@ -164,11 +164,11 @@ internal void
draw_modifiers(Debug_View *view, Render_Target *target,
bool8 *modifiers, u32 on_color, u32 off_color, i32 *x, i32 y){
persist Dbg_Modifier dm[] = {
{"CTRL", CONTROL_KEY_CONTROL},
{"ALT", CONTROL_KEY_ALT},
{"SHIFT", CONTROL_KEY_SHIFT}
{"CTRL", MDFR_CONTROL_INDEX},
{"ALT", MDFR_ALT_INDEX},
{"SHIFT", MDFR_SHIFT_INDEX}
};
for (i32 i = 0; i < CONTROL_KEY_COUNT; ++i){
for (i32 i = 0; i < MDFR_INDEX_COUNT; ++i){
Dbg_Modifier m = dm[i];
u32 color;

View File

@ -57,8 +57,8 @@ delayed_action(Delay *delay, Action_Type type,
enum File_View_Widget_Type{
FWIDG_NONE,
FWIDG_SEARCH,
FWIDG_GOTO_LINE,
//FWIDG_SEARCH,
//FWIDG_GOTO_LINE,
FWIDG_TIMELINES,
// never below this
FWIDG_TYPE_COUNT
@ -121,7 +121,6 @@ struct File_View{
File_View_Mode mode, next_mode;
File_View_Widget widget;
f32 rewind_amount, rewind_speed;
i32 rewind_max, scrub_max;
b32 unwrapped_lines;
b32 show_whitespace;
@ -158,20 +157,6 @@ get_file(Working_Set *working_set, i32 file_id){
return(result);
}
internal Range
get_range(i32 a, i32 b){
Range result = {};
if (a < b){
result.start = a;
result.end = b;
}
else{
result.start = b;
result.end = a;
}
return result;
}
inline bool32
starts_new_line(u8 character){
return (character == '\n');
@ -1489,8 +1474,8 @@ view_widget_height(File_View *view, i32 font_height){
i32 result = 0;
switch (view->widget.type){
case FWIDG_NONE: break;
case FWIDG_SEARCH: result = font_height + 2; break;
case FWIDG_GOTO_LINE: result = font_height + 2; break;
//case FWIDG_SEARCH: result = font_height + 2; break;
//case FWIDG_GOTO_LINE: result = font_height + 2; break;
case FWIDG_TIMELINES: result = view->widget.height; break;
}
return result;
@ -2908,9 +2893,6 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect,
Widget_ID wid = make_id(&state, 2);
i32 new_count;
if (do_undo_slider(wid, &state, &layout, total_count, undo_count, 0, &new_count)){
view->rewind_speed = 0;
view->rewind_amount = 0;
for (i32 i = 0; i < scrub_max && new_count < undo_count; ++i){
view_undo(system, view_->mem, view->layout, view);
--undo_count;
@ -2961,26 +2943,6 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect,
}
}break;
}
i32 rewind_max = view->rewind_max;
view->rewind_amount += view->rewind_speed;
for (i32 i = 0; view->rewind_amount <= -1.f; ++i, view->rewind_amount += 1.f){
if (i < rewind_max) view_undo(system, view_->mem, view->layout, view);
}
for (i32 i = 0; view->rewind_amount >= 1.f; ++i, view->rewind_amount -= 1.f){
if (i < rewind_max) view_redo(system, view_->mem, view->layout, view);
}
if (view->rewind_speed < 0.f && undo_count == 0){
view->rewind_speed = 0.f;
view->rewind_amount = 0.f;
}
if (view->rewind_speed > 0.f && redo_count == 0){
view->rewind_speed = 0.f;
view->rewind_amount = 0.f;
}
}
return result;
@ -3304,6 +3266,7 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
}
}break;
#if 0
case FWIDG_SEARCH:
{
Widget_ID wid = make_id(&state, 1);
@ -3323,6 +3286,8 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
persist String gotoline_str = make_lit_string("Goto Line: ");
do_text_field(wid, &state, &layout, gotoline_str, view->isearch.str);
}break;
#endif
}
ui_finish_frame(&view->widget.state, &state, &layout, widg_rect, 0, 0);
@ -3392,6 +3357,7 @@ command_search(System_Functions*,Command_Data*,Command_Binding);
internal void
command_reverse_search(System_Functions*,Command_Data*,Command_Binding);
#if 0
internal
HANDLE_COMMAND_SIG(handle_command_file_view){
File_View *file_view = (File_View*)(view);
@ -3519,6 +3485,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
}break;
}
}
#endif
inline void
free_file_view(View *view){
@ -3557,7 +3524,6 @@ internal File_View*
file_view_init(View *view, Editing_Layout *layout){
view->type = VIEW_TYPE_FILE;
view->do_view = do_file_view;
view->handle_command = handle_command_file_view;
File_View *result = (File_View*)view;
result->layout = layout;

View File

@ -180,8 +180,8 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set,
else if (key.character == '\n' || key.character == '\t'){
result.made_a_change = 1;
if (key.modifiers[CONTROL_KEY_CONTROL] ||
key.modifiers[CONTROL_KEY_ALT]){
if (key.modifiers[MDFR_CONTROL_INDEX] ||
key.modifiers[MDFR_ALT_INDEX]){
result.hit_ctrl_newline = 1;
}
else{
@ -227,8 +227,8 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set,
else if (key.character){
result.hit_a_character = 1;
if (!key.modifiers[CONTROL_KEY_CONTROL] &&
!key.modifiers[CONTROL_KEY_ALT]){
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;

View File

@ -42,13 +42,6 @@ struct View;
typedef Do_View_Sig(Do_View_Function);
#define HANDLE_COMMAND_SIG(name) \
void (name)(System_Functions *system, View *view, \
Command_Data *command, Command_Binding binding, \
Key_Event_Data key)
typedef HANDLE_COMMAND_SIG(Handle_Command_Function);
// TODO(allen): this shouldn't exist
enum View_Type{
VIEW_TYPE_NONE,
@ -70,7 +63,6 @@ struct View{
Panel *panel;
Command_Map *map;
Do_View_Function *do_view;
Handle_Command_Function *handle_command;
Mem_Options *mem;
i32 type;
i32 block_size;

View File

@ -72,21 +72,17 @@ struct Coroutine{
void *yield_handle;
void *in;
void *out;
i32 done;
};
#define Sys_Launch_Coroutine_Sig(name) Coroutine *name(Coroutine_Function *func, void *in, void *out)
typedef Sys_Launch_Coroutine_Sig(System_Launch_Coroutine);
#define Sys_Resume_Coroutine_Sig(name) void name(Coroutine *coroutine, void *in, void *out)
#define Sys_Resume_Coroutine_Sig(name) Coroutine *name(Coroutine *coroutine, void *in, void *out)
typedef Sys_Resume_Coroutine_Sig(System_Resume_Coroutine);
#define Sys_Yield_Coroutine_Sig(name) void *name(Coroutine *coroutine)
#define Sys_Yield_Coroutine_Sig(name) void name(Coroutine *coroutine)
typedef Sys_Yield_Coroutine_Sig(System_Yield_Coroutine);
#define Sys_Release_Coroutine_Sig(name) void name(Coroutine *coroutine)
typedef Sys_Release_Coroutine_Sig(System_Relase_Coroutine);
// thread
struct Thread_Context;
@ -201,7 +197,6 @@ struct System_Functions{
System_Launch_Coroutine *launch_coroutine;
System_Resume_Coroutine *resume_coroutine;
System_Yield_Coroutine *yield_coroutine;
System_Relase_Coroutine *release_coroutine;
// cli: 4
System_CLI_Call *cli_call;

View File

@ -91,7 +91,7 @@ struct Win32_Input_Chunk_Persistent{
b8 keep_playing;
Control_Keys controls;
b8 control_keys[CONTROL_KEY_COUNT];
b8 control_keys[MDFR_INDEX_COUNT];
};
struct Win32_Input_Chunk{
@ -102,6 +102,7 @@ struct Win32_Input_Chunk{
struct Win32_Coroutine{
Coroutine coroutine;
Win32_Coroutine *next;
int done;
};
struct Win32_Vars{
@ -747,35 +748,39 @@ INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){
}
#endif
internal Coroutine*
internal Win32_Coroutine*
Win32AllocCoroutine(){
Win32_Coroutine *result = win32vars.coroutine_free;
Assert(result != 0);
win32vars.coroutine_free = result->next;
return(&result->coroutine);
return(result);
}
internal void
Win32FreeCoroutine(Coroutine *coroutine){
Win32_Coroutine *data = (Win32_Coroutine*)coroutine;
Win32FreeCoroutine(Win32_Coroutine *data){
data->next = win32vars.coroutine_free;
win32vars.coroutine_free = data;
}
internal void
Win32CoroutineMain(void *arg_){
Coroutine *coroutine = (Coroutine*)arg_;
coroutine->func(coroutine);
coroutine->done = 1;
SwitchToFiber(coroutine->yield_handle);
Win32_Coroutine *c = (Win32_Coroutine*)arg_;
c->coroutine.func(&c->coroutine);
c->done = 1;
Win32FreeCoroutine(c);
SwitchToFiber(c->coroutine.yield_handle);
}
internal
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
Win32_Coroutine *c;
Coroutine *coroutine;
void *fiber;
coroutine = Win32AllocCoroutine();
c = Win32AllocCoroutine();
c->done = 0;
coroutine = &c->coroutine;
fiber = CreateFiber(0, Win32CoroutineMain, coroutine);
@ -784,17 +789,22 @@ Sys_Launch_Coroutine_Sig(system_launch_coroutine){
coroutine->yield_handle = GetCurrentFiber();
coroutine->in = in;
coroutine->out = out;
coroutine->done = 0;
SwitchToFiber(fiber);
if (c->done){
Win32FreeCoroutine(c);
coroutine = 0;
}
return(coroutine);
}
Sys_Resume_Coroutine_Sig(system_resume_coroutine){
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
void *fiber;
Assert(coroutine->done == 0);
Assert(c->done == 0);
coroutine->yield_handle = GetCurrentFiber();
coroutine->in = in;
@ -803,18 +813,17 @@ Sys_Resume_Coroutine_Sig(system_resume_coroutine){
fiber = Win32Ptr(coroutine->plat_handle);
SwitchToFiber(fiber);
if (c->done){
Win32FreeCoroutine(c);
coroutine = 0;
}
return(coroutine);
}
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
void *result;
SwitchToFiber(coroutine->yield_handle);
result = coroutine->in;
return(result);
}
Sys_Release_Coroutine_Sig(system_release_coroutine){
Assert(coroutine->done);
Win32FreeCoroutine(coroutine);
}
internal
@ -1037,7 +1046,6 @@ Win32LoadSystemCode(){
win32vars.system->launch_coroutine = system_launch_coroutine;
win32vars.system->resume_coroutine = system_resume_coroutine;
win32vars.system->yield_coroutine = system_yield_coroutine;
win32vars.system->release_coroutine = system_release_coroutine;
win32vars.system->cli_call = system_cli_call;
win32vars.system->cli_begin_update = system_cli_begin_update;
@ -1133,7 +1141,7 @@ Win32Callback(HWND hwnd, UINT uMsg,
switch (wParam){
case VK_SHIFT:
{
control_keys[CONTROL_KEY_SHIFT] = down;
control_keys[MDFR_SHIFT_INDEX] = down;
}break;
case VK_CONTROL:
@ -1160,8 +1168,8 @@ Win32Callback(HWND hwnd, UINT uMsg,
}
}
control_keys[CONTROL_KEY_CONTROL] = ctrl;
control_keys[CONTROL_KEY_ALT] = alt;
control_keys[MDFR_CONTROL_INDEX] = ctrl;
control_keys[MDFR_ALT_INDEX] = alt;
}
system_release_lock(INPUT_LOCK);
}break;
@ -1200,8 +1208,8 @@ Win32Callback(HWND hwnd, UINT uMsg,
int result;
GetKeyboardState(state);
if (control_keys[CONTROL_KEY_CONTROL] &&
!control_keys[CONTROL_KEY_ALT])
if (control_keys[MDFR_CONTROL_INDEX] &&
!control_keys[MDFR_ALT_INDEX])
state[VK_CONTROL] = 0;
x = 0;
result = ToAscii(vk, scan, state, &x, 0);
@ -1305,7 +1313,7 @@ Win32Callback(HWND hwnd, UINT uMsg,
win32vars.input_chunk.pers.mouse_r = 0;
b8 *control_keys = win32vars.input_chunk.pers.control_keys;
for (int i = 0; i < CONTROL_KEY_COUNT; ++i) control_keys[i] = 0;
for (int i = 0; i < MDFR_INDEX_COUNT; ++i) control_keys[i] = 0;
win32vars.input_chunk.pers.controls = {};
system_release_lock(INPUT_LOCK);
@ -1401,6 +1409,8 @@ Win32Callback(HWND hwnd, UINT uMsg,
DWORD
UpdateLoop(LPVOID param){
ConvertThreadToFiber(0);
for (;win32vars.input_chunk.pers.keep_playing;){
i64 timer_start = system_time();
@ -1409,7 +1419,7 @@ UpdateLoop(LPVOID param){
win32vars.input_chunk.trans = {};
system_release_lock(INPUT_LOCK);
input_chunk.pers.control_keys[CONTROL_KEY_CAPS] = GetKeyState(VK_CAPITAL) & 0x1;
input_chunk.pers.control_keys[MDFR_CAPS_INDEX] = GetKeyState(VK_CAPITAL) & 0x1;
POINT mouse_point;
if (GetCursorPos(&mouse_point) && ScreenToClient(win32vars.window_handle, &mouse_point)){
@ -1601,6 +1611,12 @@ main(int argc, char **argv){
win32vars.system = system;
Win32LoadSystemCode();
ConvertThreadToFiber(0);
win32vars.coroutine_free = win32vars.coroutine_data;
for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){
win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1;
}
LPVOID base;
#if FRED_INTERNAL
base = (LPVOID)Tbytes(1);