search all, and jump to location with return appears to be working

master
Allen Webster 2016-07-12 14:20:06 -04:00
parent 174ff25d1a
commit add72934e0
13 changed files with 1118 additions and 1054 deletions

View File

@ -45,6 +45,7 @@ Coming Soon</i><div>
<li><a href='#buffer_boundary_seek_doc'>buffer_boundary_seek</a></li>
<li><a href='#buffer_read_range_doc'>buffer_read_range</a></li>
<li><a href='#buffer_replace_range_doc'>buffer_replace_range</a></li>
<li><a href='#buffer_compute_cursor_doc'>buffer_compute_cursor</a></li>
<li><a href='#buffer_batch_edit_doc'>buffer_batch_edit</a></li>
<li><a href='#buffer_set_setting_doc'>buffer_set_setting</a></li>
<li><a href='#buffer_auto_indent_doc'>buffer_auto_indent</a></li>
@ -62,6 +63,7 @@ Coming Soon</i><div>
<li><a href='#view_set_split_proportion_doc'>view_set_split_proportion</a></li>
<li><a href='#view_compute_cursor_doc'>view_compute_cursor</a></li>
<li><a href='#view_set_cursor_doc'>view_set_cursor</a></li>
<li><a href='#view_set_scroll_doc'>view_set_scroll</a></li>
<li><a href='#view_set_mark_doc'>view_set_mark</a></li>
<li><a href='#view_set_highlight_doc'>view_set_highlight</a></li>
<li><a href='#view_set_buffer_doc'>view_set_buffer</a></li>
@ -123,6 +125,7 @@ Coming Soon</i><div>
<li><a href='#Buffer_Identifier_doc'>Buffer_Identifier</a></li>
<li><a href='#GUI_Scroll_Vars_doc'>GUI_Scroll_Vars</a></li>
<li><a href='#Full_Cursor_doc'>Full_Cursor</a></li>
<li><a href='#Partial_Cursor_doc'>Partial_Cursor</a></li>
<li><a href='#Buffer_Seek_doc'>Buffer_Seek</a></li>
<li><a href='#Buffer_Edit_doc'>Buffer_Edit</a></li>
<li><a href='#Buffer_Summary_doc'>Buffer_Summary</a></li>
@ -258,7 +261,7 @@ first len character of the clipboard contents. The output string is not null te
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns the summary of the first buffer in a buffer loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call begins a loop across all the buffers.
If the buffer returned does not exist, the loop is finished.
Buffers should not be killed durring a buffer loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_buffer_next_doc'>get_buffer_next</a></div></div><hr>
Buffers should not be killed durring a buffer loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Summary_doc'>Buffer_Summary</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_buffer_next_doc'>get_buffer_next</a></div></div><hr>
<div id='get_buffer_next_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.8: get_buffer_next</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->get_buffer_next(
@ -276,7 +279,7 @@ Buffers should not be killed durring a buffer loop.</div><div style='margin-top:
The global buffer order is kept roughly in the order of most recently used to least recently used.
If the buffer outputted does not exist, the loop is finished.
Buffers should not be killed or created durring a buffer loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_buffer_first_doc'>get_buffer_first</a></div></div><hr>
Buffers should not be killed or created durring a buffer loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Summary_doc'>Buffer_Summary</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_buffer_first_doc'>get_buffer_first</a></div></div><hr>
<div id='get_buffer_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.9: get_buffer</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Buffer_Summary app->get_buffer(
@ -290,7 +293,7 @@ Buffers should not be killed or created durring a buffer loop.</div><div style='
<div style='font-weight: 600;'>access</div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The access parameter determines what levels of protection this call can access.</div></div>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated buffer if it exists and is accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_ID_doc'>Buffer_ID</a></div></div><hr>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated buffer if it exists and is accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Summary_doc'>Buffer_Summary</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_ID_doc'>Buffer_ID</a></div></div><hr>
<div id='get_buffer_by_name_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.10: get_buffer_by_name</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Buffer_Summary app->get_buffer_by_name(
@ -308,7 +311,7 @@ Buffers should not be killed or created durring a buffer loop.</div><div style='
<div style='font-weight: 600;'>access</div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The access parameter determines what levels of protection this call can access.</div></div>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated buffer if it exists and is accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated buffer if it exists and is accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Summary_doc'>Buffer_Summary</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
<div id='buffer_boundary_seek_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.11: buffer_boundary_seek</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->buffer_boundary_seek(
@ -392,8 +395,28 @@ from start to end.
This call fails if the buffer does not exist, or if the replace
range is not within the bounds of the buffer.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
<div id='buffer_compute_cursor_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.14: buffer_compute_cursor</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_compute_cursor(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>Buffer_Seek seek,<br>Partial_Cursor *cursor_out<br></div>)
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Parameters</i></b></div><div>
<div style='font-weight: 600;'>buffer</div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The buffer parameter specifies the buffer on which to run the cursor computation.</div></div>
</div>
<div>
<div style='font-weight: 600;'>seek</div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The seek parameter specifies the target position for the seek.</div></div>
</div>
<div>
<div style='font-weight: 600;'>cursor_out</div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>On success this struct is filled with the result of the seek.</div></div>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Computes a Partial_Cursor for the given seek position with no side effects.
The seek position must be one of the types supported by Partial_Cursor. Those
types are absolute position and line,column position.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_doc'>Buffer_Seek</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Partial_Cursor_doc'>Partial_Cursor</a></div></div><hr>
<div id='buffer_batch_edit_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.14: buffer_batch_edit</h4>
<h4>&sect;3.3.15: buffer_batch_edit</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_batch_edit(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>char *str,<br>int32_t str_len,<br>Buffer_Edit *edits,<br>int32_t edit_count,<br>Buffer_Batch_Edit_Type type<br></div>)
</div>
@ -419,7 +442,7 @@ range is not within the bounds of the buffer.</div><div style='margin-top: 3mm;
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero if the batch edit succeeds.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Edit_doc'>Buffer_Edit</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Batch_Edit_Type_doc'>Buffer_Batch_Edit_Type</a></div></div><hr>
<div id='buffer_set_setting_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.15: buffer_set_setting</h4>
<h4>&sect;3.3.16: buffer_set_setting</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_set_setting(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>Buffer_Setting_ID setting,<br>int32_t value<br></div>)
</div>
@ -437,7 +460,7 @@ range is not within the bounds of the buffer.</div><div style='margin-top: 3mm;
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Setting_ID_doc'>Buffer_Setting_ID</a></div></div><hr>
<div id='buffer_auto_indent_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.16: buffer_auto_indent</h4>
<h4>&sect;3.3.17: buffer_auto_indent</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->buffer_auto_indent(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>int32_t start,<br>int32_t end,<br>int32_t tab_width,<br>Auto_Indent_Flag flags<br></div>)
</div>
@ -466,7 +489,7 @@ start to end by inserting spaces or tabs at the beginning of the lines.
If the buffer does not have lexing enabled or the lexing job has not
completed this function will fail.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Auto_Indent_Flag_doc'>Auto_Indent_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
<div id='create_buffer_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.17: create_buffer</h4>
<h4>&sect;3.3.18: create_buffer</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Buffer_Summary app->create_buffer(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *filename,<br>int32_t filename_len,<br>Buffer_Create_Flag flags<br></div>)
</div>
@ -486,9 +509,9 @@ completed this function will fail.</div><div style='margin-top: 3mm; margin-bott
exists the existing buffer is returned in the Buffer_Summary and no new buffer is created.
If the buffer does not exist a new buffer is created and named after the given filename. If
the filename corresponds to a file on the disk that file is loaded and put into buffer, if
the filename does not correspond to a file on disk the buffer is created empty.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Create_Flag_doc'>Buffer_Create_Flag</a></div></div><hr>
the filename does not correspond to a file on disk the buffer is created empty.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Summary_doc'>Buffer_Summary</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Create_Flag_doc'>Buffer_Create_Flag</a></div></div><hr>
<div id='save_buffer_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.18: save_buffer</h4>
<h4>&sect;3.3.19: save_buffer</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->save_buffer(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Summary *buffer,<br>char *filename,<br>int32_t filename_len,<br>uint32_t flags<br></div>)
</div>
@ -510,7 +533,7 @@ the filename does not correspond to a file on disk the buffer is created empty.<
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div></div><hr>
<div id='kill_buffer_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.19: kill_buffer</h4>
<h4>&sect;3.3.20: kill_buffer</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->kill_buffer(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Buffer_Identifier buffer,<br>View_ID view_id,<br>Buffer_Kill_Flag flags<br></div>)
</div>
@ -530,7 +553,7 @@ the filename does not correspond to a file on disk the buffer is created empty.<
dialogue needs to be displayed the provided view is used to show the dialogue.
If the view is not open the kill fails.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Kill_Flag_doc'>Buffer_Kill_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Identifier_doc'>Buffer_Identifier</a></div></div><hr>
<div id='get_view_first_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.20: get_view_first</h4>
<h4>&sect;3.3.21: get_view_first</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->get_view_first(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Access_Flag access<br></div>)
</div>
@ -543,7 +566,7 @@ If the view is not open the kill fails.</div><div style='margin-top: 3mm; margin
If the View_Summary returned is a null summary, the loop is finished.
Views should not be closed or opened durring a view loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_view_next_doc'>get_view_next</a></div></div><hr>
<div id='get_view_next_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.21: get_view_next</h4>
<h4>&sect;3.3.22: get_view_next</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->get_view_next(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Access_Flag access<br></div>)
</div>
@ -560,7 +583,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
If the view outputted does not exist, the loop is finished.
Views should not be closed or opened durring a view loop.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_view_first_doc'>get_view_first</a></div></div><hr>
<div id='get_view_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.22: get_view</h4>
<h4>&sect;3.3.23: get_view</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->get_view(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_ID view_id,<br>Access_Flag access<br></div>)
</div>
@ -574,7 +597,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the indicated view if it is open and accessible.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
<div id='get_active_view_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.23: get_active_view</h4>
<h4>&sect;3.3.24: get_active_view</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->get_active_view(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Access_Flag access<br></div>)
</div>
@ -584,7 +607,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns a summary that describes the active view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#set_active_view_doc'>set_active_view</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
<div id='open_view_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.24: open_view</h4>
<h4>&sect;3.3.25: open_view</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>View_Summary app->open_view(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view_location,<br>View_Split_Position position<br></div>)
</div>
@ -600,7 +623,7 @@ Views should not be closed or opened durring a view loop.</div><div style='margi
returns a null summary.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>4coder is built with a limit of 16 views. If 16 views are already open when this is called the
call will fail.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#View_Split_Position_doc'>View_Split_Position</a></div></div><hr>
<div id='close_view_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.25: close_view</h4>
<h4>&sect;3.3.26: close_view</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->close_view(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view<br></div>)
</div>
@ -613,7 +636,7 @@ If the given view is the active view, the next active view in the global
order of view will be made active.
If the given view is the last open view in the system, the call will fail.</div></div><hr>
<div id='set_active_view_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.26: set_active_view</h4>
<h4>&sect;3.3.27: set_active_view</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->set_active_view(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view<br></div>)
</div>
@ -625,7 +648,7 @@ If the given view is the last open view in the system, the call will fail.</div>
active view, and takes subsequent commands and is returned
from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#get_active_view_doc'>get_active_view</a></div></div><hr>
<div id='view_set_setting_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.27: view_set_setting</h4>
<h4>&sect;3.3.28: view_set_setting</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_setting(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>View_Setting_ID setting,<br>int32_t value<br></div>)
</div>
@ -643,7 +666,7 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#View_Setting_ID_doc'>View_Setting_ID</a></div></div><hr>
<div id='view_set_split_proportion_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.28: view_set_split_proportion</h4>
<h4>&sect;3.3.29: view_set_split_proportion</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_split_proportion(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>float t<br></div>)
</div>
@ -657,7 +680,7 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div></div><hr>
<div id='view_compute_cursor_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.29: view_compute_cursor</h4>
<h4>&sect;3.3.30: view_compute_cursor</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_compute_cursor(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_Seek seek,<br>Full_Cursor *cursor_out<br></div>)
</div>
@ -675,7 +698,7 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Computes a Full_Cursor for the given seek position with no side effects.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_doc'>Buffer_Seek</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Full_Cursor_doc'>Full_Cursor</a></div></div><hr>
<div id='view_set_cursor_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.30: view_set_cursor</h4>
<h4>&sect;3.3.31: view_set_cursor</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_cursor(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_Seek seek,<br>bool32 set_preferred_x<br></div>)
</div>
@ -694,8 +717,14 @@ from get_active_view.</div><div style='margin-top: 3mm; margin-bottom: 3mm; colo
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call sets the the view's cursor position. set_preferred_x should usually be true
unless the change in cursor position is is a vertical motion that tries to keep the
cursor in the same column or x position.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_doc'>Buffer_Seek</a></div></div><hr>
<div id='view_set_scroll_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.32: view_set_scroll</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_scroll(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>GUI_Scroll_Vars scroll<br></div>)
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#GUI_Scroll_Vars_doc'>GUI_Scroll_Vars</a></div></div><hr>
<div id='view_set_mark_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.31: view_set_mark</h4>
<h4>&sect;3.3.33: view_set_mark</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_mark(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_Seek seek<br></div>)
</div>
@ -709,7 +738,7 @@ cursor in the same column or x position.</div><div style='margin-top: 3mm; margi
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call sets the the view's mark position.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_doc'>Buffer_Seek</a></div></div><hr>
<div id='view_set_highlight_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.32: view_set_highlight</h4>
<h4>&sect;3.3.34: view_set_highlight</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_highlight(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>int32_t start,<br>int32_t end,<br>bool32 turn_on<br></div>)
</div>
@ -734,7 +763,7 @@ is set to true the highlight will be shown and the cursor will be hidden. After
that either setting the with view_set_cursor or calling view_set_highlight and
the turn_on set to false, will switch back to showing the cursor.</div></div><hr>
<div id='view_set_buffer_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.33: view_set_buffer</h4>
<h4>&sect;3.3.35: view_set_buffer</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_set_buffer(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>Buffer_ID buffer_id,<br>Set_Buffer_Flag flags<br></div>)
</div>
@ -753,7 +782,7 @@ the turn_on set to false, will switch back to showing the cursor.</div></div><hr
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>On success view_set_buffer sets the specified view's current buffer and
cancels and dialogue shown in the view and displays the file.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Set_Buffer_Flag_doc'>Set_Buffer_Flag</a></div></div><hr>
<div id='view_post_fade_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.34: view_post_fade</h4>
<h4>&sect;3.3.36: view_post_fade</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->view_post_fade(
<div style='margin-left: 4mm;'>Application_Links *app,<br>View_Summary *view,<br>float seconds,<br>int32_t start,<br>int32_t end,<br>int_color color<br></div>)
</div>
@ -779,7 +808,7 @@ cancels and dialogue shown in the view and displays the file.</div><div style='m
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#int_color_doc'>int_color</a></div></div><hr>
<div id='get_user_input_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.35: get_user_input</h4>
<h4>&sect;3.3.37: get_user_input</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>User_Input app->get_user_input(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Input_Type_Flag get_type,<br>Input_Type_Flag abort_type<br></div>)
</div>
@ -797,19 +826,19 @@ command is executed an abort signal is returned. If an abort signal is ever ret
command should finish execution without any more calls that preempt the command.
If a get condition is met the user input is returned.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Input_Type_Flag_doc'>Input_Type_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#User_Input_doc'>User_Input</a></div></div><hr>
<div id='get_command_input_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.36: get_command_input</h4>
<h4>&sect;3.3.38: get_command_input</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>User_Input app->get_command_input(
<div style='margin-left: 4mm;'>Application_Links *app<br></div>)
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns the input that triggered the currently executing command.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#User_Input_doc'>User_Input</a></div></div><hr>
<div id='get_mouse_state_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.37: get_mouse_state</h4>
<h4>&sect;3.3.39: get_mouse_state</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>Mouse_State app->get_mouse_state(
<div style='margin-left: 4mm;'>Application_Links *app<br></div>)
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns the current mouse state as of the beginning of the frame.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Mouse_State_doc'>Mouse_State</a></div></div><hr>
<div id='start_query_bar_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.38: start_query_bar</h4>
<h4>&sect;3.3.40: start_query_bar</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->start_query_bar(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Query_Bar *bar,<br>uint32_t flags<br></div>)
</div>
@ -829,7 +858,7 @@ can be changed after the call to start_query_bar and the query bar shown by 4cod
will reflect the change. Since the bar stops showing when the command exits the
only use for this call is in an interactive command that makes calls to get_user_input.</div></div><hr>
<div id='end_query_bar_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.39: end_query_bar</h4>
<h4>&sect;3.3.41: end_query_bar</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->end_query_bar(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Query_Bar *bar,<br>uint32_t flags<br></div>)
</div>
@ -843,7 +872,7 @@ only use for this call is in an interactive command that makes calls to get_user
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Stops showing the particular query bar specified by the bar parameter.</div></div><hr>
<div id='print_message_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.40: print_message</h4>
<h4>&sect;3.3.42: print_message</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->print_message(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *str,<br>int32_t len<br></div>)
</div>
@ -857,7 +886,7 @@ only use for this call is in an interactive command that makes calls to get_user
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call posts a string to the *messages* buffer.</div></div><hr>
<div id='change_theme_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.41: change_theme</h4>
<h4>&sect;3.3.43: change_theme</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->change_theme(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *name,<br>int32_t len<br></div>)
</div>
@ -871,7 +900,7 @@ only use for this call is in an interactive command that makes calls to get_user
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call changes 4coder's theme to one of the built in themes.</div></div><hr>
<div id='change_font_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.42: change_font</h4>
<h4>&sect;3.3.44: change_font</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->change_font(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *name,<br>int32_t len<br></div>)
</div>
@ -885,7 +914,7 @@ only use for this call is in an interactive command that makes calls to get_user
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call changes 4coder's font to one of the built in fonts.</div></div><hr>
<div id='set_theme_colors_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.43: set_theme_colors</h4>
<h4>&sect;3.3.45: set_theme_colors</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->set_theme_colors(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Theme_Color *colors,<br>int32_t count<br></div>)
</div>
@ -901,7 +930,7 @@ only use for this call is in an interactive command that makes calls to get_user
struct's tag is set to the color code in the struct. If the tag value is invalid
no change is made to the color pallet.</div></div><hr>
<div id='get_theme_colors_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.44: get_theme_colors</h4>
<h4>&sect;3.3.46: get_theme_colors</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->get_theme_colors(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Theme_Color *colors,<br>int32_t count<br></div>)
</div>
@ -917,7 +946,7 @@ no change is made to the color pallet.</div></div><hr>
color from the slot in the main color pallet specified by the tag. If the tag
value is invalid the color is filled with black.</div></div><hr>
<div id='directory_get_hot_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.45: directory_get_hot</h4>
<h4>&sect;3.3.47: directory_get_hot</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>int32_t app->directory_get_hot(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *out,<br>int32_t capacity<br></div>)
</div>
@ -935,7 +964,7 @@ accessed in the GUI. Whenever the GUI is opened it shows the hot directory.
In the future this will be deprecated and eliminated in favor of more flexible
directories controlled on the custom side.</div></div><hr>
<div id='get_file_list_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.46: get_file_list</h4>
<h4>&sect;3.3.48: get_file_list</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>File_List app->get_file_list(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *dir,<br>int32_t len<br></div>)
</div>
@ -951,7 +980,7 @@ directories controlled on the custom side.</div></div><hr>
the specified directory. The File_List returned should be passed to free_file_list
when it is no longer in use.</div></div><hr>
<div id='free_file_list_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.47: free_file_list</h4>
<h4>&sect;3.3.49: free_file_list</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->free_file_list(
<div style='margin-left: 4mm;'>Application_Links *app,<br>File_List list<br></div>)
</div>
@ -961,25 +990,25 @@ when it is no longer in use.</div></div><hr>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>After this call the file list passed in should not be read or written to.</div></div><hr>
<div id='memory_allocate_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.48: memory_allocate</h4>
<h4>&sect;3.3.50: memory_allocate</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void* app->memory_allocate(
<div style='margin-left: 4mm;'>Application_Links *app,<br>int32_t size<br></div>)
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div></div><hr>
<div id='memory_set_protection_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.49: memory_set_protection</h4>
<h4>&sect;3.3.51: memory_set_protection</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->memory_set_protection(
<div style='margin-left: 4mm;'>Application_Links *app,<br>void *ptr,<br>int32_t size,<br>Memory_Protect_Flags flags<br></div>)
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div></div><hr>
<div id='memory_free_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.50: memory_free</h4>
<h4>&sect;3.3.52: memory_free</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->memory_free(
<div style='margin-left: 4mm;'>Application_Links *app,<br>void *mem,<br>int32_t size<br></div>)
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>TODO</div></div><hr>
<div id='file_exists_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.51: file_exists</h4>
<h4>&sect;3.3.53: file_exists</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->file_exists(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *filename,<br>int len<br></div>)
</div>
@ -993,7 +1022,7 @@ when it is no longer in use.</div></div><hr>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero if and only if the file exists.</div></div><hr>
<div id='directory_cd_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.52: directory_cd</h4>
<h4>&sect;3.3.54: directory_cd</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->directory_cd(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *dir,<br>int *len,<br>int capacity,<br>char *rel_path,<br>int rel_len<br></div>)
</div>
@ -1026,7 +1055,7 @@ will contain "C:/Users/MySelf/Documents" and len will contain the length of that
string. This call can also be used with rel set to ".." to traverse to parent
folders.</div></div><hr>
<div id='get_4ed_path_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.53: get_4ed_path</h4>
<h4>&sect;3.3.55: get_4ed_path</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>bool32 app->get_4ed_path(
<div style='margin-left: 4mm;'>Application_Links *app,<br>char *out,<br>int32_t capacity<br></div>)
</div>
@ -1040,7 +1069,7 @@ folders.</div></div><hr>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Return</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>This call returns non-zero on success.</div></div><hr>
<div id='show_mouse_cursor_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.3.54: show_mouse_cursor</h4>
<h4>&sect;3.3.56: show_mouse_cursor</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>void app->show_mouse_cursor(
<div style='margin-left: 4mm;'>Application_Links *app,<br>Mouse_Cursor_Show_Type show<br></div>)
</div>
@ -1111,18 +1140,6 @@ the range [1,16].</div></div><hr>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_null is set aside to always be zero and is not associated with any command.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_center_view</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_center_view centers the view vertically on the cursor.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_left_adjust_view</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_left_adjust_view adjusts the view to be just left of the cursor's position.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_word_complete</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_word_complete begins or continues cycling through completions for a partial word.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_undo</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_undo performs a standard undo behavior.</div></div>
</div>
@ -1147,14 +1164,6 @@ the range [1,16].</div></div><hr>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_interactive_open begins an interactive dialogue to open a file into a buffer.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_reopen</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_reopen reloads the active buffer's associated file and discards the old buffer contents for the reloaded file.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_save</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_save saves the buffer's contents into the associated file.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_save_as</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_save_as does not currently work and is likely to be removed rather that fixed.</div></div>
</div>
@ -1167,6 +1176,14 @@ the range [1,16].</div></div><hr>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_interactive_kill_buffer begins an interactive dialogue to choose an open buffer to kill.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_reopen</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_reopen reloads the active buffer's associated file and discards the old buffer contents for the reloaded file.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_save</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_save saves the buffer's contents into the associated file.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>cmdid_kill_buffer</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>cmdid_kill_buffer tries to kill the active buffer.</div></div>
</div>
@ -1265,9 +1282,20 @@ the range [1,16].</div></div><hr>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BufferSetting_Eol</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The BufferSetting_Eol setting spcifies how line ends should be saved to the backing file.
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The BufferSetting_Eol setting specifies how line ends should be saved to the backing file.
A 1 indicates dos endings "\r\n" and a 0 indicates nix endings "\n".</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BufferSetting_Unimportant</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The BufferSetting_Unimportant setting marks a buffer so that it's dirty state will be completely
ignored. This means the "dirty" star is hidden and the buffer can be closed without presenting an
"are you sure" dialogue screen.</div></div>
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BufferSetting_ReadOnly</span></span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The BufferSetting_ReadOnly setting marks a buffer so that it can only be returned from buffer
access calls that include an AccessProtected flag.</div></div>
</div>
</div><hr>
<div id='View_Setting_ID_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.12: View_Setting_ID</h4>
@ -1393,7 +1421,7 @@ Flags can be combined with bit or to specify a state with multiple modifiers.</d
</div>
<div>
<div><span style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>BufferCreate_AlwaysNew</span> = 0x2</span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>When BufferCreate_AlwaysNew is et it indicates the buffer should be
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>When BufferCreate_AlwaysNew is set it indicates the buffer should be
cleared to empty even if it's associated file already has content.</div></div>
</div>
</div><hr>
@ -1832,7 +1860,8 @@ float wrapped_y;<br>
};<br>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Full_Cursor describes the position of a cursor in every buffer
coordinate system supported by 4coder.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div>
coordinate system supported by 4coder. This cursor type requires that
the buffer is associated with a view to give the x/y values meaning.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div>
<div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>pos</span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the cursor's position in absolute positioning.</div></div>
</div>
@ -1861,8 +1890,34 @@ coordinate system supported by 4coder.</div><div style='margin-top: 3mm; margin-
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the y position measured with wrapped lines.</div></div>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
<div id='Partial_Cursor_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.35: Partial_Cursor</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Partial_Cursor {<br>
<div style='margin-left: 8mm;'>
int32_t pos;<br>
int32_t line;<br>
int32_t character;<br>
</div>
};<br>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Partial_Cursor describes the position of a cursor in all of
the coordinate systems that a invariant to the View. In other words
the coordinate systems available here can be used on a buffer that is
not currently associated with a View.</div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div>
<div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>pos</span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the cursor's position in absolute positioning.</div></div>
</div>
<div>
<div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>line</span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the number of the line where the cursor is located. This field is one based.</div></div>
</div>
<div>
<div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>character</span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the number of the column where the cursor is located. This field is one based.</div></div>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
<div id='Buffer_Seek_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.35: Buffer_Seek</h4>
<h4>&sect;3.4.36: Buffer_Seek</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Seek {<br>
<div style='margin-left: 8mm;'>
Buffer_Seek_Type type;<br>
@ -1927,7 +1982,7 @@ for concisely creating Buffer_Seek structs. They can be found in 4coder_buffer_
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_Type_doc'>Buffer_Seek_Type</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr>
<div id='Buffer_Edit_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.36: Buffer_Edit</h4>
<h4>&sect;3.4.37: Buffer_Edit</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Edit {<br>
<div style='margin-left: 8mm;'>
int32_t str_start;<br>
@ -1957,7 +2012,7 @@ will be replaced into the buffer.</div><div style='margin-top: 3mm; margin-botto
</div>
</div><hr>
<div id='Buffer_Summary_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.37: Buffer_Summary</h4>
<h4>&sect;3.4.38: Buffer_Summary</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Summary {<br>
<div style='margin-left: 8mm;'>
bool32 exists;<br>
@ -2032,7 +2087,7 @@ bool32 unwrapped_lines;<br>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
<div id='View_Summary_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.38: View_Summary</h4>
<h4>&sect;3.4.39: View_Summary</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct View_Summary {<br>
<div style='margin-left: 8mm;'>
bool32 exists;<br>
@ -2094,15 +2149,15 @@ GUI_Scroll_Vars scroll_vars;<br>
</div>
<div>
<div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>file_region</span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This feature is not fully implemented yet.</div></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>If this is not a null summary, this describes the screen position in which this view's buffer is displayed.</div></div>
</div>
<div>
<div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>scroll_vars</span></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This feature is not fully implemented yet.</div></div>
<div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>If this is not a null summary, this describes the scrolling position inside the view.</div></div>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div></div><hr>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Access_Flag_doc'>Access_Flag</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Full_Cursor_doc'>Full_Cursor</a></div></div><hr>
<div id='User_Input_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.39: User_Input</h4>
<h4>&sect;3.4.40: User_Input</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct User_Input {<br>
<div style='margin-left: 8mm;'>
User_Input_Type_ID type;<br>
@ -2139,7 +2194,7 @@ Generic_Command command;<br>
</div>
<div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#User_Input_Type_ID_doc'>User_Input_Type_ID</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Generic_Command_doc'>Generic_Command</a></div></div><hr>
<div id='Query_Bar_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.40: Query_Bar</h4>
<h4>&sect;3.4.41: Query_Bar</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Query_Bar {<br>
<div style='margin-left: 8mm;'>
String prompt;<br>
@ -2158,7 +2213,7 @@ that will be displayed as a drop down bar durring an interactive command.</div><
</div>
</div><hr>
<div id='Event_Message_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.41: Event_Message</h4>
<h4>&sect;3.4.42: Event_Message</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Event_Message {<br>
<div style='margin-left: 8mm;'>
int type;<br>
@ -2171,7 +2226,7 @@ int type;<br>
</div>
</div><hr>
<div id='Theme_Color_doc' style='margin-bottom: 1cm;'>
<h4>&sect;3.4.42: Theme_Color</h4>
<h4>&sect;3.4.43: Theme_Color</h4>
<div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Theme_Color {<br>
<div style='margin-left: 8mm;'>
Style_Tag tag;<br>

View File

@ -11,6 +11,7 @@
#define BUFFER_BOUNDARY_SEEK_SIG(n) int32_t n(Application_Links *app, Buffer_Summary *buffer, int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)
#define BUFFER_READ_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *out)
#define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len)
#define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)
#define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type)
#define BUFFER_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value)
#define BUFFER_AUTO_INDENT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, int32_t tab_width, Auto_Indent_Flag flags)
@ -28,6 +29,7 @@
#define VIEW_SET_SPLIT_PROPORTION_SIG(n) bool32 n(Application_Links *app, View_Summary *view, float t)
#define VIEW_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out)
#define VIEW_SET_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x)
#define VIEW_SET_SCROLL_SIG(n) bool32 n(Application_Links *app, View_Summary *view, GUI_Scroll_Vars scroll)
#define VIEW_SET_MARK_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek)
#define VIEW_SET_HIGHLIGHT_SIG(n) bool32 n(Application_Links *app, View_Summary *view, int32_t start, int32_t end, bool32 turn_on)
#define VIEW_SET_BUFFER_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_ID buffer_id, Set_Buffer_Flag flags)
@ -66,6 +68,7 @@ extern "C"{
typedef BUFFER_BOUNDARY_SEEK_SIG(Buffer_Boundary_Seek_Function);
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
typedef BUFFER_SET_SETTING_SIG(Buffer_Set_Setting_Function);
typedef BUFFER_AUTO_INDENT_SIG(Buffer_Auto_Indent_Function);
@ -83,6 +86,7 @@ extern "C"{
typedef VIEW_SET_SPLIT_PROPORTION_SIG(View_Set_Split_Proportion_Function);
typedef VIEW_COMPUTE_CURSOR_SIG(View_Compute_Cursor_Function);
typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function);
typedef VIEW_SET_SCROLL_SIG(View_Set_Scroll_Function);
typedef VIEW_SET_MARK_SIG(View_Set_Mark_Function);
typedef VIEW_SET_HIGHLIGHT_SIG(View_Set_Highlight_Function);
typedef VIEW_SET_BUFFER_SIG(View_Set_Buffer_Function);
@ -124,6 +128,7 @@ struct Application_Links{
Buffer_Boundary_Seek_Function *buffer_boundary_seek;
Buffer_Read_Range_Function *buffer_read_range;
Buffer_Replace_Range_Function *buffer_replace_range;
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
Buffer_Batch_Edit_Function *buffer_batch_edit;
Buffer_Set_Setting_Function *buffer_set_setting;
Buffer_Auto_Indent_Function *buffer_auto_indent;
@ -141,6 +146,7 @@ struct Application_Links{
View_Set_Split_Proportion_Function *view_set_split_proportion;
View_Compute_Cursor_Function *view_compute_cursor;
View_Set_Cursor_Function *view_set_cursor;
View_Set_Scroll_Function *view_set_scroll;
View_Set_Mark_Function *view_set_mark;
View_Set_Highlight_Function *view_set_highlight;
View_Set_Buffer_Function *view_set_buffer;
@ -184,6 +190,7 @@ app_links->get_buffer_by_name = Get_Buffer_By_Name;\
app_links->buffer_boundary_seek = Buffer_Boundary_Seek;\
app_links->buffer_read_range = Buffer_Read_Range;\
app_links->buffer_replace_range = Buffer_Replace_Range;\
app_links->buffer_compute_cursor = Buffer_Compute_Cursor;\
app_links->buffer_batch_edit = Buffer_Batch_Edit;\
app_links->buffer_set_setting = Buffer_Set_Setting;\
app_links->buffer_auto_indent = Buffer_Auto_Indent;\
@ -201,6 +208,7 @@ app_links->view_set_setting = View_Set_Setting;\
app_links->view_set_split_proportion = View_Set_Split_Proportion;\
app_links->view_compute_cursor = View_Compute_Cursor;\
app_links->view_set_cursor = View_Set_Cursor;\
app_links->view_set_scroll = View_Set_Scroll;\
app_links->view_set_mark = View_Set_Mark;\
app_links->view_set_highlight = View_Set_Highlight;\
app_links->view_set_buffer = View_Set_Buffer;\

View File

@ -5,6 +5,7 @@
#define FCODER_DEFAULT_BINDINGS
#include "4coder_default_include.cpp"
#include "4coder_default_building.cpp"
// NOTE(allen|a3.3): All of your custom ids should be enumerated
// as shown here, they may start at 0, and you can only have
@ -153,6 +154,19 @@ HOOK_SIG(my_start){
return(0);
}
CUSTOM_COMMAND_SIG(newline_or_goto_position){
View_Summary view = app->get_active_view(app, AccessProtected);
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessProtected);
if (buffer.lock_flags & AccessProtected){
exec_command(app, goto_postion_at_cursor);
}
else{
exec_command(app, write_character);
}
}
// TODO(allen): Eliminate this hook if you can.
OPEN_FILE_HOOK_SIG(my_file_settings){
// NOTE(allen|a4.0.8): The app->get_parameter_buffer was eliminated
// and instead the buffer is passed as an explicit parameter through
@ -183,7 +197,6 @@ OPEN_FILE_HOOK_SIG(my_file_settings){
app->buffer_set_setting(app, &buffer, BufferSetting_WrapLine, wrap_lines);
app->buffer_set_setting(app, &buffer, BufferSetting_MapID, (treat_as_code)?((int)my_code_map):((int)mapid_file));
// TODO(allen): Eliminate this hook if you can.
// no meaning for return
return(0);
}
@ -192,6 +205,8 @@ OPEN_FILE_HOOK_SIG(my_file_settings){
// If this hook is not implemented a default behavior of calling the
// command is used. It is important to note that paste_next does not
// work without this hook.
// NOTE(allen|a4.0.10): As of this version the word_complete command also
// relies on this particular command caller hook.
COMMAND_CALLER_HOOK(my_command_caller){
View_Summary view = app->get_active_view(app, AccessAll);
@ -261,6 +276,11 @@ default_keys(Bind_Helper *context){
bind(context, 'o', MDFR_ALT, open_in_other);
bind(context, 'w', MDFR_CTRL, save_as);
bind(context, '.', MDFR_ALT, change_to_build_panel);
bind(context, ',', MDFR_ALT, close_build_panel);
bind(context, 'n', MDFR_ALT, goto_next_error);
bind(context, 'N', MDFR_ALT, goto_prev_error);
bind(context, 'M', MDFR_ALT, goto_first_error);
bind(context, 'm', MDFR_ALT, build_search);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
bind(context, 'z', MDFR_ALT, execute_any_cli);
@ -287,6 +307,7 @@ default_keys(Bind_Helper *context){
// and write character writes whichever character corresponds
// to the key that triggered the command.
bind(context, '\n', MDFR_NONE, write_and_auto_tab);
bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
bind(context, '}', MDFR_NONE, write_and_auto_tab);
bind(context, ')', MDFR_NONE, write_and_auto_tab);
bind(context, ']', MDFR_NONE, write_and_auto_tab);
@ -297,7 +318,6 @@ default_keys(Bind_Helper *context){
bind(context, '\t', MDFR_CTRL, auto_tab_range);
bind(context, '\t', MDFR_SHIFT, auto_tab_line_at_cursor);
bind(context, '=', MDFR_CTRL, write_increment);
bind(context, 't', MDFR_ALT, write_allen_todo);
bind(context, 'y', MDFR_ALT, write_allen_note);
bind(context, 'r', MDFR_ALT, write_allen_doc);
@ -353,9 +373,10 @@ default_keys(Bind_Helper *context){
bind(context, 'a', MDFR_CTRL, replace_in_range);
bind(context, 'c', MDFR_CTRL, copy);
bind(context, 'd', MDFR_CTRL, delete_range);
bind(context, 'e', MDFR_CTRL, cmdid_center_view);
bind(context, 'E', MDFR_CTRL, cmdid_left_adjust_view);
bind(context, 'e', MDFR_CTRL, center_view);
bind(context, 'E', MDFR_CTRL, left_adjust_view);
bind(context, 'f', MDFR_CTRL, search);
bind(context, 'F', MDFR_CTRL, list_all_locations);
bind(context, 'g', MDFR_CTRL, goto_line);
bind(context, 'h', MDFR_CTRL, cmdid_history_backward);
bind(context, 'H', MDFR_CTRL, cmdid_history_forward);
@ -377,13 +398,14 @@ default_keys(Bind_Helper *context){
bind(context, 'y', MDFR_CTRL, cmdid_redo);
bind(context, 'z', MDFR_CTRL, cmdid_undo);
bind(context, '=', MDFR_CTRL, goto_postion_at_cursor);
bind(context, '1', MDFR_CTRL, eol_dosify);
bind(context, '!', MDFR_CTRL, eol_nixify);
bind(context, '?', MDFR_CTRL, toggle_show_whitespace);
bind(context, '~', MDFR_CTRL, clean_all_lines);
bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
bind(context, '\n', MDFR_NONE, newline_or_goto_position);
bind(context, '\n', MDFR_SHIFT, newline_or_goto_position);
bind(context, ' ', MDFR_SHIFT, write_character);
end_map(context);

View File

@ -185,40 +185,6 @@ CUSTOM_COMMAND_SIG(open_in_other_build){
// Jump to Error
//
static int
read_line(Application_Links *app,
View_Summary *view,
int line,
String *str){
Full_Cursor begin = {0};
Full_Cursor end = {0};
int success = false;
if (app->view_compute_cursor(app, view,
seek_line_char(line, 1), &begin)){
if (app->view_compute_cursor(app, view,
seek_line_char(line, 65536), &end)){
Buffer_Summary buffer = app->get_buffer(app, view->buffer_id, AccessAll);
if (begin.line == line){
if (0 <= begin.pos && begin.pos <= end.pos && end.pos <= buffer.size){
int size = (end.pos - begin.pos);
if (size <= str->memory_size){
success = true;
app->buffer_read_range(app, &buffer, begin.pos, end.pos, str->str);
str->size = size;
}
}
}
}
}
return(success);
}
struct Jump_Location{
String file;
int line;
@ -234,18 +200,9 @@ jump_to_location(Application_Links *app, View_Summary *view, Jump_Location *l){
static int
gcc_style_verify(String line, int colon_pos){
int result = false;
String line_part = substr(line, colon_pos);
if (match_part(line_part, ": error")){
if (colon_pos < line.size){
result = true;
}
else if (match_part(line_part, ": warning")){
result = true;
}
else if (match_part(line_part, ": fatal")){
result = true;
}
return(result);
}
@ -298,7 +255,8 @@ parse_error(String line, Jump_Location *location,
if (line_number.size > 0){
copy(&location->file, file);
//copy(&location->file, file);
location->file = file;
int comma_pos = find(line_number, 0, ',');
if (comma_pos < line_number.size){
@ -327,6 +285,7 @@ parse_error(String line, Jump_Location *location,
int colon_pos1 = find(line, 0, ':');
int colon_pos2 = find(line, colon_pos1+1, ':');
int colon_pos3 = find(line, colon_pos2+1, ':');
if (gcc_style_verify(line, colon_pos3)){
String filename = substr(line, 0, colon_pos1);
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
@ -335,13 +294,30 @@ parse_error(String line, Jump_Location *location,
if (filename.size > 0 &&
line_number.size > 0 &&
column_number.size > 0){
copy(&location->file, filename);
//copy(&location->file, filename);
location->file = filename;
location->line = str_to_int(line_number);
location->column = str_to_int(column_number);
*colon_char = colon_pos3;
result = true;
}
}
else{
int colon_pos1 = find(line, 0, ':');
int colon_pos2 = find(line, colon_pos1+1, ':');
String filename = substr(line, 0, colon_pos1);
String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1);
if (filename.size > 0 && line_number.size > 0){
//copy(&location->file, filename);
location->file = filename;
location->line = str_to_int(line_number);
location->column = 0;
*colon_char = colon_pos2;
result = true;
}
}
}
return(result);
@ -349,18 +325,19 @@ parse_error(String line, Jump_Location *location,
static int
next_error(Application_Links *app,
View_Summary *comp_out, int *start_line,
void *memory, int memory_size,
Jump_Location *location,
int direction,
int skip_sub_errors,
int *colon_char){
Partition *part,
View_Summary *comp_out, int *start_line,
Jump_Location *location,
int direction,
int skip_sub_errors,
int *colon_char){
int result = false;
int line = *start_line + direction;
String line_str = make_string(memory, 0, memory_size);
String line_str = {0};
Buffer_Summary buffer = app->get_buffer(app, comp_out->buffer_id, AccessAll);
for (;;){
if (read_line(app, comp_out, line, &line_str)){
if (read_line(app, part, &buffer, line, &line_str)){
if (parse_error(line_str, location, skip_sub_errors, colon_char)){
result = true;
break;
@ -382,7 +359,27 @@ next_error(Application_Links *app,
}
static int
goto_error(Application_Links *app, int direction, int skip_sub_errors, Jump_Location *loc){
goto_error(Application_Links *app,
Partition *part,
View_Summary *view, int line,
Jump_Location *location,
int skip_sub_errors){
int result = false;
String line_str = {0};
Buffer_Summary buffer = app->get_buffer(app, view->buffer_id, AccessAll);
if (read_line(app, part, &buffer, line, &line_str)){
int colon_char = 0;
if (parse_error(line_str, location, skip_sub_errors, &colon_char)){
result = true;
}
}
return(result);
}
static int
seek_error(Application_Links *app, Partition *part, int direction, int skip_sub_errors, Jump_Location *loc){
int result = false;
View_Summary active_view = app->get_active_view(app, AccessAll);
@ -392,12 +389,8 @@ goto_error(Application_Links *app, int direction, int skip_sub_errors, Jump_Loca
View_Summary view = get_first_view_with_buffer(app, buffer.buffer_id);
int line = view.cursor.line;
int ms = app->memory_size/2;
location.file = make_string(app->memory, 0, ms);
void *m = (char*)app->memory + ms;
int colon_char = 0;
if (next_error(app, &view, &line, m, ms, &location,
if (next_error(app, part, &view, &line, &location,
skip_sub_errors, direction, &colon_char)){
jump_to_location(app, &active_view, &location);
app->view_set_cursor(app, &view, seek_line_char(line, colon_char+1), true);
@ -435,11 +428,11 @@ skip_this_jump(Prev_Jump prev, Prev_Jump jump){
}
CUSTOM_COMMAND_SIG(goto_next_error){
Temp_Memory temp = begin_temp_memory(&global_part);
Jump_Location location = {0};
Prev_Jump jump = {0};
do{
if (goto_error(app, true, 1, &location)){
if (seek_error(app, &global_part, true, 1, &location)){
jump = jump_location_store(app, location);
}
else{
@ -447,14 +440,15 @@ CUSTOM_COMMAND_SIG(goto_next_error){
}
}while(skip_this_jump(prev_location, jump));
prev_location = jump;
end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(goto_prev_error){
Temp_Memory temp = begin_temp_memory(&global_part);
Jump_Location location = {0};
Prev_Jump jump = {0};
do{
if (goto_error(app, true, -1, &location)){
if (seek_error(app, &global_part, true, -1, &location)){
jump = jump_location_store(app, location);
}
else{
@ -462,17 +456,35 @@ CUSTOM_COMMAND_SIG(goto_prev_error){
}
}while(skip_this_jump(prev_location, jump));
prev_location = jump;
end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(goto_first_error){
Temp_Memory temp = begin_temp_memory(&global_part);
View_Summary active_view = app->get_active_view(app, AccessAll);
app->view_set_cursor(app, &active_view, seek_pos(0), true);
Jump_Location location;
goto_error(app, true, 1, &location);
Jump_Location location = {0};
seek_error(app, &global_part, true, 1, &location);
prev_location = jump_location_store(app, location);
end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(goto_postion_at_cursor){
Temp_Memory temp = begin_temp_memory(&global_part);
View_Summary view = app->get_active_view(app, AccessProtected);
Jump_Location location = {0};
goto_error(app, &global_part,
&view, view.cursor.line,
&location, false);
exec_command(app, change_active_panel);
view = app->get_active_view(app, AccessAll);
jump_to_location(app, &view, &location);
end_temp_memory(temp);
}
#endif

View File

@ -15,8 +15,8 @@
// Memory
//
static Partition part;
static General_Memory general;
static Partition global_part;
static General_Memory global_general;
void
init_memory(Application_Links *app){
@ -25,10 +25,10 @@ init_memory(Application_Links *app){
void *part_mem = app->memory_allocate(app, part_size);
part = make_part(part_mem, part_size);
global_part = make_part(part_mem, part_size);
void *general_mem = app->memory_allocate(app, general_size);
general_memory_open(&general, general_mem, general_size);
general_memory_open(&global_general, general_mem, general_size);
}
//
@ -534,6 +534,30 @@ CUSTOM_COMMAND_SIG(delete_range){
// Basic Navigation
//
CUSTOM_COMMAND_SIG(center_view){
View_Summary view = app->get_active_view(app, AccessProtected);
i32_Rect region = view.file_region;
GUI_Scroll_Vars scroll = view.scroll_vars;
float h = (float)(region.y1 - region.y0);
float y = get_view_y(view);
y = y - h*.5f;
scroll.target_y = (int32_t)(y + .5f);
app->view_set_scroll(app, &view, scroll);
}
CUSTOM_COMMAND_SIG(left_adjust_view){
View_Summary view = app->get_active_view(app, AccessProtected);
GUI_Scroll_Vars scroll = view.scroll_vars;
float x = get_view_x(view);
x = x - 30.f;
scroll.target_x = (int32_t)(x + .5f);
app->view_set_scroll(app, &view, scroll);
}
int
get_relative_xy(View_Summary *view, int x, int y, float *x_out, float *y_out){
int result = false;
@ -2183,6 +2207,115 @@ CUSTOM_COMMAND_SIG(eol_nixify){
#include "4coder_table.cpp"
#include "4coder_search.cpp"
CUSTOM_COMMAND_SIG(list_all_locations){
Query_Bar string;
char string_space[1024];
string.prompt = make_lit_string("List Locations For: ");
string.string = make_fixed_width_string(string_space);
if (!query_user_string(app, &string)) return;
if (string.string.size == 0) return;
Search_Set set = {0};
Search_Iter iter = {0};
search_iter_init(&global_general, &iter, string.string.size);
copy(&iter.word, string.string);
int buffer_count = app->get_buffer_count(app);
search_set_init(&global_general, &set, buffer_count);
Search_Range *ranges = set.ranges;
{
View_Summary view = app->get_active_view(app, AccessProtected);
Buffer_Summary buffer = app->get_buffer(app, view.buffer_id, AccessProtected);
int j = 0;
if (buffer.exists){
ranges[0].type = SearchRange_FrontToBack;
ranges[0].flags = 0;
ranges[0].buffer = buffer.buffer_id;
ranges[0].start = 0;
ranges[0].size = buffer.size;
j = 1;
}
for (Buffer_Summary buffer_it = app->get_buffer_first(app, AccessAll);
buffer_it.exists;
app->get_buffer_next(app, &buffer_it, AccessAll)){
if (buffer.buffer_id != buffer_it.buffer_id){
ranges[j].type = SearchRange_FrontToBack;
ranges[j].flags = 0;
ranges[j].buffer = buffer_it.buffer_id;
ranges[j].start = 0;
ranges[j].size = buffer_it.size;
++j;
}
}
set.count = j;
}
Buffer_Summary search_buffer = app->get_buffer_by_name(app, literal("*search*"), AccessAll);
if (!search_buffer.exists){
search_buffer = app->create_buffer(app, literal("*search*"), BufferCreate_AlwaysNew);
app->buffer_set_setting(app, &search_buffer, BufferSetting_Unimportant, true);
app->buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, true);
}
else{
app->buffer_replace_range(app, &search_buffer, 0, search_buffer.size, 0, 0);
}
Temp_Memory temp = begin_temp_memory(&global_part);
Partition line_part = partition_sub_part(&global_part, (4 << 10));
char *str = (char*)partition_current(&global_part);
int size = 0;
for (;;){
Search_Match match = search_next_match(app, &set, &iter);
if (match.found_match){
Partial_Cursor word_pos = {0};
if (app->buffer_compute_cursor(app, &match.buffer, seek_pos(match.start), &word_pos)){
int file_len = match.buffer.file_name_len;
int line_num_len = int_to_str_size(word_pos.line);
int column_num_len = int_to_str_size(word_pos.character);
Temp_Memory line_temp = begin_temp_memory(&line_part);
String line_str = {0};
read_line(app, &line_part, &match.buffer, word_pos.line, &line_str);
line_str = skip_chop_whitespace(line_str);
int str_len = file_len + 1 + line_num_len + 1 + column_num_len + 1 + 1 + line_str.size + 1;
char *spare = push_array(&global_part, char, str_len);
size += str_len;
String out_line = make_string(spare, 0, str_len);
append(&out_line, make_string(match.buffer.file_name, file_len));
append(&out_line, ':');
append_int_to_str(&out_line, word_pos.line);
append(&out_line, ':');
append_int_to_str(&out_line, word_pos.character);
append(&out_line, ':');
append(&out_line, ' ');
append(&out_line, line_str);
append(&out_line, '\n');
end_temp_memory(line_temp);
}
}
else{
break;
}
}
app->buffer_replace_range(app, &search_buffer, 0, 0, str, size);
View_Summary view = app->get_active_view(app, AccessAll);
app->view_set_buffer(app, &view, search_buffer.buffer_id, 0);
end_temp_memory(temp);
}
struct Word_Complete_State{
Search_Set set;
Search_Iter iter;
@ -2254,7 +2387,7 @@ CUSTOM_COMMAND_SIG(word_complete){
// NOTE(allen): Initialize the search iterator
// with the partial word.
complete_state.initialized = true;
search_iter_init(app, &complete_state.iter, size);
search_iter_init(&global_general, &complete_state.iter, size);
app->buffer_read_range(app, &buffer, word_start, word_end,
complete_state.iter.word.str);
complete_state.iter.word.size = size;
@ -2262,10 +2395,11 @@ CUSTOM_COMMAND_SIG(word_complete){
// NOTE(allen): Initialize the set of ranges
// to be searched.
int buffer_count = app->get_buffer_count(app);
search_set_init(app, &complete_state.set, buffer_count);
search_set_init(&global_general, &complete_state.set, buffer_count);
Search_Range *ranges = complete_state.set.ranges;
ranges[0].type = SearchRange_Wave;
ranges[0].flags = SearchFlag_MatchStartOfIdentifier;
ranges[0].buffer = buffer.buffer_id;
ranges[0].start = 0;
ranges[0].size = buffer.size;
@ -2278,6 +2412,7 @@ CUSTOM_COMMAND_SIG(word_complete){
app->get_buffer_next(app, &buffer_it, AccessAll)){
if (buffer.buffer_id != buffer_it.buffer_id){
ranges[j].type = SearchRange_FrontToBack;
ranges[j].flags = SearchFlag_MatchStartOfIdentifier;
ranges[j].buffer = buffer_it.buffer_id;
ranges[j].start = 0;
ranges[j].size = buffer_it.size;
@ -2287,9 +2422,9 @@ CUSTOM_COMMAND_SIG(word_complete){
complete_state.set.count = j;
// NOTE(allen): Initialize the search hit table.
search_hits_init(app, &complete_state.hits, &complete_state.str,
search_hits_init(&global_general, &complete_state.hits, &complete_state.str,
100, (4 << 10));
search_hit_add(app, &complete_state.hits, &complete_state.str,
search_hit_add(&global_general, &complete_state.hits, &complete_state.str,
complete_state.iter.word.str,
complete_state.iter.word.size);
@ -2312,13 +2447,13 @@ CUSTOM_COMMAND_SIG(word_complete){
if (match.found_match){
int match_size = match.end - match.start;
Temp_Memory temp = begin_temp_memory(&part);
char *spare = push_array(&part, char, match_size);
Temp_Memory temp = begin_temp_memory(&global_part);
char *spare = push_array(&global_part, char, match_size);
app->buffer_read_range(app, &match.buffer,
match.start, match.end, spare);
if (search_hit_add(app, &complete_state.hits, &complete_state.str,
if (search_hit_add(&global_general, &complete_state.hits, &complete_state.str,
spare, match_size)){
app->buffer_replace_range(app, &buffer, word_start, word_end,
spare, match_size);
@ -2337,9 +2472,9 @@ CUSTOM_COMMAND_SIG(word_complete){
complete_state.iter.pos = 0;
complete_state.iter.i = 0;
search_hits_init(app, &complete_state.hits, &complete_state.str,
search_hits_init(&global_general, &complete_state.hits, &complete_state.str,
100, (4 << 10));
search_hit_add(app, &complete_state.hits, &complete_state.str,
search_hit_add(&global_general, &complete_state.hits, &complete_state.str,
complete_state.iter.word.str,
complete_state.iter.word.size);

View File

@ -419,8 +419,11 @@ get_active_buffer(Application_Links *app, unsigned int access){
inline char
buffer_get_char(Application_Links *app, Buffer_Summary *buffer, int pos){
char result = 0;
app->buffer_read_range(app, buffer, pos, pos+1, &result);
char result = ' ';
*buffer = app->get_buffer(app, buffer->buffer_id, AccessAll);
if (pos >= 0 && pos < buffer->size){
app->buffer_read_range(app, buffer, pos, pos+1, &result);
}
return(result);
}
@ -469,4 +472,38 @@ view_open_file(Application_Links *app, View_Summary *view,
return(result);
}
static int
read_line(Application_Links *app,
Partition *part,
Buffer_Summary *buffer,
int line,
String *str){
Partial_Cursor begin = {0};
Partial_Cursor end = {0};
int success = false;
if (app->buffer_compute_cursor(app, buffer,
seek_line_char(line, 1), &begin)){
if (app->buffer_compute_cursor(app, buffer,
seek_line_char(line, 65536), &end)){
if (begin.line == line){
if (0 <= begin.pos && begin.pos <= end.pos && end.pos <= buffer->size){
int size = (end.pos - begin.pos);
*str = make_string(push_array(part, char, size+1), size+1);
if (str->str){
success = true;
app->buffer_read_range(app, buffer, begin.pos, end.pos, str->str);
str->size = size;
terminate_with_null(str);
}
}
}
}
}
return(success);
}
#endif

View File

@ -1,431 +1,460 @@
#ifndef FCODER_SEARCH
#define FCODER_SEARCH
enum Search_Range_Type{
SearchRange_FrontToBack,
SearchRange_BackToFront,
SearchRange_Wave,
};
struct Search_Range{
int type;
int buffer;
int start;
int size;
int mid_start;
int mid_size;
};
struct Search_Set{
Search_Range *ranges;
int count;
int max;
};
struct Search_Iter{
String word;
int pos;
int back_pos;
int i;
int range_initialized;
};
struct Search_Match{
Buffer_Summary buffer;
int start;
int end;
int found_match;
};
static void
search_iter_init(Application_Links *app, Search_Iter *iter, int size){
int str_max = size*2;
if (iter->word.str == 0){
iter->word.str = (char*)general_memory_allocate(&general, str_max);
iter->word.memory_size = str_max;
}
else if (iter->word.memory_size < size){
iter->word.str = (char*)general_memory_reallocate_nocopy(&general, iter->word.str, str_max);
iter->word.memory_size = str_max;
}
iter->i = 0;
iter->range_initialized = 0;
}
static void
search_set_init(Application_Links *app, Search_Set *set, int range_count){
int max = range_count*2;
if (set->ranges == 0){
set->ranges = (Search_Range*)general_memory_allocate(&general, sizeof(Search_Range)*max);
set->max = max;
}
else if (set->max < range_count){
set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
&general, set->ranges, sizeof(Search_Range)*max);
set->max = max;
}
set->count = range_count;
}
static void
search_hits_table_alloc(Application_Links *app, Table *hits, int table_size){
void *mem = 0;
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
if (hits->hash_array == 0){
mem = general_memory_allocate(&general, mem_size);
}
else{
mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size);
}
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
}
static void
search_hits_init(Application_Links *app, Table *hits, String_Space *str, int table_size, int str_size){
if (hits->hash_array == 0){
search_hits_table_alloc(app, hits, table_size);
}
else{
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
void *mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size);
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
}
if (str->space == 0){
str->space = (char*)general_memory_allocate(&general, str_size);
str->max = str_size;
}
else if (str->max < str_size){
str->space = (char*)general_memory_reallocate_nocopy(&general, str->space, str_size);
str->max = str_size;
}
str->pos = str->new_pos = 0;
table_clear(hits);
}
static int
search_hit_add(Application_Links *app, Table *hits, String_Space *space, char *str, int len){
int result = false;
assert(len != 0);
Offset_String ostring = strspace_append(space, str, len);
if (ostring.size == 0){
int new_size = space->max*2;
if (new_size < space->max + len){
new_size = space->max + len;
}
space->space = (char*)general_memory_reallocate(
&general, space->space, space->new_pos, new_size);
ostring = strspace_append(space, str, len);
}
assert(ostring.size != 0);
if (table_at_capacity(hits)){
Table new_hits = {0};
search_hits_table_alloc(app, &new_hits, hits->max*2);
table_clear(&new_hits);
table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
general_memory_free(&general, hits->hash_array);
*hits = new_hits;
}
if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
result = true;
strspace_keep_prev(space);
}
else{
strspace_discard_prev(space);
}
return(result);
}
static int
buffer_seek_alpha_numeric_end(Application_Links *app, Buffer_Summary *buffer, int pos){
char space[1024];
Stream_Chunk chunk = {0};
if (init_stream_chunk(&chunk, app, buffer, pos, space, sizeof(space))){
int still_looping = true;
do{
for (; pos < chunk.end; ++pos){
char at_pos = chunk.data[pos];
if (!char_is_alpha_numeric(at_pos)) goto double_break;
}
still_looping = forward_stream_chunk(&chunk);
}while(still_looping);
}
double_break:;
return(pos);
}
static void
search_iter_next_range(Search_Iter *it){
++it->i;
it->pos = 0;
it->back_pos = 0;
it->range_initialized = 0;
}
enum{
FindResult_None,
FindResult_FoundMatch,
FindResult_PastEnd
};
static int
search_front_to_back_step(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
Search_Match result = *result_ptr;
int end_pos = range->start + range->size;
if (*pos + word.size < end_pos){
int start_pos = *pos;
if (start_pos < range->start){
start_pos = range->start;
}
result.buffer = app->get_buffer(app, range->buffer, AccessAll);
buffer_seek_string_forward(app, &result.buffer,
start_pos, end_pos,
word.str, word.size,
&result.start);
if (result.start < end_pos){
*pos = result.start + 1;
char prev = ' ';
if (result.start > 0){
prev = buffer_get_char(app, &result.buffer, result.start - 1);
}
if (!char_is_alpha_numeric(prev)){
result.end =
buffer_seek_alpha_numeric_end(
app, &result.buffer, result.start);
if (result.end < end_pos){
result.found_match = true;
*pos = result.end;
found_match = FindResult_FoundMatch;
}
}
}
else{
found_match = FindResult_PastEnd;
*pos = end_pos + 1;
}
}
else{
found_match = FindResult_PastEnd;
*pos = end_pos + 1;
}
*result_ptr = result;
return(found_match);
}
static int
search_front_to_back(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
for (;found_match == FindResult_None;){
found_match = search_front_to_back_step(app, range, word, pos, result_ptr);
}
return(found_match);
}
static int
search_back_to_front_step(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
Search_Match result = *result_ptr;
int end_pos = range->start + range->size;
if (*pos > range->start){
int start_pos = *pos;
result.buffer = app->get_buffer(app, range->buffer, AccessAll);
buffer_seek_string_backward(app, &result.buffer,
start_pos, range->start,
word.str, word.size,
&result.start);
if (result.start >= range->start){
*pos = result.start - 1;
char prev = ' ';
if (result.start > 0){
prev = buffer_get_char(app, &result.buffer, result.start - 1);
}
if (!char_is_alpha_numeric(prev)){
result.end =
buffer_seek_alpha_numeric_end(
app, &result.buffer, result.start);
if (result.end < end_pos){
result.found_match = true;
*pos = result.start - word.size;
found_match = FindResult_FoundMatch;
}
}
}
else{
found_match = FindResult_PastEnd;
}
}
else{
found_match = FindResult_PastEnd;
}
*result_ptr = result;
return(found_match);
}
static int
search_back_to_front(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
for (;found_match == FindResult_None;){
found_match = search_back_to_front_step(app, range, word, pos, result_ptr);
}
return(found_match);
}
static Search_Match
search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){
Search_Match result = {0};
Search_Iter iter = *it_ptr;
int count = set->count;
for (; iter.i < count;){
Search_Range *range = set->ranges + iter.i;
int find_result = FindResult_None;
if (!iter.range_initialized){
iter.range_initialized = true;
switch (range->type){
case SearchRange_BackToFront:
{
iter.back_pos = range->start+range->size-1;
}break;
case SearchRange_Wave:
{
iter.back_pos = range->mid_start-1;
iter.pos = range->mid_start + range->mid_size;
}break;
}
}
switch (range->type){
case SearchRange_FrontToBack:
{
find_result =
search_front_to_back(app, range,
iter.word,
&iter.pos,
&result);
}break;
case SearchRange_BackToFront:
{
find_result =
search_back_to_front(app, range,
iter.word,
&iter.back_pos,
&result);
}break;
case SearchRange_Wave:
{
Search_Match forward_match = {0};
Search_Match backward_match = {0};
int forward_result = FindResult_PastEnd;
int backward_result = FindResult_PastEnd;
if (iter.pos < range->start + range->size){
forward_result = search_front_to_back(app, range,
iter.word,
&iter.pos,
&forward_match);
}
if (iter.back_pos > range->start){
backward_result = search_back_to_front(app, range,
iter.word,
&iter.back_pos,
&backward_match);
}
if (forward_result == FindResult_FoundMatch){
if (backward_result == FindResult_FoundMatch){
find_result = FindResult_FoundMatch;
int forward_start = range->mid_start + range->mid_size;
int forward_distance = (forward_match.start - forward_start);
int backward_distance = (range->mid_start - backward_match.end);
if (backward_distance < forward_distance){
iter.pos = forward_match.start;
result = backward_match;
}
else{
iter.back_pos = backward_match.start;
result = forward_match;
}
}
else{
find_result = FindResult_FoundMatch;
result = forward_match;
}
}
else{
if (backward_result == FindResult_FoundMatch){
find_result = FindResult_FoundMatch;
result = backward_match;
--iter.pos;
}
else{
find_result = FindResult_PastEnd;
}
}
}break;
}
if (find_result == FindResult_FoundMatch){
goto double_break;
}
else if (find_result == FindResult_PastEnd){
search_iter_next_range(&iter);
}
}
double_break:;
*it_ptr = iter;
return(result);
}
#endif
#ifndef FCODER_SEARCH
#define FCODER_SEARCH
enum Search_Range_Type{
SearchRange_FrontToBack,
SearchRange_BackToFront,
SearchRange_Wave,
};
enum Search_Range_Flag{
SearchFlag_MatchStartOfIdentifier = 0x1,
};
struct Search_Range{
int type;
unsigned int flags;
int buffer;
int start;
int size;
int mid_start;
int mid_size;
};
struct Search_Set{
Search_Range *ranges;
int count;
int max;
};
struct Search_Iter{
String word;
int pos;
int back_pos;
int i;
int range_initialized;
};
struct Search_Match{
Buffer_Summary buffer;
int start;
int end;
int found_match;
};
static void
search_iter_init(General_Memory *general, Search_Iter *iter, int size){
int str_max = size*2;
if (iter->word.str == 0){
iter->word.str = (char*)general_memory_allocate(general, str_max);
iter->word.memory_size = str_max;
}
else if (iter->word.memory_size < size){
iter->word.str = (char*)general_memory_reallocate_nocopy(general, iter->word.str, str_max);
iter->word.memory_size = str_max;
}
iter->i = 0;
iter->range_initialized = 0;
}
static void
search_set_init(General_Memory *general, Search_Set *set, int range_count){
int max = range_count*2;
if (set->ranges == 0){
set->ranges = (Search_Range*)general_memory_allocate(general, sizeof(Search_Range)*max);
set->max = max;
}
else if (set->max < range_count){
set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
general, set->ranges, sizeof(Search_Range)*max);
set->max = max;
}
set->count = range_count;
}
static void
search_hits_table_alloc(General_Memory *general, Table *hits, int table_size){
void *mem = 0;
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
if (hits->hash_array == 0){
mem = general_memory_allocate(general, mem_size);
}
else{
mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
}
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
}
static void
search_hits_init(General_Memory *general, Table *hits, String_Space *str, int table_size, int str_size){
if (hits->hash_array == 0){
search_hits_table_alloc(general, hits, table_size);
}
else{
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
void *mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
}
if (str->space == 0){
str->space = (char*)general_memory_allocate(general, str_size);
str->max = str_size;
}
else if (str->max < str_size){
str->space = (char*)general_memory_reallocate_nocopy(general, str->space, str_size);
str->max = str_size;
}
str->pos = str->new_pos = 0;
table_clear(hits);
}
static int
search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *str, int len){
int result = false;
assert(len != 0);
Offset_String ostring = strspace_append(space, str, len);
if (ostring.size == 0){
int new_size = space->max*2;
if (new_size < space->max + len){
new_size = space->max + len;
}
space->space = (char*)general_memory_reallocate(
general, space->space, space->new_pos, new_size);
ostring = strspace_append(space, str, len);
}
assert(ostring.size != 0);
if (table_at_capacity(hits)){
Table new_hits = {0};
search_hits_table_alloc(general, &new_hits, hits->max*2);
table_clear(&new_hits);
table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
general_memory_free(general, hits->hash_array);
*hits = new_hits;
}
if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
result = true;
strspace_keep_prev(space);
}
else{
strspace_discard_prev(space);
}
return(result);
}
static int
buffer_seek_alpha_numeric_end(Application_Links *app, Buffer_Summary *buffer, int pos){
char space[1024];
Stream_Chunk chunk = {0};
if (init_stream_chunk(&chunk, app, buffer, pos, space, sizeof(space))){
int still_looping = true;
do{
for (; pos < chunk.end; ++pos){
char at_pos = chunk.data[pos];
if (!char_is_alpha_numeric(at_pos)) goto double_break;
}
still_looping = forward_stream_chunk(&chunk);
}while(still_looping);
}
double_break:;
return(pos);
}
static void
search_iter_next_range(Search_Iter *it){
++it->i;
it->pos = 0;
it->back_pos = 0;
it->range_initialized = 0;
}
enum{
FindResult_None,
FindResult_FoundMatch,
FindResult_PastEnd
};
static int
match_check(Application_Links *app, Search_Range *range, int *pos, Search_Match *result_ptr, String word){
int found_match = FindResult_None;
Search_Match result = *result_ptr;
int end_pos = range->start + range->size;
if (range->flags & SearchFlag_MatchStartOfIdentifier){
char prev = buffer_get_char(app, &result.buffer, result.start - 1);
if (!char_is_alpha_numeric(prev)){
result.end =
buffer_seek_alpha_numeric_end(
app, &result.buffer, result.start);
if (result.end <= end_pos){
result.found_match = true;
found_match = FindResult_FoundMatch;
}
else{
found_match = FindResult_PastEnd;
}
}
}
else{
char prev = buffer_get_char(app, &result.buffer, result.start - 1);
if (!char_is_alpha_numeric(prev)){
result.end = result.start + word.size;
if (result.end <= end_pos){
char next = buffer_get_char(app, &result.buffer, result.end);
if (!char_is_alpha_numeric(next)){
result.found_match = true;
found_match = FindResult_FoundMatch;
}
}
else{
found_match = FindResult_PastEnd;
}
}
}
*result_ptr = result;
return(found_match);
}
static int
search_front_to_back_step(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
Search_Match result = *result_ptr;
int end_pos = range->start + range->size;
if (*pos + word.size < end_pos){
int start_pos = *pos;
if (start_pos < range->start){
start_pos = range->start;
}
result.buffer = app->get_buffer(app, range->buffer, AccessAll);
buffer_seek_string_forward(app, &result.buffer,
start_pos, end_pos,
word.str, word.size,
&result.start);
if (result.start < end_pos){
*pos = result.start + 1;
found_match = match_check(app, range, pos, &result, word);
if (found_match == FindResult_FoundMatch){
*pos = result.end;
}
}
else{
found_match = FindResult_PastEnd;
*pos = end_pos + 1;
}
}
else{
found_match = FindResult_PastEnd;
*pos = end_pos + 1;
}
*result_ptr = result;
return(found_match);
}
static int
search_front_to_back(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
for (;found_match == FindResult_None;){
found_match = search_front_to_back_step(app, range, word, pos, result_ptr);
}
return(found_match);
}
static int
search_back_to_front_step(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
Search_Match result = *result_ptr;
if (*pos > range->start){
int start_pos = *pos;
result.buffer = app->get_buffer(app, range->buffer, AccessAll);
buffer_seek_string_backward(app, &result.buffer,
start_pos, range->start,
word.str, word.size,
&result.start);
// TODO(allen): deduplicate the match checking code.
if (result.start >= range->start){
*pos = result.start - 1;
found_match = match_check(app, range, pos, &result, word);
if (found_match == FindResult_FoundMatch){
*pos = result.start - word.size;
}
}
else{
found_match = FindResult_PastEnd;
}
}
else{
found_match = FindResult_PastEnd;
}
*result_ptr = result;
return(found_match);
}
static int
search_back_to_front(Application_Links *app,
Search_Range *range,
String word,
int *pos,
Search_Match *result_ptr){
int found_match = FindResult_None;
for (;found_match == FindResult_None;){
found_match = search_back_to_front_step(app, range, word, pos, result_ptr);
}
return(found_match);
}
static Search_Match
search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){
Search_Match result = {0};
Search_Iter iter = *it_ptr;
int count = set->count;
for (; iter.i < count;){
Search_Range *range = set->ranges + iter.i;
int find_result = FindResult_None;
if (!iter.range_initialized){
iter.range_initialized = true;
switch (range->type){
case SearchRange_BackToFront:
{
iter.back_pos = range->start+range->size-1;
}break;
case SearchRange_Wave:
{
iter.back_pos = range->mid_start-1;
iter.pos = range->mid_start + range->mid_size;
}break;
}
}
switch (range->type){
case SearchRange_FrontToBack:
{
find_result =
search_front_to_back(app, range,
iter.word,
&iter.pos,
&result);
}break;
case SearchRange_BackToFront:
{
find_result =
search_back_to_front(app, range,
iter.word,
&iter.back_pos,
&result);
}break;
case SearchRange_Wave:
{
Search_Match forward_match = {0};
Search_Match backward_match = {0};
int forward_result = FindResult_PastEnd;
int backward_result = FindResult_PastEnd;
if (iter.pos < range->start + range->size){
forward_result = search_front_to_back(app, range,
iter.word,
&iter.pos,
&forward_match);
}
if (iter.back_pos > range->start){
backward_result = search_back_to_front(app, range,
iter.word,
&iter.back_pos,
&backward_match);
}
if (forward_result == FindResult_FoundMatch){
if (backward_result == FindResult_FoundMatch){
find_result = FindResult_FoundMatch;
int forward_start = range->mid_start + range->mid_size;
int forward_distance = (forward_match.start - forward_start);
int backward_distance = (range->mid_start - backward_match.end);
if (backward_distance < forward_distance){
iter.pos = forward_match.start;
result = backward_match;
}
else{
iter.back_pos = backward_match.start;
result = forward_match;
}
}
else{
find_result = FindResult_FoundMatch;
result = forward_match;
}
}
else{
if (backward_result == FindResult_FoundMatch){
find_result = FindResult_FoundMatch;
result = backward_match;
--iter.pos;
}
else{
find_result = FindResult_PastEnd;
}
}
}break;
}
if (find_result == FindResult_FoundMatch){
goto double_break;
}
else if (find_result == FindResult_PastEnd){
search_iter_next_range(&iter);
}
}
double_break:;
*it_ptr = iter;
return(result);
}
#endif

View File

@ -51,14 +51,6 @@ ENUM(uint64_t, Command_ID){
/* DOC(cmdid_null is set aside to always be zero and is not associated with any command.) */
cmdid_null,
/* DOC(cmdid_center_view centers the view vertically on the cursor.) */
cmdid_center_view,
/* DOC(cmdid_left_adjust_view adjusts the view to be just left of the cursor's position.) */
cmdid_left_adjust_view,
/* DOC(cmdid_word_complete begins or continues cycling through completions for a partial word.) */
cmdid_word_complete,
/* DOC(cmdid_undo performs a standard undo behavior.) */
cmdid_undo,
/* DOC(cmdid_redo reperforms an edit that was undone.) */
@ -72,16 +64,17 @@ ENUM(uint64_t, Command_ID){
cmdid_interactive_new,
/* DOC(cmdid_interactive_open begins an interactive dialogue to open a file into a buffer.) */
cmdid_interactive_open,
/* DOC(cmdid_reopen reloads the active buffer's associated file and discards the old buffer contents for the reloaded file.) */
cmdid_reopen,
/* DOC(cmdid_save saves the buffer's contents into the associated file.) */
cmdid_save,
/* DOC(cmdid_save_as does not currently work and is likely to be removed rather that fixed.) */
cmdid_save_as,
/* DOC(cmdid_interactive_switch_buffer begins an interactive dialogue to choose an open buffer to swap into the active view.) */
cmdid_interactive_switch_buffer,
/* DOC(cmdid_interactive_kill_buffer begins an interactive dialogue to choose an open buffer to kill.) */
cmdid_interactive_kill_buffer,
/* DOC(cmdid_reopen reloads the active buffer's associated file and discards the old buffer contents for the reloaded file.) */
cmdid_reopen,
/* DOC(cmdid_save saves the buffer's contents into the associated file.) */
cmdid_save,
/* DOC(cmdid_kill_buffer tries to kill the active buffer.) */
cmdid_kill_buffer,
@ -157,9 +150,18 @@ ENUM(int32_t, Buffer_Setting_ID){
active when a buffer is active.) */
BufferSetting_MapID,
/* DOC(The BufferSetting_Eol setting spcifies how line ends should be saved to the backing file.
/* DOC(The BufferSetting_Eol setting specifies how line ends should be saved to the backing file.
A 1 indicates dos endings "\r\n" and a 0 indicates nix endings "\n".) */
BufferSetting_Eol,
/* DOC(The BufferSetting_Unimportant setting marks a buffer so that it's dirty state will be completely
ignored. This means the "dirty" star is hidden and the buffer can be closed without presenting an
"are you sure" dialogue screen.) */
BufferSetting_Unimportant,
/* DOC(The BufferSetting_ReadOnly setting marks a buffer so that it can only be returned from buffer
access calls that include an AccessProtected flag.) */
BufferSetting_ReadOnly,
};
/* DOC(A View_Setting_ID names a setting in a view.) */
@ -185,7 +187,7 @@ ENUM(int32_t, View_Setting_ID){
FLAGENUM(Buffer_Create_Flag){
/* DOC(BufferCreate_Background is not currently implemented.) */
BufferCreate_Background = 0x1,
/* DOC(When BufferCreate_AlwaysNew is et it indicates the buffer should be
/* DOC(When BufferCreate_AlwaysNew is set it indicates the buffer should be
cleared to empty even if it's associated file already has content.) */
BufferCreate_AlwaysNew = 0x2,
};
@ -485,7 +487,8 @@ struct GUI_Scroll_Vars{
};
/* DOC(Full_Cursor describes the position of a cursor in every buffer
coordinate system supported by 4coder.)
coordinate system supported by 4coder. This cursor type requires that
the buffer is associated with a view to give the x/y values meaning.)
DOC_SEE(4coder_Buffer_Positioning_System) */
struct Full_Cursor{
/* DOC(This field contains the cursor's position in absolute positioning.) */
@ -504,6 +507,20 @@ struct Full_Cursor{
float wrapped_y;
};
/* DOC(Partial_Cursor describes the position of a cursor in all of
the coordinate systems that a invariant to the View. In other words
the coordinate systems available here can be used on a buffer that is
not currently associated with a View.)
DOC_SEE(4coder_Buffer_Positioning_System) */
struct Partial_Cursor{
/* DOC(This field contains the cursor's position in absolute positioning.) */
int32_t pos;
/* DOC(This field contains the number of the line where the cursor is located. This field is one based.) */
int32_t line;
/* DOC(This field contains the number of the column where the cursor is located. This field is one based.) */
int32_t character;
};
/* DOC(Buffer_Seek describes the destination of a seek operation. There are helpers
for concisely creating Buffer_Seek structs. They can be found in 4coder_buffer_types.h.)
DOC_SEE(Buffer_Seek_Type)
@ -596,7 +613,9 @@ struct Buffer_Summary{
};
/* DOC(View_Summary acts as a handle to a view and describes the state of the view.)
DOC_SEE(Access_Flag)*/
DOC_SEE(Access_Flag)
DOC_SEE(Full_Cursor)
*/
struct View_Summary{
/* DOC(
This field indicates whether the View_Summary describes a view that is open in 4coder.
@ -617,12 +636,10 @@ struct View_Summary{
/*
DOC(If this is not a null summary, this describes the position of the cursor.)
DOC_SEE(Full_Cursor)
*/
Full_Cursor cursor;
/*
DOC(If this is not a null summary, this describes the position of the mark.)
DOC_SEE(Full_Cursor)
*/
Full_Cursor mark;
/* DOC(If this is not a null summary, this is the x position that is maintained in vertical navigation.) */
@ -634,9 +651,9 @@ struct View_Summary{
/* DOC(If this is not a null summary, this indicates that the view is set to highlight white space.) */
bool32 show_whitespace;
/* DOC(This feature is not fully implemented yet.) */
/* DOC(If this is not a null summary, this describes the screen position in which this view's buffer is displayed.) */
i32_Rect file_region;
/* DOC(This feature is not fully implemented yet.) */
/* DOC(If this is not a null summary, this describes the scrolling position inside the view.) */
GUI_Scroll_Vars scroll_vars;
};

232
4ed.cpp
View File

@ -34,15 +34,6 @@ struct CLI_List{
i32 count, max;
};
struct Complete_State{
Search_Set set;
Search_Iter iter;
Table hits;
String_Space str;
i32 word_start, word_end;
b32 initialized;
};
struct Command_Data{
Models *models;
struct App_Vars *vars;
@ -169,7 +160,6 @@ struct App_Vars{
App_State state;
App_State_Resizing resizing;
Complete_State complete_state;
Command_Data command_data;
@ -281,223 +271,6 @@ COMMAND_DECL(null){
AllowLocal(command);
}
internal i32
seek_token_left(Cpp_Token_Stack *tokens, i32 pos){
Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
if (get.token_index == -1){
get.token_index = 0;
}
Cpp_Token *token = tokens->tokens + get.token_index;
if (token->start == pos && get.token_index > 0){
--token;
}
return token->start;
}
internal i32
seek_token_right(Cpp_Token_Stack *tokens, i32 pos){
Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
if (get.in_whitespace){
++get.token_index;
}
if (get.token_index >= tokens->count){
get.token_index = tokens->count-1;
}
Cpp_Token *token = tokens->tokens + get.token_index;
return token->start + token->size;
}
COMMAND_DECL(center_view){
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
Assert(view->edit_pos);
f32 h = view_file_height(view);
f32 y = view->edit_pos->cursor.wrapped_y;
if (view->file_data.unwrapped_lines){
y = view->edit_pos->cursor.unwrapped_y;
}
y = clamp_bottom(0.f, y - h*.5f);
view->edit_pos->scroll.target_y = ROUND32(y);
}
COMMAND_DECL(left_adjust_view){
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
Assert(view->edit_pos);
f32 x = view->edit_pos->cursor.wrapped_x;
if (view->file_data.unwrapped_lines){
x = view->edit_pos->cursor.unwrapped_x;
}
x = clamp_bottom(0.f, x - 30.f);
view->edit_pos->scroll.target_x = ROUND32(x);
}
COMMAND_DECL(word_complete){
USE_MODELS(models);
USE_VARS(vars);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
Assert(view->edit_pos);
Partition *part = &models->mem.part;
General_Memory *general = &models->mem.general;
Working_Set *working_set = &models->working_set;
Complete_State *complete_state = &vars->complete_state;
Search_Range *ranges = 0;
Buffer_Type *buffer = &file->state.buffer;
i32 size_of_buffer = buffer_size(buffer);
i32 cursor_pos = 0;
i32 word_start = 0;
i32 word_end = 0;
char c = 0;
char *spare = 0;
i32 size = 0;
b32 do_init = false;
if (view->mode.rewrite != 2){
do_init = true;
}
view->next_mode.rewrite = 2;
if (complete_state->initialized == 0){
do_init = true;
}
if (do_init){
word_end = view->edit_pos->cursor.pos;
word_start = word_end;
cursor_pos = word_end - 1;
// TODO(allen): macros for these buffer loops and some method
// of breaking out of them.
for (Buffer_Backify_Type loop = buffer_backify_loop(buffer, cursor_pos, 0);
buffer_backify_good(&loop);
buffer_backify_next(&loop)){
i32 end = loop.absolute_pos;
char *data = loop.data - loop.absolute_pos;
for (; cursor_pos >= end; --cursor_pos){
c = data[cursor_pos];
if (char_is_alpha(c)){
word_start = cursor_pos;
}
else if (!char_is_numeric(c)){
goto double_break;
}
}
}
double_break:;
size = word_end - word_start;
if (size == 0){
complete_state->initialized = 0;
return;
}
complete_state->initialized = 1;
search_iter_init(general, &complete_state->iter, size);
buffer_stringify(buffer, word_start, word_end, complete_state->iter.word.str);
complete_state->iter.word.size = size;
{
File_Node *node, *used_nodes;
Editing_File *file_ptr;
i32 buffer_count, j;
buffer_count = working_set->file_count;
search_set_init(general, &complete_state->set, buffer_count + 1);
ranges = complete_state->set.ranges;
ranges[0].buffer = buffer;
ranges[0].start = 0;
ranges[0].size = word_start;
ranges[1].buffer = buffer;
ranges[1].start = word_end;
ranges[1].size = size_of_buffer - word_end;
used_nodes = &working_set->used_sentinel;
j = 2;
for (dll_items(node, used_nodes)){
file_ptr = (Editing_File*)node;
if (file_ptr != file){
ranges[j].buffer = &file_ptr->state.buffer;
ranges[j].start = 0;
ranges[j].size = buffer_size(ranges[j].buffer);
++j;
}
}
complete_state->set.count = j;
}
search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4));
search_hit_add(general, &complete_state->hits, &complete_state->str,
complete_state->iter.word.str, complete_state->iter.word.size);
complete_state->word_start = word_start;
complete_state->word_end = word_end;
}
else{
word_start = complete_state->word_start;
word_end = complete_state->word_end;
size = complete_state->iter.word.size;
}
if (size > 0){
for (;;){
i32 match_size = 0;
Search_Match match =
search_next_match(part, &complete_state->set, &complete_state->iter);
if (match.found_match){
Temp_Memory temp = begin_temp_memory(part);
match_size = match.end - match.start;
spare = (char*)push_array(part, char, match_size);
buffer_stringify(match.buffer, match.start, match.end, spare);
if (search_hit_add(general, &complete_state->hits, &complete_state->str, spare, match_size)){
view_replace_range(system, models, view, word_start, word_end, spare, match_size);
view_cursor_move(view, word_start + match_size);
complete_state->word_end = word_start + match_size;
complete_state->set.ranges[1].start = word_start + match_size;
end_temp_memory(temp);
break;
}
end_temp_memory(temp);
}
else{
complete_state->iter.pos = 0;
complete_state->iter.i = 0;
search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4));
search_hit_add(general, &complete_state->hits, &complete_state->str,
complete_state->iter.word.str, complete_state->iter.word.size);
match_size = complete_state->iter.word.size;
view_replace_range(system, models, view, word_start, word_end,
complete_state->iter.word.str, match_size);
view_cursor_move(view, word_start + match_size);
complete_state->word_end = word_start + match_size;
complete_state->set.ranges[1].start = word_start + match_size;
break;
}
}
}
}
// TODO(allen): FIX THIS SHIT!
COMMAND_DECL(undo){
USE_MODELS(models);
@ -1027,11 +800,6 @@ setup_command_table(){
#define SET(n) command_table[cmdid_##n] = command_##n
SET(null);
SET(center_view);
SET(left_adjust_view);
SET(word_complete);
SET(undo);
SET(redo);
SET(history_backward);

View File

@ -447,6 +447,7 @@ This call begins a loop across all the buffers.
If the buffer returned does not exist, the loop is finished.
Buffers should not be killed durring a buffer loop.
)
DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
DOC_SEE(get_buffer_next)
*/{
@ -474,6 +475,7 @@ The global buffer order is kept roughly in the order of most recently used to le
If the buffer outputted does not exist, the loop is finished.
Buffers should not be killed or created durring a buffer loop.
)
DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
DOC_SEE(get_buffer_first)
*/{
@ -491,6 +493,7 @@ Get_Buffer(Application_Links *app, Buffer_ID buffer_id, Access_Flag access)/*
DOC_PARAM(buffer_id, The parameter buffer_id specifies which buffer to try to get.)
DOC_PARAM(access, The access parameter determines what levels of protection this call can access.)
DOC_RETURN(This call returns a summary that describes the indicated buffer if it exists and is accessible.)
DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
DOC_SEE(Buffer_ID)
*/{
@ -516,6 +519,7 @@ DOC_PARAM(name, The name parameter specifies the buffer name to try to get. The
DOC_PARAM(len, The len parameter specifies the length of the name string.)
DOC_PARAM(access, The access parameter determines what levels of protection this call can access.)
DOC_RETURN(This call returns a summary that describes the indicated buffer if it exists and is accessible.)
DOC_SEE(Buffer_Summary)
DOC_SEE(Access_Flag)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
@ -534,6 +538,35 @@ DOC_SEE(Access_Flag)
return(buffer);
}
internal i32
seek_token_left(Cpp_Token_Stack *tokens, i32 pos){
Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
if (get.token_index == -1){
get.token_index = 0;
}
Cpp_Token *token = tokens->tokens + get.token_index;
if (token->start == pos && get.token_index > 0){
--token;
}
return token->start;
}
internal i32
seek_token_right(Cpp_Token_Stack *tokens, i32 pos){
Cpp_Get_Token_Result get = cpp_get_token(tokens, pos);
if (get.in_whitespace){
++get.token_index;
}
if (get.token_index >= tokens->count){
get.token_index = tokens->count-1;
}
Cpp_Token *token = tokens->tokens + get.token_index;
return token->start + token->size;
}
API_EXPORT int32_t
Buffer_Boundary_Seek(Application_Links *app, Buffer_Summary *buffer, int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)/*
DOC_PARAM(buffer, The buffer parameter specifies the buffer through which to seek.)
@ -712,6 +745,32 @@ DOC_SEE(4coder_Buffer_Positioning_System)
return(result);
}
API_EXPORT bool32
Buffer_Compute_Cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)/*
DOC_PARAM(buffer, The buffer parameter specifies the buffer on which to run the cursor computation.)
DOC_PARAM(seek, The seek parameter specifies the target position for the seek.)
DOC_PARAM(cursor_out, On success this struct is filled with the result of the seek.)
DOC_RETURN(This call returns non-zero on success.)
DOC(Computes a Partial_Cursor for the given seek position with no side effects.
The seek position must be one of the types supported by Partial_Cursor. Those
types are absolute position and line,column position.)
DOC_SEE(Buffer_Seek)
DOC_SEE(Partial_Cursor)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file = imp_get_file(cmd, buffer);
bool32 result = false;
if (file){
if (file_compute_cursor(file, seek, cursor_out)){
result = true;
fill_buffer_summary(buffer, file, cmd);
}
}
return(result);
}
API_EXPORT bool32
Buffer_Batch_Edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type)/*
DOC_PARAM(str, This parameter provides all of the source string for the edits in the batch.)
@ -844,6 +903,26 @@ DOC_SEE(Buffer_Setting_ID)
file->settings.dos_write_mode = value;
file->state.last_4ed_edit_time = system->now_time_stamp();
}break;
case BufferSetting_Unimportant:
{
if (value){
file->settings.unimportant = true;
}
else{
file->settings.unimportant = false;
}
}break;
case BufferSetting_ReadOnly:
{
if (value){
file->settings.read_only = true;
}
else{
file->settings.read_only = false;
}
}break;
}
fill_buffer_summary(buffer, file, cmd);
}
@ -907,6 +986,7 @@ If the buffer does not exist a new buffer is created and named after the given f
the filename corresponds to a file on the disk that file is loaded and put into buffer, if
the filename does not correspond to a file on disk the buffer is created empty.
)
DOC_SEE(Buffer_Summary)
DOC_SEE(Buffer_Create_Flag)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
@ -1508,8 +1588,30 @@ DOC_SEE(Buffer_Seek)
seek.character = 1;
}
Full_Cursor cursor = view_compute_cursor(vptr, seek);
view_set_cursor(vptr, cursor,
set_preferred_x, vptr->file_data.unwrapped_lines);
view_set_cursor(vptr, cursor, set_preferred_x,
vptr->file_data.unwrapped_lines);
fill_view_summary(view, vptr, cmd);
}
}
return(result);
}
API_EXPORT bool32
View_Set_Scroll(Application_Links *app, View_Summary *view, GUI_Scroll_Vars scroll)/*
DOC(TODO)
DOC_SEE(GUI_Scroll_Vars)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
View *vptr = imp_get_view(cmd, view);
Editing_File *file = 0;
bool32 result = false;
if (vptr){
file = vptr->file_data.file;
if (file && !file->is_loading){
result = true;
view_set_scroll(vptr, scroll);
fill_view_summary(view, vptr, cmd);
}
}

View File

@ -377,6 +377,40 @@ view_cursor_limits(View *view){
return(limits);
}
inline Partial_Cursor
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
return(result);
}
inline Partial_Cursor
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
return(result);
}
inline b32
file_compute_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
b32 result = true;
switch (seek.type){
case buffer_seek_pos:
{
*cursor = file_compute_cursor_from_pos(file, seek.pos);
}break;
case buffer_seek_line_char:
{
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
}break;
default:
{
result = false;
}break;
}
return(result);
}
inline Full_Cursor
view_compute_cursor_from_pos(View *view, i32 pos){
Editing_File *file = view->file_data.file;
@ -5982,196 +6016,6 @@ file_view_free_buffers(View *view){
view->gui_mem = 0;
}
struct Search_Range{
Buffer_Type *buffer;
i32 start, size;
};
struct Search_Set{
Search_Range *ranges;
i32 count, max;
};
struct Search_Iter{
String word;
i32 pos;
i32 i;
};
struct Search_Match{
Buffer_Type *buffer;
i32 start, end;
b32 found_match;
};
internal void
search_iter_init(General_Memory *general, Search_Iter *iter, i32 size){
i32 str_max;
if (iter->word.str == 0){
str_max = size*2;
iter->word.str = (char*)general_memory_allocate(general, str_max);
iter->word.memory_size = str_max;
}
else if (iter->word.memory_size < size){
str_max = size*2;
iter->word.str = (char*)general_memory_reallocate_nocopy(general, iter->word.str, str_max);
iter->word.memory_size = str_max;
}
iter->i = 0;
iter->pos = 0;
}
internal void
search_set_init(General_Memory *general, Search_Set *set, i32 set_count){
i32 max;
if (set->ranges == 0){
max = set_count*2;
set->ranges = (Search_Range*)general_memory_allocate(general, sizeof(Search_Range)*max);
set->max = max;
}
else if (set->max < set_count){
max = set_count*2;
set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
general, set->ranges, sizeof(Search_Range)*max);
set->max = max;
}
set->count = set_count;
}
internal void
search_hits_table_alloc(General_Memory *general, Table *hits, i32 table_size){
void *mem;
i32 mem_size;
mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
if (hits->hash_array == 0){
mem = general_memory_allocate(general, mem_size);
}
else{
mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
}
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
}
internal void
search_hits_init(General_Memory *general, Table *hits, String_Space *str, i32 table_size, i32 str_size){
void *mem;
i32 mem_size;
if (hits->hash_array == 0){
search_hits_table_alloc(general, hits, table_size);
}
else if (hits->max < table_size){
mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
mem = general_memory_reallocate_nocopy(general, hits->hash_array, mem_size);
table_init_memory(hits, mem, table_size, sizeof(Offset_String));
}
if (str->space == 0){
str->space = (char*)general_memory_allocate(general, str_size);
str->max = str_size;
}
else if (str->max < str_size){
str->space = (char*)general_memory_reallocate_nocopy(general, str->space, str_size);
str->max = str_size;
}
str->pos = str->new_pos = 0;
table_clear(hits);
}
internal b32
search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *str, i32 len){
b32 result;
i32 new_size;
Offset_String ostring;
Table new_hits;
Assert(len != 0);
ostring = strspace_append(space, str, len);
if (ostring.size == 0){
new_size = Max(space->max*2, space->max + len);
space->space = (char*)general_memory_reallocate(general, space->space, space->new_pos, new_size);
ostring = strspace_append(space, str, len);
}
Assert(ostring.size != 0);
if (table_at_capacity(hits)){
search_hits_table_alloc(general, &new_hits, hits->max*2);
table_clear(&new_hits);
table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
general_memory_free(general, hits->hash_array);
*hits = new_hits;
}
if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
result = 1;
strspace_keep_prev(space);
}
else{
result = 0;
strspace_discard_prev(space);
}
return(result);
}
internal Search_Match
search_next_match(Partition *part, Search_Set *set, Search_Iter *iter_){
Search_Match result = {};
Search_Iter iter = *iter_;
Search_Range *range;
Temp_Memory temp;
char *spare;
i32 start_pos, end_pos, count;
temp = begin_temp_memory(part);
spare = push_array(part, char, iter.word.size);
count = set->count;
for (; iter.i < count;){
range = set->ranges + iter.i;
end_pos = range->start + range->size;
if (iter.pos + iter.word.size < end_pos){
start_pos = Max(iter.pos, range->start);
result.start = buffer_find_string(
range->buffer, start_pos, end_pos, iter.word.str, iter.word.size, spare);
if (result.start < end_pos){
iter.pos = result.start + 1;
if (result.start == 0 || !char_is_alpha_numeric(buffer_get_char(range->buffer, result.start - 1))){
result.end = buffer_seek_word_right_assume_on_word(range->buffer, result.start);
if (result.end < end_pos){
result.found_match = 1;
result.buffer = range->buffer;
iter.pos = result.end;
break;
}
}
}
else{
++iter.i, iter.pos = 0;
}
}
else{
++iter.i, iter.pos = 0;
}
}
end_temp_memory(temp);
*iter_ = iter;
return(result);
}
inline void
view_change_size(General_Memory *general, View *view){
if (view->file_data.file){

View File

@ -1069,6 +1069,21 @@ buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width,
return(state.cursor);
}
internal_4tech Partial_Cursor
buffer_partial_from_pos(Buffer_Type *buffer, int pos){
Partial_Cursor result = {0};
if (pos > buffer->size) pos = buffer->size;
if (pos < 0) pos = 0;
int line_index = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count);
result.pos = pos;
result.line = line_index+1;
result.character = pos - buffer->line_starts[line_index] + 1;
return(result);
}
internal_4tech Full_Cursor
buffer_cursor_from_pos(Buffer_Type *buffer, int pos, float *wraps,
float max_width, float font_height, float *advance_data){
@ -1086,20 +1101,45 @@ buffer_cursor_from_pos(Buffer_Type *buffer, int pos, float *wraps,
return(result);
}
internal_4tech Partial_Cursor
buffer_partial_from_line_character(Buffer_Type *buffer, int line, int character){
Partial_Cursor result = {0};
int line_index = line - 1;
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
int this_start = buffer->line_starts[line_index];
int next_start = buffer->size;
if (line_index+1 < buffer->line_count){
next_start = buffer->line_starts[line_index+1];
}
int max_character = (next_start-this_start);
if (character <= 0) character = 1;
if (character > max_character) character = max_character;
result.pos = this_start + character - 1;
result.line = line_index+1;
result.character = character;
return(result);
}
internal_4tech Full_Cursor
buffer_cursor_from_line_character(Buffer_Type *buffer, int line, int character, float *wraps,
float max_width, float font_height, float *advance_data){
Full_Cursor result;
int line_index;
line_index = line - 1;
Full_Cursor result = {0};
int line_index = line - 1;
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_line_char(line, character),
max_width, font_height, advance_data, result);
return(result);
}

View File

@ -238,17 +238,12 @@ get_bindings(void *data, int size){
default_keys(context);
// NOTE(allen|4.0.6): Command maps can be opened more than
// NOTE(allen|a4.0.6): Command maps can be opened more than
// once so that you can extend existing maps very easily.
// You can also use the helper "restart_map" instead of
// begin_map to clear everything that was in the map and
// bind new things instead.
begin_map(context, mapid_global);
bind(context, '.', MDFR_ALT, change_to_build_panel);
bind(context, ',', MDFR_ALT, close_build_panel);
bind(context, 'n', MDFR_ALT, goto_next_error);
bind(context, 'N', MDFR_ALT, goto_prev_error);
bind(context, 'M', MDFR_ALT, goto_first_error);
end_map(context);
begin_map(context, mapid_file);