fixed up file track issue
This commit is contained in:
parent
1f064acbb7
commit
30a2a95b69
21
4ed.cpp
21
4ed.cpp
|
@ -353,13 +353,17 @@ COMMAND_DECL(reopen){
|
|||
General_Memory *general = &models->mem.general;
|
||||
|
||||
File_Edit_Positions edit_poss[16];
|
||||
int32_t line_number[16];
|
||||
int32_t column_number[16];
|
||||
View *vptrs[16];
|
||||
i32 vptr_count = 0;
|
||||
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
|
||||
file_view_iter_good(iter);
|
||||
iter = file_view_iter_next(iter)){
|
||||
vptrs[vptr_count] = iter.view;
|
||||
edit_poss[vptr_count] = *iter.view->edit_pos;
|
||||
edit_poss[vptr_count] = iter.view->edit_pos[0];
|
||||
line_number[vptr_count] = iter.view->edit_pos[0].cursor.line;
|
||||
column_number[vptr_count] = iter.view->edit_pos[0].cursor.character;
|
||||
iter.view->edit_pos = 0;
|
||||
++vptr_count;
|
||||
}
|
||||
|
@ -367,13 +371,18 @@ COMMAND_DECL(reopen){
|
|||
file_close(system, general, file);
|
||||
init_normal_file(system, models, file, buffer, size);
|
||||
|
||||
for (i32 i = 0;
|
||||
i < vptr_count;
|
||||
++i){
|
||||
for (i32 i = 0; i < vptr_count; ++i){
|
||||
view_set_file(vptrs[i], file, models);
|
||||
|
||||
int32_t line = line_number[i];
|
||||
int32_t column = column_number[i];
|
||||
|
||||
*vptrs[i]->edit_pos = edit_poss[i];
|
||||
view_set_cursor(vptrs[i], edit_poss[i].cursor,
|
||||
true, view->file_data.unwrapped_lines);
|
||||
Full_Cursor cursor =
|
||||
view_compute_cursor_from_line_pos(vptrs[i], line, column);
|
||||
|
||||
view_set_cursor(vptrs[i], cursor, true,
|
||||
view->file_data.unwrapped_lines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,11 +41,7 @@ struct File_Edit_Positions{
|
|||
i32 last_set_type;
|
||||
b32 in_view;
|
||||
};
|
||||
inline File_Edit_Positions
|
||||
file_edit_positions_zero(){
|
||||
File_Edit_Positions data = {0};
|
||||
return(data);
|
||||
}
|
||||
static File_Edit_Positions null_edit_pos = {0};
|
||||
|
||||
enum Edit_Type{
|
||||
ED_NORMAL,
|
||||
|
|
|
@ -505,14 +505,14 @@ view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){
|
|||
Full_Cursor result;
|
||||
if (view->file_data.unwrapped_lines) result = view_compute_cursor_from_unwrapped_xy(view, seek_x, seek_y);
|
||||
else result = view_compute_cursor_from_wrapped_xy(view, seek_x, seek_y);
|
||||
return result;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline i32
|
||||
view_wrapped_line_span(f32 line_width, f32 max_width){
|
||||
i32 line_count = CEIL32(line_width / max_width);
|
||||
if (line_count == 0) line_count = 1;
|
||||
return line_count;
|
||||
return(line_count);
|
||||
}
|
||||
|
||||
internal i32
|
||||
|
@ -535,7 +535,7 @@ view_compute_lowest_line(View *view){
|
|||
lowest_line += line_span - 1;
|
||||
}
|
||||
}
|
||||
return lowest_line;
|
||||
return(lowest_line);
|
||||
}
|
||||
|
||||
inline i32
|
||||
|
@ -646,10 +646,8 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll,
|
|||
}
|
||||
|
||||
internal void
|
||||
view_set_cursor(View *view,
|
||||
Full_Cursor cursor,
|
||||
b32 set_preferred_x,
|
||||
b32 unwrapped_lines){
|
||||
view_set_cursor(View *view, Full_Cursor cursor,
|
||||
b32 set_preferred_x, b32 unwrapped_lines){
|
||||
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
|
||||
edit_pos_set_cursor_(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||
|
||||
|
|
13
TODO.txt
13
TODO.txt
|
@ -1,10 +1,11 @@
|
|||
|
||||
; Started this list on: (18.01.2016)(dd.mm.yyyy)
|
||||
; This list is an informal todo list, it may very well miss items
|
||||
; checked or unchecked, that I inted to do some day. It is included
|
||||
; in the distribution so that you may take a look and see if your
|
||||
; requested feature is there, and if not, so that you may remind me.
|
||||
; Cheers everyone!
|
||||
;
|
||||
|
||||
; BUGS
|
||||
; [X] '\t' thing
|
||||
; [X] smoothness in smoothscrolling isn't very smooth
|
||||
|
@ -74,6 +75,7 @@
|
|||
; [X] paths with parens in them
|
||||
; [X] killing compilation panel changes active panel
|
||||
; [X] make panel resizing not whacky with child panels
|
||||
; [X] visual studio file saves aren't picked up by the file track system
|
||||
;
|
||||
; [] indication on failure to save
|
||||
; [] history is broken, revist the entire system
|
||||
|
@ -83,12 +85,6 @@
|
|||
; [] view fails to follow cursor when the view is shrunk
|
||||
; [] view fails to follow cursor after deleting long line
|
||||
;
|
||||
;
|
||||
|
||||
; BEFORE I SHIP
|
||||
;
|
||||
; [] occasionally missing the (!) mark on files on windows
|
||||
;
|
||||
|
||||
; TODOS
|
||||
; [X] success message when compiler works
|
||||
|
@ -144,7 +140,7 @@
|
|||
; [] switch to line classification system
|
||||
; [] more built in options for auto indenting
|
||||
;
|
||||
;
|
||||
|
||||
; [] binary buffers
|
||||
; [] commands for resizing panels
|
||||
; [] user file bar string
|
||||
|
@ -273,6 +269,7 @@
|
|||
; [] a triangle rendered for a few frames? color of the dirty markers (not reproduced by me yet)
|
||||
; [] minimize and reopen problem (not reproduced by me yet)
|
||||
;
|
||||
;
|
||||
|
||||
; FANCY-PANTS IDEAS
|
||||
; [] pass messages to 'jobs' to try to avoid cancelling them
|
||||
|
|
|
@ -116,6 +116,17 @@ internal_get_file_index(BY_HANDLE_FILE_INFORMATION info){
|
|||
return(hash);
|
||||
}
|
||||
|
||||
#define FLAGS ( \
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME | \
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME | \
|
||||
FILE_NOTIFY_CHANGE_ATTRIBUTES | \
|
||||
FILE_NOTIFY_CHANGE_SIZE | \
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE | \
|
||||
FILE_NOTIFY_CHANGE_LAST_ACCESS| \
|
||||
FILE_NOTIFY_CHANGE_SECURITY | \
|
||||
FILE_NOTIFY_CHANGE_CREATION | \
|
||||
0)
|
||||
|
||||
FILE_TRACK_LINK File_Track_Result
|
||||
add_listener(File_Track_System *system, char *filename){
|
||||
File_Track_Result result = FileTrack_Good;
|
||||
|
@ -157,8 +168,8 @@ add_listener(File_Track_System *system, char *filename){
|
|||
if (ReadDirectoryChangesW(dir,
|
||||
node->listener.result,
|
||||
sizeof(node->listener.result),
|
||||
0,
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE,
|
||||
1,
|
||||
FLAGS,
|
||||
0,
|
||||
&node->listener.overlapped,
|
||||
0)){
|
||||
|
@ -250,6 +261,7 @@ remove_listener(File_Track_System *system, char *filename){
|
|||
|
||||
if (node->listener.user_count == 0){
|
||||
insert_node(&vars->free_sentinel, &node->node);
|
||||
CancelIo(win32_dir->dir);
|
||||
CloseHandle(win32_dir->dir);
|
||||
internal_free_slot(tables, dir_lookup);
|
||||
}
|
||||
|
@ -316,6 +328,10 @@ get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *
|
|||
File_Track_Result result = FileTrack_NoMoreEvents;
|
||||
Win32_File_Track_Vars *vars = to_vars(system);
|
||||
|
||||
static int32_t has_buffered_event = 0;
|
||||
static DWORD offset = 0;
|
||||
static Win32_Directory_Listener listener;
|
||||
|
||||
EnterCriticalSection(&vars->table_lock);
|
||||
|
||||
{
|
||||
|
@ -323,78 +339,83 @@ get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *
|
|||
DWORD length = 0;
|
||||
ULONG_PTR key = 0;
|
||||
|
||||
if (GetQueuedCompletionStatus(vars->iocp,
|
||||
&length,
|
||||
&key,
|
||||
&overlapped,
|
||||
0)){
|
||||
|
||||
Win32_Directory_Listener *listener_ptr = (Win32_Directory_Listener*)overlapped;
|
||||
|
||||
// NOTE(allen): Get a copy of the state of this node so we can set the node
|
||||
// to work listening for changes again right away.
|
||||
Win32_Directory_Listener listener = *listener_ptr;
|
||||
|
||||
ZeroStruct(listener_ptr->overlapped);
|
||||
ReadDirectoryChangesW(listener_ptr->dir,
|
||||
listener_ptr->result,
|
||||
sizeof(listener_ptr->result),
|
||||
0,
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE,
|
||||
0,
|
||||
&listener_ptr->overlapped,
|
||||
0);
|
||||
|
||||
char *listener_buffer = listener.result;
|
||||
DWORD offset = 0;
|
||||
FILE_NOTIFY_INFORMATION *info = 0;
|
||||
|
||||
for (;;){
|
||||
info = (FILE_NOTIFY_INFORMATION*)(listener_buffer + offset);
|
||||
int32_t has_result = 0;
|
||||
|
||||
if (has_buffered_event){
|
||||
has_buffered_event = 0;
|
||||
has_result = 1;
|
||||
}
|
||||
else{
|
||||
if (GetQueuedCompletionStatus(vars->iocp,
|
||||
&length,
|
||||
&key,
|
||||
&overlapped,
|
||||
0)){
|
||||
Win32_Directory_Listener *listener_ptr = (Win32_Directory_Listener*)overlapped;
|
||||
|
||||
int32_t len = info->FileNameLength / 2;
|
||||
int32_t dir_len = GetFinalPathNameByHandle(listener.dir, 0, 0,
|
||||
FILE_NAME_NORMALIZED);
|
||||
int32_t req_size = dir_len + 1 + len;
|
||||
*size = req_size;
|
||||
if (req_size < max){
|
||||
int32_t pos = 0;
|
||||
|
||||
pos = GetFinalPathNameByHandle(listener.dir, buffer, max,
|
||||
FILE_NAME_NORMALIZED);
|
||||
buffer[pos++] = '\\';
|
||||
|
||||
for (int32_t i = 0; i < len; ++i, ++pos){
|
||||
buffer[pos] = (char)info->FileName[i];
|
||||
}
|
||||
|
||||
if (buffer[0] == '\\'){
|
||||
for (int32_t i = 0; i+4 < pos; ++i){
|
||||
buffer[i] = buffer[i+4];
|
||||
}
|
||||
*size -= 4;
|
||||
}
|
||||
|
||||
result = FileTrack_Good;
|
||||
}
|
||||
else{
|
||||
// TODO(allen): Need some way to stash this result so that if the
|
||||
// user comes back with more memory we can give them the change
|
||||
// notification they missed.
|
||||
result = FileTrack_MemoryTooSmall;
|
||||
// NOTE(allen): Get a copy of the state of this node so we can set the node
|
||||
// to work listening for changes again right away.
|
||||
listener = *listener_ptr;
|
||||
|
||||
ZeroStruct(listener_ptr->overlapped);
|
||||
ReadDirectoryChangesW(listener_ptr->dir,
|
||||
listener_ptr->result,
|
||||
sizeof(listener_ptr->result),
|
||||
1,
|
||||
FLAGS,
|
||||
0,
|
||||
&listener_ptr->overlapped,
|
||||
0);
|
||||
|
||||
offset = 0;
|
||||
has_result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_result){
|
||||
|
||||
FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*)(listener.result + offset);
|
||||
|
||||
int32_t len = info->FileNameLength / 2;
|
||||
int32_t dir_len = GetFinalPathNameByHandle(listener.dir, 0, 0,
|
||||
FILE_NAME_NORMALIZED);
|
||||
|
||||
int32_t req_size = dir_len + 1 + len;
|
||||
*size = req_size;
|
||||
if (req_size < max){
|
||||
int32_t pos = 0;
|
||||
|
||||
pos = GetFinalPathNameByHandle(listener.dir, buffer, max,
|
||||
FILE_NAME_NORMALIZED);
|
||||
buffer[pos++] = '\\';
|
||||
|
||||
for (int32_t i = 0; i < len; ++i, ++pos){
|
||||
buffer[pos] = (char)info->FileName[i];
|
||||
}
|
||||
|
||||
if (info->NextEntryOffset != 0){
|
||||
// TODO(allen): We're not ready to handle this yet.
|
||||
// For now I am breaking. In the future, if there
|
||||
// are more results we should stash them and return
|
||||
// them in future calls.
|
||||
offset += info->NextEntryOffset;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
if (buffer[0] == '\\'){
|
||||
for (int32_t i = 0; i+4 < pos; ++i){
|
||||
buffer[i] = buffer[i+4];
|
||||
}
|
||||
*size -= 4;
|
||||
}
|
||||
|
||||
result = FileTrack_Good;
|
||||
}
|
||||
else{
|
||||
// TODO(allen): Need some way to stash this result so that if the
|
||||
// user comes back with more memory we can give them the change
|
||||
// notification they missed.
|
||||
result = FileTrack_MemoryTooSmall;
|
||||
}
|
||||
|
||||
if (info->NextEntryOffset != 0){
|
||||
// TODO(allen): We're not ready to handle this yet.
|
||||
// For now I am breaking. In the future, if there
|
||||
// are more results we should stash them and return
|
||||
// them in future calls.
|
||||
offset += info->NextEntryOffset;
|
||||
has_buffered_event = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -424,6 +445,9 @@ shut_down_track_system(File_Track_System *system){
|
|||
|
||||
if (!entry_is_available(entry)){
|
||||
Win32_File_Track_Entry *win32_entry = (Win32_File_Track_Entry*)entry;
|
||||
if (!CancelIo(win32_entry->dir)){
|
||||
win32_result = 1;
|
||||
}
|
||||
if (!CloseHandle(win32_entry->dir)){
|
||||
win32_result = 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue