eliminated do_view callback

This commit is contained in:
Allen Webster 2016-03-03 14:27:09 -05:00
parent 451a5b983e
commit 1b16bf2c11
7 changed files with 401 additions and 475 deletions

View File

@ -12,50 +12,6 @@
#ifndef FRED_BUFFER_TYPES_H
#define FRED_BUFFER_TYPES_H
#ifndef FRED_STRING_STRUCT
#define FRED_STRING_STRUCT
typedef struct String{
char *str;
int size;
int memory_size;
} String;
typedef struct Offset_String{
int offset;
int size;
} Offset_String;
#endif
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 Mouse_State{
char l, r;
char press_l, press_r;
char release_l, release_r;
char wheel;
char out_of_window;
int x, y;
} Mouse_State;
typedef struct Full_Cursor{
int pos;
int line, character;
@ -126,114 +82,6 @@ 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.min = p2;
range.max = p1;
}
return(range);
}
typedef enum Dynamic_Type{
dynamic_type_int,
dynamic_type_string,
// never below this
dynamic_type_count
} Dynamic_Type;
typedef struct Dynamic{
int type;
union{
struct{
int str_len;
char *str_value;
};
int int_value;
};
} Dynamic;
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;
}
typedef struct File_Info{
String filename;
int folder;
} File_Info;
typedef struct File_List{
// Ignore this, it's for internal stuff.
void *block;
// The list of files and folders.
File_Info *infos;
int count;
// Ignore this, it's for internal stuff.
int block_size;
} File_List;
#endif

View File

@ -564,6 +564,26 @@ CUSTOM_COMMAND_SIG(query_replace){
app->view_set_cursor(app, &view, seek_pos(pos), 1);
}
CUSTOM_COMMAND_SIG(close_all_code){
String extension;
Buffer_Summary buffer;
int max, i;
max = app->get_buffer_max_index(app);
for (i = 0; i < max; ++i){
buffer = app->get_buffer(app, i);
extension = file_extension(make_string(buffer.file_name, buffer.file_name_len));
if (match(extension, make_lit_string("cpp")) ||
match(extension, make_lit_string("hpp")) ||
match(extension, make_lit_string("c")) ||
match(extension, make_lit_string("h"))){
//
push_parameter(app, par_buffer_id, buffer.buffer_id);
exec_command(app, cmdid_kill_buffer);
}
}
}
CUSTOM_COMMAND_SIG(open_all_code){
// NOTE(allen|a3.4.4): This method of getting the hot directory works
// because this custom.cpp gives no special meaning to app->memory
@ -603,6 +623,29 @@ CUSTOM_COMMAND_SIG(open_all_code){
app->free_file_list(app, list);
}
CUSTOM_COMMAND_SIG(execute_any_cli){
Query_Bar bar_out, bar_cmd;
String hot_directory;
char space[1024], more_space[1024], even_more_space[1024];
bar_out.prompt = make_lit_string("Output Buffer: ");
bar_out.string = make_fixed_width_string(space);
if (!query_user_string(app, &bar_out)) return;
bar_cmd.prompt = make_lit_string("Command: ");
bar_cmd.string = make_fixed_width_string(more_space);
if (!query_user_string(app, &bar_cmd)) return;
hot_directory = make_fixed_width_string(even_more_space);
hot_directory.size = app->directory_get_hot(app, hot_directory.str, hot_directory.memory_size);
push_parameter(app, par_cli_overlap_with_conflict, 1);
push_parameter(app, par_name, bar_out.string.str, bar_out.string.size);
push_parameter(app, par_cli_path, hot_directory.str, hot_directory.size);
push_parameter(app, par_cli_command, bar_cmd.string.str, bar_cmd.string.size);
exec_command(app, cmdid_command_line);
}
CUSTOM_COMMAND_SIG(execute_arbitrary_command){
// NOTE(allen): This isn't a super powerful version of this command, I will expand
// upon it so that it has all the cmdid_* commands by default. However, with this
@ -624,6 +667,9 @@ CUSTOM_COMMAND_SIG(execute_arbitrary_command){
if (match(bar.string, make_lit_string("open all code"))){
exec_command(app, open_all_code);
}
else if(match(bar.string, make_lit_string("close all code"))){
exec_command(app, close_all_code);
}
else if (match(bar.string, make_lit_string("open in quotes"))){
exec_command(app, open_file_in_quotes);
}
@ -840,6 +886,7 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, 'm', MDFR_ALT, build_search);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
bind(context, 'z', MDFR_ALT, execute_any_cli);
// NOTE(allen): These callbacks may not actually be useful to you, but
// go look at them and see what they do.

View File

@ -2,6 +2,156 @@
#include "4coder_keycodes.h"
#include "4coder_buffer_types.h"
#ifndef FRED_STRING_STRUCT
#define FRED_STRING_STRUCT
typedef struct String{
char *str;
int size;
int memory_size;
} String;
typedef struct Offset_String{
int offset;
int size;
} Offset_String;
#endif
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 Mouse_State{
char l, r;
char press_l, press_r;
char release_l, release_r;
char wheel;
char out_of_window;
int x, y;
} Mouse_State;
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.min = p2;
range.max = p1;
}
return(range);
}
typedef enum Dynamic_Type{
dynamic_type_int,
dynamic_type_string,
// never below this
dynamic_type_count
} Dynamic_Type;
typedef struct Dynamic{
int type;
union{
struct{
int str_len;
char *str_value;
};
int int_value;
};
} Dynamic;
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;
}
typedef struct File_Info{
String filename;
int folder;
} File_Info;
typedef struct File_List{
// Ignore this, it's for internal stuff.
void *block;
// The list of files and folders.
File_Info *infos;
int count;
// Ignore this, it's for internal stuff.
int block_size;
} File_List;
#define MDFR_NONE 0
#define MDFR_CTRL 1
#define MDFR_ALT 2
@ -169,41 +319,41 @@ extern "C"{
struct Application_Links;
// Command exectuion
#define PUSH_PARAMETER_SIG(name) void name(Application_Links *context, Dynamic param, Dynamic value)
#define PUSH_MEMORY_SIG(name) char* name(Application_Links *context, int len)
#define EXECUTE_COMMAND_SIG(name) void name(Application_Links *context, int command_id)
#define CLEAR_PARAMETERS_SIG(name) void name(Application_Links *context)
#define PUSH_PARAMETER_SIG(name) void name(Application_Links *app, Dynamic param, Dynamic value)
#define PUSH_MEMORY_SIG(name) char* name(Application_Links *app, int len)
#define EXECUTE_COMMAND_SIG(name) void name(Application_Links *app, int command_id)
#define CLEAR_PARAMETERS_SIG(name) void name(Application_Links *app)
// File system navigation
#define DIRECTORY_GET_HOT_SIG(name) int name(Application_Links *context, char *out, int capacity)
#define FILE_EXISTS_SIG(name) int name(Application_Links *context, char *filename, int len)
#define DIRECTORY_CD_SIG(name) int name(Application_Links *context, char *dir, int *len, int capacity, char *rel_path, int rel_len)
#define GET_FILE_LIST_SIG(name) File_List name(Application_Links *context, char *dir, int len)
#define FREE_FILE_LIST_SIG(name) void name(Application_Links *context, File_List list)
#define DIRECTORY_GET_HOT_SIG(name) int name(Application_Links *app, char *out, int capacity)
#define FILE_EXISTS_SIG(name) int name(Application_Links *app, char *filename, int len)
#define DIRECTORY_CD_SIG(name) int name(Application_Links *app, char *dir, int *len, int capacity, char *rel_path, int rel_len)
#define GET_FILE_LIST_SIG(name) File_List name(Application_Links *app, char *dir, int len)
#define FREE_FILE_LIST_SIG(name) void name(Application_Links *app, File_List list)
// Direct buffer manipulation
#define GET_BUFFER_MAX_INDEX_SIG(name) int name(Application_Links *context)
#define GET_BUFFER_SIG(name) Buffer_Summary name(Application_Links *context, int index)
#define GET_ACTIVE_BUFFER_SIG(name) Buffer_Summary name(Application_Links *context)
#define GET_BUFFER_BY_NAME(name) Buffer_Summary name(Application_Links *context, char *filename, int len)
#define GET_BUFFER_MAX_INDEX_SIG(name) int name(Application_Links *app)
#define GET_BUFFER_SIG(name) Buffer_Summary name(Application_Links *app, int index)
#define GET_ACTIVE_BUFFER_SIG(name) Buffer_Summary name(Application_Links *app)
#define GET_BUFFER_BY_NAME(name) Buffer_Summary name(Application_Links *app, char *filename, int len)
#define REFRESH_BUFFER_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer)
#define BUFFER_SEEK_DELIMITER_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out)
#define BUFFER_SEEK_STRING_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out)
#define BUFFER_READ_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *out)
#define BUFFER_REPLACE_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *str, int len)
#define BUFFER_SET_POS_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int pos)
#define REFRESH_BUFFER_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer)
#define BUFFER_SEEK_DELIMITER_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out)
#define BUFFER_SEEK_STRING_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out)
#define BUFFER_READ_RANGE_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out)
#define BUFFER_REPLACE_RANGE_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len)
#define BUFFER_SET_POS_SIG(name) int name(Application_Links *app, Buffer_Summary *buffer, int pos)
// File view manipulation
#define GET_VIEW_MAX_INDEX_SIG(name) int name(Application_Links *context)
#define GET_VIEW_SIG(name) View_Summary name(Application_Links *context, int index)
#define GET_ACTIVE_VIEW_SIG(name) View_Summary name(Application_Links *context)
#define GET_VIEW_MAX_INDEX_SIG(name) int name(Application_Links *app)
#define GET_VIEW_SIG(name) View_Summary name(Application_Links *app, int index)
#define GET_ACTIVE_VIEW_SIG(name) View_Summary name(Application_Links *app)
#define REFRESH_VIEW_SIG(name) int name(Application_Links *context, View_Summary *view)
#define VIEW_SET_CURSOR_SIG(name) int name(Application_Links *context, View_Summary *view, Buffer_Seek seek, int set_preferred_x)
#define VIEW_SET_MARK_SIG(name) int name(Application_Links *context, View_Summary *view, Buffer_Seek seek)
#define VIEW_SET_HIGHLIGHT_SIG(name) int name(Application_Links *context, View_Summary *view, int start, int end, int turn_on)
#define VIEW_SET_BUFFER_SIG(name) int name(Application_Links *context, View_Summary *view, int buffer_id)
#define REFRESH_VIEW_SIG(name) int name(Application_Links *app, View_Summary *view)
#define VIEW_SET_CURSOR_SIG(name) int name(Application_Links *app, View_Summary *view, Buffer_Seek seek, int set_preferred_x)
#define VIEW_SET_MARK_SIG(name) int name(Application_Links *app, View_Summary *view, Buffer_Seek seek)
#define VIEW_SET_HIGHLIGHT_SIG(name) int name(Application_Links *app, View_Summary *view, int start, int end, int turn_on)
#define VIEW_SET_BUFFER_SIG(name) int name(Application_Links *app, View_Summary *view, int buffer_id)
// Directly get user input
#define EventOnAnyKey 0x1

183
4ed.cpp
View File

@ -1096,10 +1096,32 @@ COMMAND_DECL(interactive_kill_buffer){
COMMAND_DECL(kill_buffer){
ProfileMomentFunction();
USE_VIEW(view);
REQ_FILE(file, view);
USE_FILE(file, view);
USE_DELAY(delay);
USE_WORKING_SET(working_set);
delayed_try_kill(delay, file->name.live_name, view->panel);
int buffer_id = -1;
Command_Parameter *end = param_stack_end(&command->part);
Command_Parameter *param = param_stack_first(&command->part, end);
for (; param < end; param = param_next(param, end)){
int v = dynamic_to_int(&param->param.param);
if (v == par_buffer_id && param->param.value.type == dynamic_type_int){
buffer_id = dynamic_to_int(&param->param.value);
}
}
if (buffer_id != -1){
if (buffer_id > 0 && buffer_id < working_set->file_max_count){
file = working_set->files + buffer_id;
if (!file->state.is_dummy){
delayed_kill(delay, file->name.source_path);
}
}
}
else if (file){
delayed_try_kill(delay, file->name.live_name, view->panel);
}
}
COMMAND_DECL(toggle_line_wrap){
@ -1748,9 +1770,11 @@ build(System_Functions *system, Mem_Options *mem,
index = (i32)(file - vars->working_set.files);
if (file){
if (!(flags & CLI_AlwaysBindToView)){
Panel *panel = layout->panels;
for (i32 i = 0; i < layout->panel_count; ++i, ++panel){
View *view = panel->view;
View *view;
Panel *panel, *used_panels;
used_panels = &layout->used_sentinel;
for (dll_items(panel, used_panels)){
view = panel->view;
if (view->file == file){
bind_to_new_view = 0;
break;
@ -1881,18 +1905,20 @@ globalvar Command_Function command_table[cmdid_count];
internal void
fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *working_set){
buffer->exists = 1;
buffer->ready = file_is_ready(file);
buffer->is_lexed = file->settings.tokens_exist;
buffer->buffer_id = (int)(file - working_set->files);
buffer->size = file->state.buffer.size;
buffer->buffer_cursor_pos = file->state.cursor_pos;
if (!file->state.is_dummy){
buffer->ready = file_is_ready(file);
buffer->is_lexed = file->settings.tokens_exist;
buffer->buffer_id = (int)(file - working_set->files);
buffer->size = file->state.buffer.size;
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;
buffer->file_name = file->name.source_path.str;
buffer->buffer_name = file->name.live_name.str;
buffer->file_name_len = file->name.source_path.size;
buffer->buffer_name_len = file->name.live_name.size;
buffer->file_name = file->name.source_path.str;
buffer->buffer_name = file->name.live_name.str;
buffer->map_id = file->settings.base_map_id;
buffer->map_id = file->settings.base_map_id;
}
}
internal void
@ -1911,7 +1937,7 @@ fill_view_summary(View_Summary *view, View *file_view, Live_Views *live_set, Wor
extern "C"{
EXECUTE_COMMAND_SIG(external_exec_command_keep_stack){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Command_Function function = command_table[command_id];
Command_Binding binding;
binding.function = function;
@ -1921,7 +1947,7 @@ extern "C"{
}
PUSH_PARAMETER_SIG(external_push_parameter){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Partition *part = &cmd->part;
Command_Parameter *cmd_param = push_struct(part, Command_Parameter);
cmd_param->type = 0;
@ -1930,7 +1956,7 @@ extern "C"{
}
PUSH_MEMORY_SIG(external_push_memory){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Partition *part = &cmd->part;
Command_Parameter *base = push_struct(part, Command_Parameter);
char *result = push_array(part, char, len);
@ -1944,12 +1970,12 @@ extern "C"{
}
CLEAR_PARAMETERS_SIG(external_clear_parameters){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
cmd->part.pos = 0;
}
DIRECTORY_GET_HOT_SIG(external_directory_get_hot){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Hot_Directory *hot = &cmd->vars->hot_directory;
i32 copy_max = capacity - 1;
hot_directory_clean_end(hot);
@ -1961,7 +1987,7 @@ extern "C"{
}
GET_FILE_LIST_SIG(external_get_file_list){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
File_List result = {};
system->set_file_list(&result, make_string(dir, len));
@ -1969,20 +1995,20 @@ extern "C"{
}
FREE_FILE_LIST_SIG(external_free_file_list){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
system->set_file_list(&list, make_string(0, 0));
}
GET_BUFFER_MAX_INDEX_SIG(external_get_buffer_max_index){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Working_Set *working_set = cmd->working_set;
int max = working_set->file_index_count;
return(max);
}
GET_BUFFER_SIG(external_get_buffer){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set = cmd->working_set;
int max = working_set->file_index_count;
@ -1990,36 +2016,28 @@ extern "C"{
if (index >= 0 && index < max){
file = working_set->files + index;
if (!file->state.is_dummy){
fill_buffer_summary(&buffer, file, working_set);
}
fill_buffer_summary(&buffer, file, working_set);
}
return(buffer);
}
GET_ACTIVE_BUFFER_SIG(external_get_active_buffer){
Command_Data *cmd = (Command_Data*)context->cmd_context;
View *view;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set;
Buffer_Summary buffer = {};
view = cmd->view;
if (view){
file = view->file;
working_set = cmd->working_set;
file = cmd->view->file;
if (file && !file->state.is_dummy){
fill_buffer_summary(&buffer, file, working_set);
}
if (file && !file->state.is_dummy){
fill_buffer_summary(&buffer, file, cmd->working_set);
}
return(buffer);
}
GET_BUFFER_BY_NAME(external_get_buffer_by_name){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set;
i32 index;
@ -2038,13 +2056,13 @@ extern "C"{
REFRESH_BUFFER_SIG(external_refresh_buffer){
int result;
*buffer = external_get_buffer(context, buffer->buffer_id);
*buffer = external_get_buffer(app, buffer->buffer_id);
result = buffer->exists;
return(result);
}
BUFFER_SEEK_DELIMITER_SIG(external_buffer_seek_delimiter){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set;
int result = 0;
@ -2076,7 +2094,7 @@ extern "C"{
}
BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set;
Temp_Memory temp;
@ -2114,7 +2132,7 @@ extern "C"{
}
BUFFER_READ_RANGE_SIG(external_buffer_read_range){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set;
int result = 0;
@ -2137,7 +2155,7 @@ extern "C"{
}
BUFFER_REPLACE_RANGE_SIG(external_buffer_replace_range){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set;
@ -2177,7 +2195,7 @@ extern "C"{
}
BUFFER_SET_POS_SIG(external_buffer_set_pos){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file;
Working_Set *working_set;
@ -2201,14 +2219,14 @@ extern "C"{
}
GET_VIEW_MAX_INDEX_SIG(external_get_view_max_index){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Live_Views *live_set = cmd->live_set;
int max = live_set->max;
return(max);
}
GET_VIEW_SIG(external_get_view){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Live_Views *live_set = cmd->live_set;
int max = live_set->max;
View *vptr;
@ -2223,7 +2241,7 @@ extern "C"{
}
GET_ACTIVE_VIEW_SIG(external_get_active_view){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
View_Summary view = {};
View *vptr;
@ -2235,13 +2253,13 @@ extern "C"{
REFRESH_VIEW_SIG(external_refresh_view){
int result;
*view = external_get_view(context, view->view_id);
*view = external_get_view(app, view->view_id);
result = view->exists;
return(result);
}
VIEW_SET_CURSOR_SIG(external_view_set_cursor){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Live_Views *live_set;
View *vptr;
int result = 0;
@ -2250,6 +2268,9 @@ extern "C"{
live_set = cmd->live_set;
vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id);
result = 1;
if (seek.type == buffer_seek_line_char && seek.character <= 0){
seek.character = 1;
}
vptr->cursor = view_compute_cursor(vptr, seek);
if (set_preferred_x){
vptr->preferred_x = view_get_cursor_x(vptr);
@ -2261,7 +2282,7 @@ extern "C"{
}
VIEW_SET_MARK_SIG(external_view_set_mark){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Live_Views *live_set;
View *vptr;
Full_Cursor cursor;
@ -2271,6 +2292,9 @@ extern "C"{
live_set = cmd->live_set;
vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id);
result = 1;
if (seek.type == buffer_seek_line_char && seek.character <= 0){
seek.character = 1;
}
if (seek.type != buffer_seek_pos){
cursor = view_compute_cursor(vptr, seek);
vptr->mark = cursor.pos;
@ -2285,7 +2309,7 @@ extern "C"{
}
VIEW_SET_HIGHLIGHT_SIG(external_view_set_highlight){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Live_Views *live_set;
View *vptr;
int result = 0;
@ -2307,7 +2331,7 @@ extern "C"{
}
VIEW_SET_BUFFER_SIG(external_view_set_buffer){
Command_Data *cmd = (Command_Data*)context->cmd_context;
Command_Data *cmd = (Command_Data*)app->cmd_context;
Live_Views *live_set;
View *vptr;
Editing_File *file;
@ -2939,6 +2963,7 @@ extern "C" SCROLL_RULE_SIG(fallback_scroll_rule){
return(result);
}
App_Init_Sig(app_init){
app_links_init(system, memory->user_memory, memory->user_memory_size);
@ -3249,7 +3274,7 @@ App_Init_Sig(app_init){
// more unified behavior, I will use this to add checks to the program's state so that I
// can make sure it behaving well.
internal void
correctness_check(App_Vars *vars){
correctness_check_(App_Vars *vars){
Panel *panel, *used_panels;
used_panels = &vars->layout.used_sentinel;
for (dll_items(panel, used_panels)){
@ -3410,8 +3435,6 @@ App_Step_Sig(app_step){
ProfileEnd(OS_syncing);
correctness_check(vars);
ProfileStart(hover_status);
// NOTE(allen): detect mouse hover status
i32 mx = mouse->x;
@ -3491,8 +3514,6 @@ App_Step_Sig(app_step){
}
ProfileEnd(hover_status);
correctness_check(vars);
// NOTE(allen): prepare to start executing commands
ProfileStart(prepare_commands);
@ -3524,8 +3545,8 @@ App_Step_Sig(app_step){
i32 i;
String file_name;
Panel *panel = vars->layout.panels;
for (i = 0; i < vars->settings.init_files_count; ++i, ++panel){
Panel *panel = &vars->layout.used_sentinel;
for (i = 0; i < vars->settings.init_files_count; ++i, panel = panel->next){
file_name = make_string_slowly(vars->settings.init_files[i]);
if (i < vars->layout.panel_count){
@ -3673,8 +3694,6 @@ App_Step_Sig(app_step){
ProfileEnd(command_coroutine);
correctness_check(vars);
// NOTE(allen): pass raw input to the panels
ProfileStart(step);
@ -3719,17 +3738,18 @@ App_Step_Sig(app_step){
{
Panel *panel, *used_panels;
View *view;
b32 active;
used_panels = &vars->layout.used_sentinel;
for (dll_items(panel, used_panels)){
View *view_ = panel->view;
Assert(view_->do_view);
b32 active = (panel == cmd->panel);
view = panel->view;
active = (panel == cmd->panel);
Input_Summary input = (active)?(active_input):(dead_input);
if (panel == mouse_panel && !mouse->out_of_window){
input.mouse = mouse_state;
}
if (view_->do_view(system, exchange, view_, panel->inner, cmd->view,
VMSG_STEP, 0, &input, &active_input)){
if (step_file_view(system, exchange, view, panel->inner, active, &input)){
app_result.redraw = 1;
}
}
@ -3738,8 +3758,6 @@ App_Step_Sig(app_step){
update_command_data(vars, cmd);
ProfileEnd(step);
correctness_check(vars);
// NOTE(allen): command execution
ProfileStart(command);
if (!consumed_input[0] || !consumed_input[1]){
@ -3801,8 +3819,6 @@ App_Step_Sig(app_step){
update_command_data(vars, cmd);
ProfileEnd(command);
correctness_check(vars);
ProfileStart(resizing);
// NOTE(allen): panel resizing
switch (vars->state){
@ -3908,8 +3924,6 @@ App_Step_Sig(app_step){
update_command_data(vars, cmd);
ProfileEnd(resizing);
correctness_check(vars);
// NOTE(allen): processing sys app bindings
ProfileStart(sys_app_bind_processing);
{
@ -4222,8 +4236,6 @@ App_Step_Sig(app_step){
end_temp_memory(param_stack_temp);
ProfileEnd(delayed_actions);
correctness_check(vars);
ProfileStart(resize);
// NOTE(allen): send resize messages to panels that have changed size
{
@ -4236,9 +4248,7 @@ App_Step_Sig(app_step){
prev.x1 != inner.x1 || prev.y1 != inner.y1){
View *view = panel->view;
if (view){
view->do_view(system, exchange,
view, inner, cmd->view,
VMSG_RESIZE, 0, &dead_input, &active_input);
remeasure_file_view(system, view, panel->inner);
}
}
panel->prev_inner = inner;
@ -4268,16 +4278,12 @@ App_Step_Sig(app_step){
for (dll_items(panel, used_panels)){
View *view = panel->view;
if (view){
view->do_view(system, exchange,
view, panel->inner, cmd->view,
VMSG_STYLE_CHANGE, 0, &dead_input, &active_input);
remeasure_file_view(system, view, panel->inner);
}
}
}
ProfileEnd(style_change);
correctness_check(vars);
ProfileStart(redraw);
if (mouse_panel != vars->prev_mouse_panel) app_result.redraw = 1;
if (app_result.redraw){
@ -4300,14 +4306,9 @@ App_Step_Sig(app_step){
u32 back_color = style->main.back_color;
draw_rectangle(target, full, back_color);
if (view){
Assert(view->do_view);
draw_push_clip(target, panel->inner);
view->do_view(system, exchange,
view, panel->inner, cmd->view,
VMSG_DRAW, target, &dead_input, &active_input);
draw_pop_clip(target);
}
draw_push_clip(target, panel->inner);
draw_file_view(system, exchange, view, cmd->view, panel->inner, active, target, &dead_input);
draw_pop_clip(target);
u32 margin_color;
if (active){
@ -4353,8 +4354,6 @@ App_Step_Sig(app_step){
*result = app_result;
result->lctrl_lalt_is_altgr = vars->settings.lctrl_lalt_is_altgr;
correctness_check(vars);
// end-of-app_step
}

View File

@ -35,10 +35,11 @@
#define FCPP_LEXER_IMPLEMENTATION
#include "4cpp_lexer.h"
#include "4ed_template.cpp"
#include "4ed_exchange.cpp"
#include "4ed_font_set.cpp"
#include "4ed_rendering_helper.cpp"
#include "4ed_template.cpp"
#include "4ed_exchange.cpp"
#include "4ed_command.cpp"
#include "4ed_style.cpp"
#include "4ed_file.cpp"

View File

@ -9,23 +9,6 @@
// TOP
enum View_Message{
VMSG_STEP,
VMSG_DRAW,
VMSG_RESIZE,
VMSG_STYLE_CHANGE,
VMSG_FREE
};
struct View;
#define Do_View_Sig(name) \
i32 (name)(System_Functions *system, Exchange *exchange, \
View *view, i32_Rect rect, View *active, \
View_Message message, Render_Target *target, \
Input_Summary *user_input, Input_Summary *active_input)
typedef Do_View_Sig(Do_View_Function);
enum Interactive_Action{
IAct_Open,
IAct_Save_As,
@ -42,7 +25,7 @@ enum Interactive_Interaction{
};
struct View_Mode{
i8 rewrite;
i32 rewrite;
};
struct Incremental_Search{
@ -91,7 +74,6 @@ struct View{
Panel *panel;
Command_Map *map;
Do_View_Function *do_view;
Scroll_Rule_Function *scroll_rule;
i32 id;
@ -134,6 +116,7 @@ struct View{
b8 import_export_check[64];
i32 import_file_id;
// file stuff
i32 font_advance;
i32 font_height;
@ -143,6 +126,7 @@ struct View{
f32 scroll_x, target_x, prev_target_x;
f32 preferred_x;
i32 scroll_i;
f32 scroll_min_limit;
union{
Incremental_Search isearch;
@ -170,6 +154,7 @@ struct View{
f32 *line_wrap_y;
Command_Map *map_for_file;
b32 reinit_scrolling;
};
struct View_And_ID{
@ -666,16 +651,12 @@ file_close(System_Functions *system, General_Memory *general, Editing_File *file
general_memory_free(general, file->state.token_stack.tokens);
}
#if BUFFER_EXPERIMENT_SCALPEL <= 1
Buffer_Type *buffer = &file->state.buffer;
if (buffer->data){
general_memory_free(general, buffer->data);
general_memory_free(general, buffer->line_starts);
general_memory_free(general, buffer->line_widths);
}
#elif BUFFER_EXPERIMENT_SCALPEL == 2
// TODO
#endif
if (file->state.undo.undo.edits){
general_memory_free(general, file->state.undo.undo.strings);
@ -746,23 +727,7 @@ Job_Callback_Sig(job_full_lex){
u8 *dest = (u8*)file->state.swap_stack.tokens;
u8 *src = (u8*)tokens.tokens;
#if 1
memcpy(dest, src, tokens.count*sizeof(Cpp_Token));
#else
i32 copy_amount = Kbytes(8);
i32 uncoppied = tokens.count*sizeof(Cpp_Token);
if (copy_amount > uncoppied) copy_amount = uncoppied;
while (uncoppied > 0){
system->acquire_lock(FRAME_LOCK);
memcpy(dest, src, copy_amount);
system->release_lock(FRAME_LOCK);
dest += copy_amount;
src += copy_amount;
uncoppied -= copy_amount;
if (copy_amount > uncoppied) copy_amount = uncoppied;
}
#endif
system->acquire_lock(FRAME_LOCK);
{
@ -815,10 +780,6 @@ file_first_lex_parallel(System_Functions *system,
file->state.tokens_complete = 0;
file->state.still_lexing = 1;
#if 0
full_lex(system, file, general);
#else
Job_Data job;
job.callback = job_full_lex;
job.data[0] = file;
@ -906,20 +867,14 @@ file_relex_parallel(System_Functions *system,
file->state.still_lexing = 1;
#if 0
full_lex(system, file, general);
#else
Job_Data job;
job.callback = job_full_lex;
job.data[0] = file;
job.data[1] = general;
job.memory_request = Kbytes(64);
file->state.lex_job = system->post_job(BACKGROUND_THREADS, job);
#endif
}
}
#endif
internal bool32
file_grow_as_needed_(General_Memory *general, Editing_File *file, i32 new_size){
@ -1132,7 +1087,6 @@ file_unpost_history_block(Editing_File *file){
file->state.undo.history_head_block = old_head->prev_block;
}
#if BUFFER_EXPERIMENT_SCALPEL <= 3
internal Edit_Step*
file_post_history(General_Memory *general, Editing_File *file,
Edit_Step step, b32 do_merge, b32 can_merge){
@ -1202,7 +1156,6 @@ file_post_history(General_Memory *general, Editing_File *file,
return result;
}
#endif
inline Full_Cursor
view_compute_cursor_from_pos(View *view, i32 pos){
@ -1368,10 +1321,6 @@ view_set_file(
Panel *panel;
Font_Info *fnt_info;
f32 w, h;
f32 cursor_x, cursor_y;
f32 target_x, target_y;
panel = view->panel;
// NOTE(allen): This is actually more like view_set_style right?
@ -1386,11 +1335,6 @@ view_set_file(
view->file = file;
view->cursor = {};
view->prev_target_x = -1000.f;
view->prev_target_y = -1000.f;
target_x = 0;
target_y = 0;
// NOTE(allen): Stuff that does assume file exists.
@ -1405,29 +1349,10 @@ view_set_file(
view_measure_wraps(system, &view->mem->general, view);
view->cursor = view_compute_cursor_from_pos(view, file->state.cursor_pos);
cursor_x = view_get_cursor_x(view);
cursor_y = view_get_cursor_y(view);
w = (f32)(panel->inner.x1 - panel->inner.x0);
h = (f32)(panel->inner.y1 - panel->inner.y0);
Assert(cursor_x >= target_x);
if (cursor_x >= target_x + w){
target_x = (f32)(cursor_x - w*.5f);
}
target_y = (f32)FLOOR32(cursor_y - h*.5f);
if (target_y < 0) target_y = 0;
view->reinit_scrolling = 1;
}
}
// NOTE(allen): More stuff that doesn't assume file exists, but that
// has to come after computing target_x, target_y
view->target_x = target_x;
view->target_y = target_y;
view->scroll_x = target_x;
view->scroll_y = target_y;
// TODO(allen): Bypass all this nonsense, it's a hack! Hooks need parameters!
// Just accept it and pass the file to the open hook when it is loaded.
if (file){
@ -1438,33 +1363,30 @@ view_set_file(
}
}
// TODO(allen): Somehow keep track of the scroll limits through this process.
// Maybe scroll limits should be stored in the view at each frame.
struct Relative_Scrolling{
f32 scroll_x, scroll_y;
f32 target_x, target_y;
f32 scroll_min_limit;
};
internal Relative_Scrolling
view_get_relative_scrolling(View *view){
Relative_Scrolling result;
f32 cursor_x, cursor_y;
cursor_x = view_get_cursor_x(view);
f32 cursor_y;
cursor_y = view_get_cursor_y(view);
result.scroll_x = cursor_x - view->scroll_x;
result.scroll_y = cursor_y - view->scroll_y;
result.target_x = cursor_x - view->target_x;
result.target_y = cursor_y - view->target_y;
result.scroll_min_limit = view->scroll_min_limit;
return result;
}
internal void
view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){
f32 cursor_x, cursor_y;
cursor_x = view_get_cursor_x(view);
f32 cursor_y;
cursor_y = view_get_cursor_y(view);
view->scroll_y = cursor_y - scrolling.scroll_y;
view->target_y = cursor_y - scrolling.target_y;
if (view->target_y < scrolling.scroll_min_limit) view->target_y = scrolling.scroll_min_limit;
}
inline void
@ -1517,20 +1439,6 @@ view_widget_rect(View *view, i32 font_height){
return(result);
}
#if FRED_SLOW
inline b32
debug_edit_step_check(Edit_Step a, Edit_Step b){
Assert(a.type == b.type);
Assert(a.can_merge == b.can_merge);
Assert(a.pre_pos == b.pre_pos);
Assert(a.post_pos == b.post_pos);
Assert(a.edit.start == b.edit.start);
Assert(a.edit.end == b.edit.end);
Assert(a.edit.len == b.edit.len);
return(1);
}
#endif
enum History_Mode{
hist_normal,
hist_backward,
@ -1541,28 +1449,8 @@ internal void
file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str,
History_Mode history_mode){
if (!file->state.undo.undo.edits) return;
#if BUFFER_EXPERIMENT_SCALPEL <= 3
General_Memory *general = &mem->general;
#if FRED_SLOW
if (history_mode == hist_backward)
debug_edit_step_check(step, file->state.undo.history.edits[file->state.undo.edit_history_cursor]);
else if (history_mode == hist_forward)
debug_edit_step_check(step, file->state.undo.history.edits[file->state.undo.history.edit_count]);
switch (step.type){
case ED_UNDO:
{
Assert(file->state.undo.undo.edit_count > 0);
debug_edit_step_check(step, file->state.undo.undo.edits[file->state.undo.undo.edit_count-1]);
}break;
case ED_REDO:
{
Assert(file->state.undo.redo.edit_count > 0);
debug_edit_step_check(step, file->state.undo.redo.edits[file->state.undo.redo.edit_count-1]);
}break;
}
#endif
b32 can_merge = 0, do_merge = 0;
switch (step.type){
case ED_NORMAL:
@ -1709,21 +1597,6 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step
if (history_mode == hist_normal){
file->state.undo.edit_history_cursor = file->state.undo.history.edit_count;
}
#endif
}
inline b32
debug_step_match(Edit_Step a, Edit_Step b){
Assert(a.type == b.type);
Assert(a.can_merge == b.can_merge);
Assert(a.pre_pos == b.pre_pos);
Assert(a.post_pos == b.post_pos);
Assert(a.next_block == b.next_block);
Assert(a.prev_block == b.prev_block);
Assert(a.edit.start == b.edit.start);
Assert(a.edit.end == b.edit.end);
Assert(a.edit.len == b.edit.len);
return 1;
}
inline void
@ -1803,19 +1676,22 @@ file_edit_cursor_fix(System_Functions *system,
view->preferred_x = view_get_cursor_x(view);
view->mark = cursors[cursor_count++].pos + 1;
view->scroll_i = cursors[cursor_count++].pos + 1;
temp_cursor = view_compute_cursor_from_pos(view, view->scroll_i);
y_offset = MOD(view->scroll_y, view->font_height);
i32 new_scroll_i = cursors[cursor_count++].pos + 1;
if (view->scroll_i != new_scroll_i){
view->scroll_i = new_scroll_i;
temp_cursor = view_compute_cursor_from_pos(view, view->scroll_i);
y_offset = MOD(view->scroll_y, view->font_height);
if (view->unwrapped_lines){
y_position = temp_cursor.unwrapped_y + y_offset;
view->target_y += (y_position - view->scroll_y);
view->scroll_y = y_position;
}
else{
y_position = temp_cursor.wrapped_y + y_offset;
view->target_y += (y_position - view->scroll_y);
view->scroll_y = y_position;
if (view->unwrapped_lines){
y_position = temp_cursor.unwrapped_y + y_offset;
view->target_y += (y_position - view->scroll_y);
view->scroll_y = y_position;
}
else{
y_position = temp_cursor.wrapped_y + y_offset;
view->target_y += (y_position - view->scroll_y);
view->scroll_y = y_position;
}
}
}
}
@ -1900,7 +1776,6 @@ internal void
view_do_white_batch_edit(System_Functions *system, Mem_Options *mem, View *view, Editing_File *file,
Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){
if (view->locked) return;
#if BUFFER_EXPERIMENT_SCALPEL <= 3
Assert(file);
ProfileMomentFunction();
@ -1977,7 +1852,6 @@ view_do_white_batch_edit(System_Functions *system, Mem_Options *mem, View *view,
desc.batch_size = batch_size;
file_edit_cursor_fix(system, part, general, file, layout, desc);
#endif
}
inline void
@ -3420,6 +3294,7 @@ interactive_shit(System_Functions *system, View *view, UI_State *state, UI_Layou
if (complete){
view->finished = 1;
interactive_view_complete(view);
result= 1;
}
return(result);
@ -3506,6 +3381,41 @@ do_file_bar(View *view, Editing_File *file, UI_Layout *layout, Render_Target *ta
}
}
internal void
view_reinit_scrolling(View *view){
Editing_File *file = view->file;
f32 w, h;
f32 cursor_x, cursor_y;
f32 target_x, target_y;
view->reinit_scrolling = 0;
target_x = 0;
target_y = 0;
if (file && file_is_ready(file)){
cursor_x = view_get_cursor_x(view);
cursor_y = view_get_cursor_y(view);
w = view_compute_width(view);
h = view_compute_height(view);
if (cursor_x >= target_x + w){
target_x = (f32)(cursor_x - w*.5f);
}
target_y = (f32)FLOOR32(cursor_y - h*.5f);
if (target_y < view->scroll_min_limit) target_y = view->scroll_min_limit;
}
view->target_x = target_x;
view->target_y = target_y;
view->scroll_x = target_x;
view->scroll_y = target_y;
view->prev_target_x = -1000.f;
view->prev_target_y = -1000.f;
}
internal i32
step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rect rect,
b32 is_active, Input_Summary *user_input){
@ -3549,6 +3459,11 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rec
}
}
view->scroll_min_limit = (f32)-widget_height;
if (view->reinit_scrolling){
view_reinit_scrolling(view);
}
// TODO(allen): Split this into passive step and step that depends on input
if (file && !file->state.is_loading){
f32 line_height = (f32)view->font_height;
@ -3892,6 +3807,7 @@ draw_file_view(System_Functions *system, Exchange *exchange,
widget_height = layout.y - rect.y0;
ui_finish_frame(&view->widget.state, &state, &layout, rect, 0, 0);
}
view->scroll_min_limit = (f32)-widget_height;
{
rect.y0 += widget_height;
@ -3910,6 +3826,9 @@ draw_file_view(System_Functions *system, Exchange *exchange,
case VUI_None:
{
if (file && file_is_ready(file)){
if (view->reinit_scrolling){
view_reinit_scrolling(view);
}
result = draw_file_loaded(view, rect, is_active, target);
}
}break;
@ -3970,39 +3889,12 @@ free_file_view(View *view){
general_memory_free(&view->mem->general, view->line_wrap_y);
}
internal
Do_View_Sig(do_file_view){
i32 result = 0;
switch (message){
case VMSG_RESIZE:
case VMSG_STYLE_CHANGE:
{
remeasure_file_view(system, view, rect);
}break;
case VMSG_DRAW:
{
result = draw_file_view(system, exchange, view, active, rect, (view == active), target, user_input);
}break;
case VMSG_STEP:
{
result = step_file_view(system, exchange, view, rect, (view == active), user_input);
}break;
case VMSG_FREE:
{
free_file_view(view);
}break;
}
return result;
}
internal View*
file_view_init(View *view, Editing_Layout *layout,
Working_Set *working_set, Delay *delay,
App_Settings *settings, Hot_Directory *hot_directory,
Mem_Options *mem, Style_Library *styles){
view->do_view = do_file_view;
view->layout = layout;
view->working_set = working_set;
view->delay = delay;
@ -4303,7 +4195,7 @@ inline void
live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *live_set, View *view){
Assert(live_set->count > 0);
--live_set->count;
view->do_view(system, exchange, view, {}, 0, VMSG_FREE, 0, {}, 0);
free_file_view(view);
dll_insert(&live_set->free_sentinel, view);
}

View File

@ -527,17 +527,6 @@ DIRECTORY_CD_SIG(system_directory_cd){
return(result);
}
Sys_File_Paths_Equal_Sig(system_file_paths_equal){
b32 result = 0;
// TODO(someone who knows windows): implement me
AllowLocal(path_a);
AllowLocal(path_b);
return result;
}
internal
Sys_Post_Clipboard_Sig(system_post_clipboard){
if (OpenClipboard(win32vars.window_handle)){