readme generator started

This commit is contained in:
Allen Webster 2016-05-12 12:40:26 -04:00
parent ff83917900
commit db058ea6d7
6 changed files with 1326 additions and 624 deletions

View File

@ -1,195 +1,189 @@
Distribution Date: 12.05.2016 (dd.mm.yyyy)
Thank you for contributing to the 4coder project!
To submit bug reports or to request particular features email editor@4coder.net.
Watch 4coder.net blog and @AllenWebster4th twitter for news about 4coder progress.
---------------------------------
FAIR WARNING
---------------------------------
THINGS WILL GET CRASHY FAST IF ANY .ttf FILES ARE MISSING.
THIS EFFECT WILL ALSO OCCUR IF YOU LAUNCH FROM A DIRECTORY
THAT DOESN'T CONTAIN THE .ttf FILES. (This problem will be
fixed eventually).
This build is extremely "janky" for lack of a better term. From what limitted testing
I have been able to do I think it should run on a Windows 7 machine. It has not been
launched at all on any other version of Windows. I have done what I can to get rid of
the bugs and crashes that would make it unusable, but there are certainly more in there
if you start digging and pressing hard enough.
**Please USE SOURCE CONTROL WITH 4CODER for now**
-----------------------------------------------------
INSTRUCTIONS FOR USE
-----------------------------------------------------
****Changes in 4.0.3****
4coder now uses 0% CPU when you are not using it.
There is a scrollbar on files now. (It is not the nicest scrollbar to use in the world,
but the real purpose it serves is to indicate where in a file you are. I imagine most
scrolling will still happen with the wheel or cursor navigation.)
File lists are now arrow navigatable and scrollable... these two systems do no work
together very well yet.
Color adjusting is possible again, but the UI is heavily downgraded from the fancieness
of the old system.
While editing:
alt + Z: execute command line with the same output buffer and same command
as in the previous use of "alt + z".
****Changes in 4.0.2****
The previous file limit of 128 has been raised to something over 8 million.
A *messages* buffer is now opened on launch to provide some information about
new features and messages will be posted there to report events sometimes.
subst and link directories no longer confuse the system, it treats them as one file.
on the command line: -f <N> sets the font size, the default is 16
ctrl + e: centers the view on the cursor
****Changes in 4.0.0****
alt + x: changed to arbitrary command (NOW WORKS ANYWHERE!)
Opens a command prompt from which you can execute:
"open menu" to open the menu (old behavior of alt+x)
"open all code" loads all cpp and h files in current directory
"close all code" closes all cpp and h files currently open
"open in quotes" opens the file who's name under the cursor is surrounded by quotes
"dos lines" dosify the file end of iles
"nix lines" nixify the file end of iles
alt + z: execute arbitrary command-line command
Specify an output buffer and a command to execute
and the results will be dropped into the specified buffer.
****Command line options****
4ed [<files-to-open>] [options]
-d/-D <filename> -- use a dll other than 4coder_custom.dll for your customizations
-d -- if the file isn't found look for 4coder_custom.dll
-D -- only look for the specified
-i <line-number> -- line number to jump to in first file to open specified on command line
-w <w, h> -- width and height of the 4coder window
-p <x, y> -- position of the 4coder window
-W -- open in full screen, overrides -w and -p, although the size will still be the default size of the window
-T -- invoke special tool isntead of launching 4coder normally
-T version : prints the 4coder version string
****Old Information****
Basic Navigation:
mouse click - move cursor
arrows - move cursor
home & end - move cursor to beginning/end of line
page up & page down - page up & page down respectively
control + left/right - move cursor left/right to first whitespace
control + up/down - move cursor up or down to first blank line
Fancy Navigation:
control + f : begin find mode, uses interaction bar
control + r : begin reverse-find mode, uses interaction bar
While in find mode or reverse-find mode, pressing enter ends the mode
leaving the cursor wherever the find highlighter is, and pressing escape
ends the mode leaving the cursor wherever it was before the find mode began.
control + g - goto line number
control + m - swap cursor and mark
Basic Editing:
characters keys, delete, and backspace
control + c : copy between cursor and mark
control + x : cut between cursor and mark
control + v : paste at cursor
control + V : use after normal paste to cycle through older copied text
control + d : delete between cursor and mark
control + SPACE : set mark to cursor
Undo and History:
control + z : undo
control + y : redo
control + Z: undo / history timelines
control + h: history back step
control + H: history forward step
alt + left: increase rewind speed (through undo)
alt + right: increase fastforward speed (through redo)
alt + down: stop redining / fastforwarding
Fancy Editing:
control + u : to uppercase between cursor and mark
control + j : to lowercase between cursor and mark
control + q: query replace
control + a: replace in range
control + =: write increment
control + -: decrement increment
control + [: write {} pair with cursor in line between
control + {: as <control + [> with a semicolon after "}"
control + }: as <control + [> with a "break;" after "}"
control + 9: wrap the range specified by mark and cursor in parens
control + i: wrap the range specified by mark and cursor in #if 0 #endif
Whitespace Boringness:
Typing characters: },],),; and inserting newlines cause the line to autotab
TAB: word complete
control + TAB : auto indent lines between cursor and mark
shift + TAB: auto indent cursor line
control + 1 : set the file to dos mode for writing to disk
control + ! : set the flie to nix mode for writing to disk
Viewing Options:
alt + c - open theme selection UI
control + p : vertically split the current panel (max 16)
control + '-' : horizontally split the current panel (max 16)
control + P : close the currently selected panel
control + , : switch to another panel
control + l : toggle line wrapping
control + L : toggle end of line mode
mode 1: treat all \r\n and all \n as newline, show \r when not followed by \n
mode 2: treat all \r and \n as newline
mode 3: treat all \n as newline, show all \r
control + ? : toggle highlight whitespace mode
Tools:
alt + m : search in the current hot directory and up through all parent
> directories for a build.bat, and execute that bat if it discovered, sending
> output to the buffer *compilation*
File Managing:
control + n : create a new file, begins interactive input mode
control + o : open file, begins interactive input mode
control + O : reopen the current file
(discarding any differences the live version has from the file system's version)
control + s : save
control + w : save as, begins interative input mode
control + i : switch active file in this panel, begins interactive input mode
control + k : kill (close) a file, begins interactive input mode
control + K : kill (close) the file being viewed in the currently active panel
While in interactive input mode, pressing enter confirms the input for the command, and
pressing escape (once) will end the input mode and abort the command. If the file does
not exist either the nearest match will be opened, or no file will be opened if none is
considered a match. Use backspace to go back through directories.
Menu UI
Keyboard options:
> left control + left alt act as AltGr
Theme selection UI
esc - close UI view return to major view if one was open previously
Themes are saved in p4c files, I encourage either of the following pronciations:
"pack"
"pee-fork"
Distribution Date: 12.5.2016 (dd.mm.yyyy)
Thank you for contributing to the 4coder project!
To submit bug reports or to request particular features email editor@4coder.net.
Watch 4coder.net blog and @AllenWebster4th twitter for news about 4coder progress.
---------------------------------
FAIR WARNING
---------------------------------
THINGS WILL GET CRASHY FAST IF ANY .ttf FILES ARE MISSING.
THIS EFFECT WILL ALSO OCCUR IF YOU LAUNCH FROM A DIRECTORY
THAT DOESN'T CONTAIN THE .ttf FILES. (This problem will be
fixed eventually).
This build is extremely "janky" for lack of a better term. From what limitted testing
I have been able to do I think it should run on a Windows 7 machine. It has not been
launched at all on any other version of Windows. I have done what I can to get rid of
the bugs and crashes that would make it unusable, but there are certainly more in there
if you start digging and pressing hard enough.
**Please USE SOURCE CONTROL WITH 4CODER for now**
-----------------------------------------------------
INSTRUCTIONS FOR USE
-----------------------------------------------------
****Changes in 4.0.3****
4coder now uses 0% CPU when you are not using it.
There is a scrollbar on files now. (It is not the nicest scrollbar to use in the world,
but the real purpose it serves is to indicate where in a file you are. I imagine most
scrolling will still happen with the wheel or cursor navigation.)
File lists are now arrow navigatable and scrollable... these two systems do no work
together very well yet.
Color adjusting is possible again, but the UI is heavily downgraded from the fancieness
of the old system.
While editing:
alt + Z: execute command line with the same output buffer and same command
as in the previous use of "alt + z".
****Changes in 4.0.2****
The previous file limit of 128 has been raised to something over 8 million.
A *messages* buffer is now opened on launch to provide some information about
new features and messages will be posted there to report events sometimes.
subst and link directories no longer confuse the system, it treats them as one file.
on the command line: -f <N> sets the font size, the default is 16
ctrl + e: centers the view on the cursor
****Changes in 4.0.0****
alt + x: changed to arbitrary command (NOW WORKS ANYWHERE!)
Opens a command prompt from which you can execute:
"open menu" to open the menu (old behavior of alt+x)
"open all code" loads all cpp and h files in current directory
"close all code" closes all cpp and h files currently open
"open in quotes" opens the file who's name under the cursor is surrounded by quotes
"dos lines" dosify the file end of iles
"nix lines" nixify the file end of iles
alt + z: execute arbitrary command-line command
Specify an output buffer and a command to execute
and the results will be dropped into the specified buffer.
****Command line options****
4ed [<files-to-open>] [options]
-d/-D <filename> -- use a dll other than 4coder_custom.dll for your customizations
-d -- if the file isn't found look for 4coder_custom.dll
-D -- only look for the specified
-i <line-number> -- line number to jump to in first file to open specified on command line
-w <w, h> -- width and height of the 4coder window
-p <x, y> -- position of the 4coder window
-W -- open in full screen, overrides -w and -p, although the size will still be the default size of the window
-T -- invoke special tool isntead of launching 4coder normally
-T version : prints the 4coder version string
****Old Information****
Basic Navigation:
mouse click - move cursor
arrows - move cursor
home & end - move cursor to beginning/end of line
page up & page down - page up & page down respectively
control + left/right - move cursor left/right to first whitespace
control + up/down - move cursor up or down to first blank line
Fancy Navigation:
control + f : begin find mode, uses interaction bar
control + r : begin reverse-find mode, uses interaction bar
While in find mode or reverse-find mode, pressing enter ends the mode
leaving the cursor wherever the find highlighter is, and pressing escape
ends the mode leaving the cursor wherever it was before the find mode began.
control + g - goto line number
control + m - swap cursor and mark
Basic Editing:
characters keys, delete, and backspace
control + c : copy between cursor and mark
control + x : cut between cursor and mark
control + v : paste at cursor
control + V : use after normal paste to cycle through older copied text
control + d : delete between cursor and mark
control + SPACE : set mark to cursor
Undo and History:
control + z : undo
control + y : redo
control + Z: undo / history timelines
control + h: history back step
control + H: history forward step
alt + left: increase rewind speed (through undo)
alt + right: increase fastforward speed (through redo)
alt + down: stop redining / fastforwarding
Fancy Editing:
control + u : to uppercase between cursor and mark
control + j : to lowercase between cursor and mark
control + q: query replace
control + a: replace in range
control + =: write increment
control + -: decrement increment
control + [: write {} pair with cursor in line between
control + {: as <control + [> with a semicolon after "}"
control + }: as <control + [> with a "break;" after "}"
control + 9: wrap the range specified by mark and cursor in parens
control + i: wrap the range specified by mark and cursor in #if 0 #endif
Whitespace Boringness:
Typing characters: },],),; and inserting newlines cause the line to autotab
TAB: word complete
control + TAB : auto indent lines between cursor and mark
shift + TAB: auto indent cursor line
control + 1 : set the file to dos mode for writing to disk
control + ! : set the flie to nix mode for writing to disk
Viewing Options:
alt + c - open theme selection UI
control + p : vertically split the current panel (max 16)
control + '-' : horizontally split the current panel (max 16)
control + P : close the currently selected panel
control + , : switch to another panel
control + l : toggle line wrapping
control + L : toggle end of line mode
mode 1: treat all \r\n and all \n as newline, show \r when not followed by \n
mode 2: treat all \r and \n as newline
mode 3: treat all \n as newline, show all \r
control + ? : toggle highlight whitespace mode
Tools:
alt + m : search in the current hot directory and up through all parent
> directories for a build.bat, and execute that bat if it discovered, sending
> output to the buffer *compilation*
File Managing:
control + n : create a new file, begins interactive input mode
control + o : open file, begins interactive input mode
control + O : reopen the current file
(discarding any differences the live version has from the file system's version)
control + s : save
control + w : save as, begins interative input mode
control + i : switch active file in this panel, begins interactive input mode
control + k : kill (close) a file, begins interactive input mode
control + K : kill (close) the file being viewed in the currently active panel
While in interactive input mode, pressing enter confirms the input for the command, and
pressing escape (once) will end the input mode and abort the command. If the file does
not exist either the nearest match will be opened, or no file will be opened if none is
considered a match. Use backspace to go back through directories.
Menu UI
Keyboard options:
> left control + left alt act as AltGr
Theme selection UI
esc - close UI view return to major view if one was open previously

181
README_body.txt Normal file
View File

@ -0,0 +1,181 @@
---------------------------------
FAIR WARNING
---------------------------------
THINGS WILL GET CRASHY FAST IF ANY .ttf FILES ARE MISSING.
THIS EFFECT WILL ALSO OCCUR IF YOU LAUNCH FROM A DIRECTORY
THAT DOESN'T CONTAIN THE .ttf FILES. (This problem will be
fixed eventually).
This build is extremely "janky" for lack of a better term. From what limitted testing
I have been able to do I think it should run on a Windows 7 machine. It has not been
launched at all on any other version of Windows. I have done what I can to get rid of
the bugs and crashes that would make it unusable, but there are certainly more in there
if you start digging and pressing hard enough.
**Please USE SOURCE CONTROL WITH 4CODER for now**
-----------------------------------------------------
INSTRUCTIONS FOR USE
-----------------------------------------------------
****Changes in 4.0.3****
4coder now uses 0% CPU when you are not using it.
There is a scrollbar on files now. (It is not the nicest scrollbar to use in the world,
but the real purpose it serves is to indicate where in a file you are. I imagine most
scrolling will still happen with the wheel or cursor navigation.)
File lists are now arrow navigatable and scrollable... these two systems do no work
together very well yet.
Color adjusting is possible again, but the UI is heavily downgraded from the fancieness
of the old system.
While editing:
alt + Z: execute command line with the same output buffer and same command
as in the previous use of "alt + z".
****Changes in 4.0.2****
The previous file limit of 128 has been raised to something over 8 million.
A *messages* buffer is now opened on launch to provide some information about
new features and messages will be posted there to report events sometimes.
subst and link directories no longer confuse the system, it treats them as one file.
on the command line: -f <N> sets the font size, the default is 16
ctrl + e: centers the view on the cursor
****Changes in 4.0.0****
alt + x: changed to arbitrary command (NOW WORKS ANYWHERE!)
Opens a command prompt from which you can execute:
"open menu" to open the menu (old behavior of alt+x)
"open all code" loads all cpp and h files in current directory
"close all code" closes all cpp and h files currently open
"open in quotes" opens the file who's name under the cursor is surrounded by quotes
"dos lines" dosify the file end of iles
"nix lines" nixify the file end of iles
alt + z: execute arbitrary command-line command
Specify an output buffer and a command to execute
and the results will be dropped into the specified buffer.
****Command line options****
4ed [<files-to-open>] [options]
-d/-D <filename> -- use a dll other than 4coder_custom.dll for your customizations
-d -- if the file isn't found look for 4coder_custom.dll
-D -- only look for the specified
-i <line-number> -- line number to jump to in first file to open specified on command line
-w <w, h> -- width and height of the 4coder window
-p <x, y> -- position of the 4coder window
-W -- open in full screen, overrides -w and -p, although the size will still be the default size of the window
-T -- invoke special tool isntead of launching 4coder normally
-T version : prints the 4coder version string
****Old Information****
Basic Navigation:
mouse click - move cursor
arrows - move cursor
home & end - move cursor to beginning/end of line
page up & page down - page up & page down respectively
control + left/right - move cursor left/right to first whitespace
control + up/down - move cursor up or down to first blank line
Fancy Navigation:
control + f : begin find mode, uses interaction bar
control + r : begin reverse-find mode, uses interaction bar
While in find mode or reverse-find mode, pressing enter ends the mode
leaving the cursor wherever the find highlighter is, and pressing escape
ends the mode leaving the cursor wherever it was before the find mode began.
control + g - goto line number
control + m - swap cursor and mark
Basic Editing:
characters keys, delete, and backspace
control + c : copy between cursor and mark
control + x : cut between cursor and mark
control + v : paste at cursor
control + V : use after normal paste to cycle through older copied text
control + d : delete between cursor and mark
control + SPACE : set mark to cursor
Undo and History:
control + z : undo
control + y : redo
control + Z: undo / history timelines
control + h: history back step
control + H: history forward step
alt + left: increase rewind speed (through undo)
alt + right: increase fastforward speed (through redo)
alt + down: stop redining / fastforwarding
Fancy Editing:
control + u : to uppercase between cursor and mark
control + j : to lowercase between cursor and mark
control + q: query replace
control + a: replace in range
control + =: write increment
control + -: decrement increment
control + [: write {} pair with cursor in line between
control + {: as <control + [> with a semicolon after "}"
control + }: as <control + [> with a "break;" after "}"
control + 9: wrap the range specified by mark and cursor in parens
control + i: wrap the range specified by mark and cursor in #if 0 #endif
Whitespace Boringness:
Typing characters: },],),; and inserting newlines cause the line to autotab
TAB: word complete
control + TAB : auto indent lines between cursor and mark
shift + TAB: auto indent cursor line
control + 1 : set the file to dos mode for writing to disk
control + ! : set the flie to nix mode for writing to disk
Viewing Options:
alt + c - open theme selection UI
control + p : vertically split the current panel (max 16)
control + '-' : horizontally split the current panel (max 16)
control + P : close the currently selected panel
control + , : switch to another panel
control + l : toggle line wrapping
control + L : toggle end of line mode
mode 1: treat all \r\n and all \n as newline, show \r when not followed by \n
mode 2: treat all \r and \n as newline
mode 3: treat all \n as newline, show all \r
control + ? : toggle highlight whitespace mode
Tools:
alt + m : search in the current hot directory and up through all parent
> directories for a build.bat, and execute that bat if it discovered, sending
> output to the buffer *compilation*
File Managing:
control + n : create a new file, begins interactive input mode
control + o : open file, begins interactive input mode
control + O : reopen the current file
(discarding any differences the live version has from the file system's version)
control + s : save
control + w : save as, begins interative input mode
control + i : switch active file in this panel, begins interactive input mode
control + k : kill (close) a file, begins interactive input mode
control + K : kill (close) the file being viewed in the currently active panel
While in interactive input mode, pressing enter confirms the input for the command, and
pressing escape (once) will end the input mode and abort the command. If the file does
not exist either the nearest match will be opened, or no file will be opened if none is
considered a match. Use backspace to go back through directories.
Menu UI
Keyboard options:
> left control + left alt act as AltGr
Theme selection UI
esc - close UI view return to major view if one was open previously

View File

@ -1,428 +1,428 @@
Distribution Date: 12.05.2016 (dd.mm.yyyy)
Thank you for contributing to the 4coder project!
To submit bug reports or to request particular features email editor@4coder.net.
Watch 4coder.net blog and @AllenWebster4th twitter for news about 4coder progress.
-------------------------------------
BUILDING 4coder_custom
-------------------------------------
To customize 4coder you have to build 4coder_custom.dll. The batch file buildsuper.bat will
compile the dll for you if you have visual studio installed. If you have an old version, use
the example to figure out how to get your old setup working in the new system.
As you create your customizations keep in mind that this API is still in development.
I will do what I can to keep your customizations working as I settle on an API, but some
updates may deeply break your code.
-------------------------------------
SOME DOCUMENTATION
-------------------------------------
See comments in 4coder_default_bindings.cpp for more detailed information.
Functions to implement (optional in the dll, but required if you are using buildsuper.bat):
get_bindings
NEW IN 4.0.3:
================
The build system for customizations has been changed. There is no longer a 4coder_custom.cpp.
Instead the default customizations are in 4coder_default_bindings.cpp. The batch file takes a parameter
that tells it what file to treat as the target for building, if the parameter is not defined it defaults to
4coder_default_bindings.cpp.
NEW IN 4.0.2:
================
#include "4coder_default.cpp" at the top of your own file to get a lot of the default functions
such as incremental search, various word boundry seeks, and so on.
app->buffer_seek_string_insensitive(app, &buffer, start, str, len, seek_forward, &out);
Exactly the same as app->buffer_seek_string, but the matching rule is case insensitive
app->get_command_input(app);
Returns a User_Input that represents the input event that triggered the current command.
app->print_message(app, str, len);
Put a string into the *message* buffer.
OLD API DOC:
================================================================
There is an API available to custom commands and hooks, described at length here.
The system has two main data types, buffers and views. A buffer contains text,
undo history, and tokens. Views looks at a file and has a cursor a mark a highlight
and so on. The view and buffer are not the same because not all buffers are viewed,
and there may be two views viewing the same buffer.
================
app->memory;
app->memory_size;
Here you get 2mb of memory that are completely yours to do whatever you need to do. This is for
those who found that malloc was not working for their allocation needs. There are currently no
allocation helpers so you'll have to figure out how to manage it.
================
app->directory_get_hot(app, out, capacity);
Fills the out buffer with the "hot directory", which is the last directory 4coder has visited.
If it cannot write out the whole name it writes only what it can.
Always returns the length of the current hot directory in bytes.
================
app->file_exists(app, filename, len);
Filename can be either a full path or a relative path.
Returns whether the file exists.
================
app->directory_cd(app, dir, &len, capacity, rel_path, rel_len);
Looks at dir and updates it's contents as if a "cd" command had been cone from that directory.
if rel_path is ".." then the .. is not appended as a string, the directory is shortened if possible.
Returns false if the directory does not exist or if ".." was specified but it is impossible to back up,
returns true otherwise.
================
app->get_file_list(app, dir, len);
If the directory exists, generates a list of all files and folders in that directory. All File_List structs
generated by get_file_list should be freed with free_file_list.
Returns a File_List struct listing all files and folders in dir, or an empty list if dir does not exist or is empty.
================
app->free_file_list(app, list);
Frees a File_List created by get_file_list.
================
struct File_List;
The important fields are:
File_Info *infos;
int count;
count is the number of File_Info structs in the File_Info array.
struct File_Info;
String filename;
int folder;
folder is 1 or 0 to indicate whether the entry is a file or folder.
filrname is a string which may be editted, but not resized, that is filled with the name of a file or folder.
================
app->get_buffer_first(app);
app->get_buffer_next(app, &buffer);
The new method for looping over buffers is:
for (Buffer_Summary b = app->get_buffer_first(app);
b.exists;
app->get_buffer_next(app, &b)) { }
================
app->get_buffer(app, index);
Returns a Buffer_Summary which contains information about a buffer and acts as the
handle to the buffer for other functions. The parameter index can be anything in the
range [0,max) where max comes from app->get_buffer_max_index
================
app->get_active_buffer(app, index);
Returns a Buffer_Summary obtained from the active panel.
================
app->get_buffer_by_name(app, str, len);
Returns a Buffer_Summary who's "full source path" exactly matches str. There is
currently no way to look a buffer up by "live name" the short name shown on the top bar.
Buffers that are not associated with real files such as *compilation* have their "full source path"
name set to the same value as their live name, therefore you can get a *compilation* buffer with
this API by the name "*compilation*".
================
app->refresh_buffer(app, &buffer);
If a changes are made to a buffer the changes are not necessarily reflected in your Buffer_Summary,
use this to get updated information on the buffer. All commands in the low level API will udpate
your Buffer_Summary if a change is made, so refreshing afterwards is not necessary in that case.
The function returns 1 on success and 0 on failure.
================
app->buffer_seek_delimiter(app, &buffer, start, delim, seek_forward, &out);
Starting from start, seeks forward or backward until the first occurance of delim,
the pointer out is filled with the position of the delimiter.
If no delimiter is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
The function returns 1 on success and 0 on failure.
================
app->buffer_seek_string(app, &buffer, start, str, len, seek_forward, &out);
Starting from start, seeks forward or backward until the first occurance of str,
the pointer out is filled with the position of the delimiter.
If no str is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
The function returns 1 on success and 0 on failure.
================
app->buffer_read_range(app, &buffer, start, end, buffer_out);
Fills buffer_out with the text that the buffer contains in the range [start,end) it is your responsibility
to ensure that the memory pointed to by buffer_out is at least (end - start) bytes.
The function returns 1 on success and 0 on failure.
================
app->buffer_replace_range(app, &buffer, start, end, str, len);
Replaces the text in the range between start and end with the the text in str. It is allowed that
start == end so that you may insert str without replacing anything, and it is allowed that len == 0
so that you may delete text without replacing it with anything. These edits are tracked by history
and cause an update in the tokens if there are tokens. Your buffer will be updated to reflect
the change in the buffer caused by this edit.
The function returns 1 on success and 0 on failure.
================
View_Summary:
There use to be a lot of different view types and only "file views" were exposed in the API.
As of alpha 4 there are only views and you can always get a view.
Besides renaming the struct, there is also a change in the meaning of the "buffer_id" field.
A view can have a buffer attached, but not currently be looking at that file.
All of the following indicate the buffer associated with the view:
buffer_id
locked_buffer_id
hidden_buffer_id
These ids are nulled out to indicate that access at a particular level is not available.
buffer_id -
This is null if the file is not visible in the view OR if the view is locked.
A view is only locked right now for read only buffers (compilation output).
locked_buffer_id -
This is null only if the file is not visible.
hidden_buffer_id -
This is never null.
In normal circumstances you can just use buffer_id and your code will automatically do
nothing when you try to edit a buffer you should not.
If what you are writing is unusual and it SHOULD edit a buffer even if it is locked or
hidden, then you can use the other ids to get deeper access.
================
app->get_view_first(app);
app->get_view_next(app, &view);
The new method for looping over views is:
for (View_Summary v = app->get_view_first(app);
v.exists;
app->get_view_next(app, &v)) { }
================
app->get_file_view(app, index);
Returns a View_Summary which contains information about a file view and acts as
the handle to the file view for other functions. The parameter index can be anything in the
range [0,max) where max comes from app->get_view_max_index
================
app->get_active_file_view(app, index);
Returns a View_Summary obtained from the active panel.
================
app->refresh_file_view(app, &view);
If a changes are made to a view the changes are not necessarily reflected in your View_Summary,
use this to get updated information on the view. All commands in the low level API will udpate
your View_Summary if a change is made, so refreshing afterwards is not necessary in that case.
The function returns 1 on success and 0 on failure.
================
struct Buffer_Seek;
This struct specifies how to set a position in a file, it is in 4coder_buffer_types.h look there to see
all the options.
The following helpers will return Buffer_Seek structs for you:
+ To seek to a particular position (0-based-indexing) use seek_pos(pos)
+ To seek to a particular xy you either want seek_wrapped_xy(x, y, round_down)
or seek_unwrapped_xy(x, y, round_down). Wrapped vs unwrapped refers to whether
line wrapping is on. Both seek types are valid whether or not lines are wrapped, but
the results may be surprising if you do not match the correct type. round_down is usually 0,
and the effect is subtle, it has to do with whether the y position should be rounded down or rounded
to the nearest line. x and y are specified in pixels to move the y up or down a while line use view.line_height.
+ To seek to a particular line and character index on that line use seek_line_char(line, char_index)
================
app->view_set_cursor(app, &view, seek, set_preferred_x)
Updates the cursor location in this view. See information on the Buffer_Seek struct above for more
information. set_preferred_x if true set's the "preferred_x" of view to match the x of the cursor. The
preferred_x is the x the cursor tries to stay at as it moves up and down. Most cursor motion does set
the preferred_x.
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->view_set_mark(app, &view, seek)
Updates the mark location in this view. See information on the Buffer_Seek struct above for more
information.
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->view_set_highlight(app, &view, start, end, on)
If on is 0 this call turns the highlight off.
If on is 1 this call turns the highlight on and sets the highlight to range from start to end.
While the highlight is on the view will follow the end of the highlight and the cursor will be hidden.
Be sure to turn the highlight off when you're done with it!
The function returns 1 on success and 0 on failure.
================
app->view_set_file(app, &view, file_id)
Set this view to look at a different buffer (the buffer must already be opened and have a file_id).
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->get_user_input(app, get_type, abort_type);
This is a blocking operation that will allow 4coder to continue operating. The next input event
will be intercepted by this command, and will not be interpreted as normal. Input events include:
pressing a key
clicking left or right
rolling the mouse wheel
moving the mouse
The get_type flags specify a filter of what types of input you'd like to be notified about. Even if you
are not notified about keyboard input events, they are still not passed to any other systems to be
interpreted as commands or text input. The same is true for mouse input with the exception of
panel resizing, which can be done durring a command.
The abort_type flags specify the set of inputs you'd like to get an abort message on. It is good to
specify abort flags so that the system will know when your command is about to finish up. After
getting an abort message you can continue to do other work and call commands with exec_command
but you should not call app->get_user_input again. It will not cause an error if you do, but it could lead
to unexpected behavior. And in the future it might be that it IS an error to call get_user_input after an abort.
================
struct User_Input;
type: either UserInputKey or UserInputMouse
abort: true if this is an abort message, false otherwise
key: information about a key event
mouse: information about a mouse event
command: if this event would be translated into a command normally, this is the command.
Use CommandEqual to compare two commands in a typeless way since
cmdid_* and custom commands have different types.
================
key is of type:
struct Key_Event_Data;
keycode: always set to exactly the key that was pressed
character: a translation of the key press that takes into account Shift/Control/Alt/AltrGr/Caps-Lock
character_no_caps_lock: same as "character" but doesn't take Caps-Lock into account
modifiers[i]: flags for modifiers were held when this key was pressed
i: MDFR_SHIFT_INDEX, MDFR_CONTROL_INDEX, MDFR_ALT_INDEX, MDFR_CAPS_INDEX
TIP! Don't use MDFR_SHIFT, MDFR_CTRL, MDFR_ALT in the array! Those are bit masks, not indices!
================
mouse is of type:
struct Mouse_State;
l - whether the left button is down
r - whether the right button is down
press_l - whether the left button was just put down
press_r - whether the right button was just put down
release_l - whether the left button was just released
release_r - whether the right button was just released
wheel - values of 1, 0, -1. Does not report wheel amount, only direction.
out_of_window - 1 if the mouse is outside of the 4coder window, 0 otherwise
x, y - position of the mouse relative to the 4coder window
================
app->start_query_bar(app, &bar, 0);
Notify 4coder that you are using a Query_Bar and you want it rendered onto the screen.
While the query bar is still running any changes you make to prompt or string will be
shown right away, you don't have to ask 4coder to update it's bar because it reads straight
out of your Query_Bar.
If the pointer you pass goes bad, because a stack frame ends or you otherwise no longer
need the bar, you should call app->end_query_bar(app, &bar); so that 4coder doesn't try
to render a query bar from garbage memory. If the command finishes and there are query
bars that haven't been ended, 4coder automatically ends them.
There is a limit of 8 simultaneous queries bars and right now only file views support them.
The abillity to make a Query_Bar in other views including the empty view will come in the future though.
The 0 is there because Iintend to add flags for query bars in the future,
for modifying their appearance and behavior.
Returns 1 if it successfully started a query bar.
================
app->end_query_bar(app, &bar);
See start_query_bar for details.
================
Theme changing API
app->change_theme(app, name, len)
Set the theme to one of the prebuilt themes by name.
app->change_font(app, name, len)
Set the font to one of the fonts by name (not by ttf file name, by the name in the list).
app->set_theme_colors(app, colors, count)
Set colors of the current theme by tag color pairs.
Changes from 3.3 to 3.4:
-exposed command word complete
Changes from 3.2 to 3.3:
-exposed command build and added several example uses to the example file
-introduced directory navigation API
-slight tweaks to the API, moving away from macro translation
Changes from 3.1 to 3.2:
-exposed new commands relating to auto-tab
-removed old commands for whitespace cleaning
Changes from 3.0 to 3.1:
-start_hook eliminated, now bound through set_hook durring the get_bindings function
-vanilla_keys changed so that specific keys can be overriden
-you can now specify your own maps
-new parameter stack for communicating to some commands
-fulfill_interaction has been removed (push_parameter will be used to achieve it's effect)
-new hook for opening files, intended for file setting configuration
-exposed the new commands relating to history and the timeline scrub bar
Changes from 2.2.3 to 3.0:
-exposed the new undo / redo commands
Changes from 2.2.2 to 2.2.3:
-The binding API is remarkably different, but I included a
small set of helpers with this API that make the API look
almost exactly the same.
-you can now specify size for custom fonts
-you can now fulfill interacive commands
-fixed a bug that existed when some commands were used in exec_command
Changes from 2.2.1 to 2.2.2:
-added MDFR_SHIFT
-removed redundant keys from Key_Codes struct
-added bind_me
-added exec_command
-put bind, bind_me and exec_command into a struct
-added Custom_Command_Function
-added Start_Hook_Function
Distribution Date: 12.5.2016 (dd.mm.yyyy)
Thank you for contributing to the 4coder project!
To submit bug reports or to request particular features email editor@4coder.net.
Watch 4coder.net blog and @AllenWebster4th twitter for news about 4coder progress.
-------------------------------------
BUILDING 4coder_custom
-------------------------------------
To customize 4coder you have to build 4coder_custom.dll. The batch file buildsuper.bat will
compile the dll for you if you have visual studio installed. If you have an old version, use
the example to figure out how to get your old setup working in the new system.
As you create your customizations keep in mind that this API is still in development.
I will do what I can to keep your customizations working as I settle on an API, but some
updates may deeply break your code.
-------------------------------------
SOME DOCUMENTATION
-------------------------------------
See comments in 4coder_default_bindings.cpp for more detailed information.
Functions to implement (optional in the dll, but required if you are using buildsuper.bat):
get_bindings
NEW IN 4.0.3:
================
The build system for customizations has been changed. There is no longer a 4coder_custom.cpp.
Instead the default customizations are in 4coder_default_bindings.cpp. The batch file takes a parameter
that tells it what file to treat as the target for building, if the parameter is not defined it defaults to
4coder_default_bindings.cpp.
NEW IN 4.0.2:
================
#include "4coder_default.cpp" at the top of your own file to get a lot of the default functions
such as incremental search, various word boundry seeks, and so on.
app->buffer_seek_string_insensitive(app, &buffer, start, str, len, seek_forward, &out);
Exactly the same as app->buffer_seek_string, but the matching rule is case insensitive
app->get_command_input(app);
Returns a User_Input that represents the input event that triggered the current command.
app->print_message(app, str, len);
Put a string into the *message* buffer.
OLD API DOC:
================================================================
There is an API available to custom commands and hooks, described at length here.
The system has two main data types, buffers and views. A buffer contains text,
undo history, and tokens. Views looks at a file and has a cursor a mark a highlight
and so on. The view and buffer are not the same because not all buffers are viewed,
and there may be two views viewing the same buffer.
================
app->memory;
app->memory_size;
Here you get 2mb of memory that are completely yours to do whatever you need to do. This is for
those who found that malloc was not working for their allocation needs. There are currently no
allocation helpers so you'll have to figure out how to manage it.
================
app->directory_get_hot(app, out, capacity);
Fills the out buffer with the "hot directory", which is the last directory 4coder has visited.
If it cannot write out the whole name it writes only what it can.
Always returns the length of the current hot directory in bytes.
================
app->file_exists(app, filename, len);
Filename can be either a full path or a relative path.
Returns whether the file exists.
================
app->directory_cd(app, dir, &len, capacity, rel_path, rel_len);
Looks at dir and updates it's contents as if a "cd" command had been cone from that directory.
if rel_path is ".." then the .. is not appended as a string, the directory is shortened if possible.
Returns false if the directory does not exist or if ".." was specified but it is impossible to back up,
returns true otherwise.
================
app->get_file_list(app, dir, len);
If the directory exists, generates a list of all files and folders in that directory. All File_List structs
generated by get_file_list should be freed with free_file_list.
Returns a File_List struct listing all files and folders in dir, or an empty list if dir does not exist or is empty.
================
app->free_file_list(app, list);
Frees a File_List created by get_file_list.
================
struct File_List;
The important fields are:
File_Info *infos;
int count;
count is the number of File_Info structs in the File_Info array.
struct File_Info;
String filename;
int folder;
folder is 1 or 0 to indicate whether the entry is a file or folder.
filrname is a string which may be editted, but not resized, that is filled with the name of a file or folder.
================
app->get_buffer_first(app);
app->get_buffer_next(app, &buffer);
The new method for looping over buffers is:
for (Buffer_Summary b = app->get_buffer_first(app);
b.exists;
app->get_buffer_next(app, &b)) { }
================
app->get_buffer(app, index);
Returns a Buffer_Summary which contains information about a buffer and acts as the
handle to the buffer for other functions. The parameter index can be anything in the
range [0,max) where max comes from app->get_buffer_max_index
================
app->get_active_buffer(app, index);
Returns a Buffer_Summary obtained from the active panel.
================
app->get_buffer_by_name(app, str, len);
Returns a Buffer_Summary who's "full source path" exactly matches str. There is
currently no way to look a buffer up by "live name" the short name shown on the top bar.
Buffers that are not associated with real files such as *compilation* have their "full source path"
name set to the same value as their live name, therefore you can get a *compilation* buffer with
this API by the name "*compilation*".
================
app->refresh_buffer(app, &buffer);
If a changes are made to a buffer the changes are not necessarily reflected in your Buffer_Summary,
use this to get updated information on the buffer. All commands in the low level API will udpate
your Buffer_Summary if a change is made, so refreshing afterwards is not necessary in that case.
The function returns 1 on success and 0 on failure.
================
app->buffer_seek_delimiter(app, &buffer, start, delim, seek_forward, &out);
Starting from start, seeks forward or backward until the first occurance of delim,
the pointer out is filled with the position of the delimiter.
If no delimiter is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
The function returns 1 on success and 0 on failure.
================
app->buffer_seek_string(app, &buffer, start, str, len, seek_forward, &out);
Starting from start, seeks forward or backward until the first occurance of str,
the pointer out is filled with the position of the delimiter.
If no str is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
The function returns 1 on success and 0 on failure.
================
app->buffer_read_range(app, &buffer, start, end, buffer_out);
Fills buffer_out with the text that the buffer contains in the range [start,end) it is your responsibility
to ensure that the memory pointed to by buffer_out is at least (end - start) bytes.
The function returns 1 on success and 0 on failure.
================
app->buffer_replace_range(app, &buffer, start, end, str, len);
Replaces the text in the range between start and end with the the text in str. It is allowed that
start == end so that you may insert str without replacing anything, and it is allowed that len == 0
so that you may delete text without replacing it with anything. These edits are tracked by history
and cause an update in the tokens if there are tokens. Your buffer will be updated to reflect
the change in the buffer caused by this edit.
The function returns 1 on success and 0 on failure.
================
View_Summary:
There use to be a lot of different view types and only "file views" were exposed in the API.
As of alpha 4 there are only views and you can always get a view.
Besides renaming the struct, there is also a change in the meaning of the "buffer_id" field.
A view can have a buffer attached, but not currently be looking at that file.
All of the following indicate the buffer associated with the view:
buffer_id
locked_buffer_id
hidden_buffer_id
These ids are nulled out to indicate that access at a particular level is not available.
buffer_id -
This is null if the file is not visible in the view OR if the view is locked.
A view is only locked right now for read only buffers (compilation output).
locked_buffer_id -
This is null only if the file is not visible.
hidden_buffer_id -
This is never null.
In normal circumstances you can just use buffer_id and your code will automatically do
nothing when you try to edit a buffer you should not.
If what you are writing is unusual and it SHOULD edit a buffer even if it is locked or
hidden, then you can use the other ids to get deeper access.
================
app->get_view_first(app);
app->get_view_next(app, &view);
The new method for looping over views is:
for (View_Summary v = app->get_view_first(app);
v.exists;
app->get_view_next(app, &v)) { }
================
app->get_file_view(app, index);
Returns a View_Summary which contains information about a file view and acts as
the handle to the file view for other functions. The parameter index can be anything in the
range [0,max) where max comes from app->get_view_max_index
================
app->get_active_file_view(app, index);
Returns a View_Summary obtained from the active panel.
================
app->refresh_file_view(app, &view);
If a changes are made to a view the changes are not necessarily reflected in your View_Summary,
use this to get updated information on the view. All commands in the low level API will udpate
your View_Summary if a change is made, so refreshing afterwards is not necessary in that case.
The function returns 1 on success and 0 on failure.
================
struct Buffer_Seek;
This struct specifies how to set a position in a file, it is in 4coder_buffer_types.h look there to see
all the options.
The following helpers will return Buffer_Seek structs for you:
+ To seek to a particular position (0-based-indexing) use seek_pos(pos)
+ To seek to a particular xy you either want seek_wrapped_xy(x, y, round_down)
or seek_unwrapped_xy(x, y, round_down). Wrapped vs unwrapped refers to whether
line wrapping is on. Both seek types are valid whether or not lines are wrapped, but
the results may be surprising if you do not match the correct type. round_down is usually 0,
and the effect is subtle, it has to do with whether the y position should be rounded down or rounded
to the nearest line. x and y are specified in pixels to move the y up or down a while line use view.line_height.
+ To seek to a particular line and character index on that line use seek_line_char(line, char_index)
================
app->view_set_cursor(app, &view, seek, set_preferred_x)
Updates the cursor location in this view. See information on the Buffer_Seek struct above for more
information. set_preferred_x if true set's the "preferred_x" of view to match the x of the cursor. The
preferred_x is the x the cursor tries to stay at as it moves up and down. Most cursor motion does set
the preferred_x.
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->view_set_mark(app, &view, seek)
Updates the mark location in this view. See information on the Buffer_Seek struct above for more
information.
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->view_set_highlight(app, &view, start, end, on)
If on is 0 this call turns the highlight off.
If on is 1 this call turns the highlight on and sets the highlight to range from start to end.
While the highlight is on the view will follow the end of the highlight and the cursor will be hidden.
Be sure to turn the highlight off when you're done with it!
The function returns 1 on success and 0 on failure.
================
app->view_set_file(app, &view, file_id)
Set this view to look at a different buffer (the buffer must already be opened and have a file_id).
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->get_user_input(app, get_type, abort_type);
This is a blocking operation that will allow 4coder to continue operating. The next input event
will be intercepted by this command, and will not be interpreted as normal. Input events include:
pressing a key
clicking left or right
rolling the mouse wheel
moving the mouse
The get_type flags specify a filter of what types of input you'd like to be notified about. Even if you
are not notified about keyboard input events, they are still not passed to any other systems to be
interpreted as commands or text input. The same is true for mouse input with the exception of
panel resizing, which can be done durring a command.
The abort_type flags specify the set of inputs you'd like to get an abort message on. It is good to
specify abort flags so that the system will know when your command is about to finish up. After
getting an abort message you can continue to do other work and call commands with exec_command
but you should not call app->get_user_input again. It will not cause an error if you do, but it could lead
to unexpected behavior. And in the future it might be that it IS an error to call get_user_input after an abort.
================
struct User_Input;
type: either UserInputKey or UserInputMouse
abort: true if this is an abort message, false otherwise
key: information about a key event
mouse: information about a mouse event
command: if this event would be translated into a command normally, this is the command.
Use CommandEqual to compare two commands in a typeless way since
cmdid_* and custom commands have different types.
================
key is of type:
struct Key_Event_Data;
keycode: always set to exactly the key that was pressed
character: a translation of the key press that takes into account Shift/Control/Alt/AltrGr/Caps-Lock
character_no_caps_lock: same as "character" but doesn't take Caps-Lock into account
modifiers[i]: flags for modifiers were held when this key was pressed
i: MDFR_SHIFT_INDEX, MDFR_CONTROL_INDEX, MDFR_ALT_INDEX, MDFR_CAPS_INDEX
TIP! Don't use MDFR_SHIFT, MDFR_CTRL, MDFR_ALT in the array! Those are bit masks, not indices!
================
mouse is of type:
struct Mouse_State;
l - whether the left button is down
r - whether the right button is down
press_l - whether the left button was just put down
press_r - whether the right button was just put down
release_l - whether the left button was just released
release_r - whether the right button was just released
wheel - values of 1, 0, -1. Does not report wheel amount, only direction.
out_of_window - 1 if the mouse is outside of the 4coder window, 0 otherwise
x, y - position of the mouse relative to the 4coder window
================
app->start_query_bar(app, &bar, 0);
Notify 4coder that you are using a Query_Bar and you want it rendered onto the screen.
While the query bar is still running any changes you make to prompt or string will be
shown right away, you don't have to ask 4coder to update it's bar because it reads straight
out of your Query_Bar.
If the pointer you pass goes bad, because a stack frame ends or you otherwise no longer
need the bar, you should call app->end_query_bar(app, &bar); so that 4coder doesn't try
to render a query bar from garbage memory. If the command finishes and there are query
bars that haven't been ended, 4coder automatically ends them.
There is a limit of 8 simultaneous queries bars and right now only file views support them.
The abillity to make a Query_Bar in other views including the empty view will come in the future though.
The 0 is there because Iintend to add flags for query bars in the future,
for modifying their appearance and behavior.
Returns 1 if it successfully started a query bar.
================
app->end_query_bar(app, &bar);
See start_query_bar for details.
================
Theme changing API
app->change_theme(app, name, len)
Set the theme to one of the prebuilt themes by name.
app->change_font(app, name, len)
Set the font to one of the fonts by name (not by ttf file name, by the name in the list).
app->set_theme_colors(app, colors, count)
Set colors of the current theme by tag color pairs.
Changes from 3.3 to 3.4:
-exposed command word complete
Changes from 3.2 to 3.3:
-exposed command build and added several example uses to the example file
-introduced directory navigation API
-slight tweaks to the API, moving away from macro translation
Changes from 3.1 to 3.2:
-exposed new commands relating to auto-tab
-removed old commands for whitespace cleaning
Changes from 3.0 to 3.1:
-start_hook eliminated, now bound through set_hook durring the get_bindings function
-vanilla_keys changed so that specific keys can be overriden
-you can now specify your own maps
-new parameter stack for communicating to some commands
-fulfill_interaction has been removed (push_parameter will be used to achieve it's effect)
-new hook for opening files, intended for file setting configuration
-exposed the new commands relating to history and the timeline scrub bar
Changes from 2.2.3 to 3.0:
-exposed the new undo / redo commands
Changes from 2.2.2 to 2.2.3:
-The binding API is remarkably different, but I included a
small set of helpers with this API that make the API look
almost exactly the same.
-you can now specify size for custom fonts
-you can now fulfill interacive commands
-fixed a bug that existed when some commands were used in exec_command
Changes from 2.2.1 to 2.2.2:
-added MDFR_SHIFT
-removed redundant keys from Key_Codes struct
-added bind_me
-added exec_command
-put bind, bind_me and exec_command into a struct
-added Custom_Command_Function
-added Start_Hook_Function

420
SUPERREADME_body.txt Normal file
View File

@ -0,0 +1,420 @@
-------------------------------------
BUILDING 4coder_custom
-------------------------------------
To customize 4coder you have to build 4coder_custom.dll. The batch file buildsuper.bat will
compile the dll for you if you have visual studio installed. If you have an old version, use
the example to figure out how to get your old setup working in the new system.
As you create your customizations keep in mind that this API is still in development.
I will do what I can to keep your customizations working as I settle on an API, but some
updates may deeply break your code.
-------------------------------------
SOME DOCUMENTATION
-------------------------------------
See comments in 4coder_default_bindings.cpp for more detailed information.
Functions to implement (optional in the dll, but required if you are using buildsuper.bat):
get_bindings
NEW IN 4.0.3:
================
The build system for customizations has been changed. There is no longer a 4coder_custom.cpp.
Instead the default customizations are in 4coder_default_bindings.cpp. The batch file takes a parameter
that tells it what file to treat as the target for building, if the parameter is not defined it defaults to
4coder_default_bindings.cpp.
NEW IN 4.0.2:
================
#include "4coder_default.cpp" at the top of your own file to get a lot of the default functions
such as incremental search, various word boundry seeks, and so on.
app->buffer_seek_string_insensitive(app, &buffer, start, str, len, seek_forward, &out);
Exactly the same as app->buffer_seek_string, but the matching rule is case insensitive
app->get_command_input(app);
Returns a User_Input that represents the input event that triggered the current command.
app->print_message(app, str, len);
Put a string into the *message* buffer.
OLD API DOC:
================================================================
There is an API available to custom commands and hooks, described at length here.
The system has two main data types, buffers and views. A buffer contains text,
undo history, and tokens. Views looks at a file and has a cursor a mark a highlight
and so on. The view and buffer are not the same because not all buffers are viewed,
and there may be two views viewing the same buffer.
================
app->memory;
app->memory_size;
Here you get 2mb of memory that are completely yours to do whatever you need to do. This is for
those who found that malloc was not working for their allocation needs. There are currently no
allocation helpers so you'll have to figure out how to manage it.
================
app->directory_get_hot(app, out, capacity);
Fills the out buffer with the "hot directory", which is the last directory 4coder has visited.
If it cannot write out the whole name it writes only what it can.
Always returns the length of the current hot directory in bytes.
================
app->file_exists(app, filename, len);
Filename can be either a full path or a relative path.
Returns whether the file exists.
================
app->directory_cd(app, dir, &len, capacity, rel_path, rel_len);
Looks at dir and updates it's contents as if a "cd" command had been cone from that directory.
if rel_path is ".." then the .. is not appended as a string, the directory is shortened if possible.
Returns false if the directory does not exist or if ".." was specified but it is impossible to back up,
returns true otherwise.
================
app->get_file_list(app, dir, len);
If the directory exists, generates a list of all files and folders in that directory. All File_List structs
generated by get_file_list should be freed with free_file_list.
Returns a File_List struct listing all files and folders in dir, or an empty list if dir does not exist or is empty.
================
app->free_file_list(app, list);
Frees a File_List created by get_file_list.
================
struct File_List;
The important fields are:
File_Info *infos;
int count;
count is the number of File_Info structs in the File_Info array.
struct File_Info;
String filename;
int folder;
folder is 1 or 0 to indicate whether the entry is a file or folder.
filrname is a string which may be editted, but not resized, that is filled with the name of a file or folder.
================
app->get_buffer_first(app);
app->get_buffer_next(app, &buffer);
The new method for looping over buffers is:
for (Buffer_Summary b = app->get_buffer_first(app);
b.exists;
app->get_buffer_next(app, &b)) { }
================
app->get_buffer(app, index);
Returns a Buffer_Summary which contains information about a buffer and acts as the
handle to the buffer for other functions. The parameter index can be anything in the
range [0,max) where max comes from app->get_buffer_max_index
================
app->get_active_buffer(app, index);
Returns a Buffer_Summary obtained from the active panel.
================
app->get_buffer_by_name(app, str, len);
Returns a Buffer_Summary who's "full source path" exactly matches str. There is
currently no way to look a buffer up by "live name" the short name shown on the top bar.
Buffers that are not associated with real files such as *compilation* have their "full source path"
name set to the same value as their live name, therefore you can get a *compilation* buffer with
this API by the name "*compilation*".
================
app->refresh_buffer(app, &buffer);
If a changes are made to a buffer the changes are not necessarily reflected in your Buffer_Summary,
use this to get updated information on the buffer. All commands in the low level API will udpate
your Buffer_Summary if a change is made, so refreshing afterwards is not necessary in that case.
The function returns 1 on success and 0 on failure.
================
app->buffer_seek_delimiter(app, &buffer, start, delim, seek_forward, &out);
Starting from start, seeks forward or backward until the first occurance of delim,
the pointer out is filled with the position of the delimiter.
If no delimiter is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
The function returns 1 on success and 0 on failure.
================
app->buffer_seek_string(app, &buffer, start, str, len, seek_forward, &out);
Starting from start, seeks forward or backward until the first occurance of str,
the pointer out is filled with the position of the delimiter.
If no str is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
The function returns 1 on success and 0 on failure.
================
app->buffer_read_range(app, &buffer, start, end, buffer_out);
Fills buffer_out with the text that the buffer contains in the range [start,end) it is your responsibility
to ensure that the memory pointed to by buffer_out is at least (end - start) bytes.
The function returns 1 on success and 0 on failure.
================
app->buffer_replace_range(app, &buffer, start, end, str, len);
Replaces the text in the range between start and end with the the text in str. It is allowed that
start == end so that you may insert str without replacing anything, and it is allowed that len == 0
so that you may delete text without replacing it with anything. These edits are tracked by history
and cause an update in the tokens if there are tokens. Your buffer will be updated to reflect
the change in the buffer caused by this edit.
The function returns 1 on success and 0 on failure.
================
View_Summary:
There use to be a lot of different view types and only "file views" were exposed in the API.
As of alpha 4 there are only views and you can always get a view.
Besides renaming the struct, there is also a change in the meaning of the "buffer_id" field.
A view can have a buffer attached, but not currently be looking at that file.
All of the following indicate the buffer associated with the view:
buffer_id
locked_buffer_id
hidden_buffer_id
These ids are nulled out to indicate that access at a particular level is not available.
buffer_id -
This is null if the file is not visible in the view OR if the view is locked.
A view is only locked right now for read only buffers (compilation output).
locked_buffer_id -
This is null only if the file is not visible.
hidden_buffer_id -
This is never null.
In normal circumstances you can just use buffer_id and your code will automatically do
nothing when you try to edit a buffer you should not.
If what you are writing is unusual and it SHOULD edit a buffer even if it is locked or
hidden, then you can use the other ids to get deeper access.
================
app->get_view_first(app);
app->get_view_next(app, &view);
The new method for looping over views is:
for (View_Summary v = app->get_view_first(app);
v.exists;
app->get_view_next(app, &v)) { }
================
app->get_file_view(app, index);
Returns a View_Summary which contains information about a file view and acts as
the handle to the file view for other functions. The parameter index can be anything in the
range [0,max) where max comes from app->get_view_max_index
================
app->get_active_file_view(app, index);
Returns a View_Summary obtained from the active panel.
================
app->refresh_file_view(app, &view);
If a changes are made to a view the changes are not necessarily reflected in your View_Summary,
use this to get updated information on the view. All commands in the low level API will udpate
your View_Summary if a change is made, so refreshing afterwards is not necessary in that case.
The function returns 1 on success and 0 on failure.
================
struct Buffer_Seek;
This struct specifies how to set a position in a file, it is in 4coder_buffer_types.h look there to see
all the options.
The following helpers will return Buffer_Seek structs for you:
+ To seek to a particular position (0-based-indexing) use seek_pos(pos)
+ To seek to a particular xy you either want seek_wrapped_xy(x, y, round_down)
or seek_unwrapped_xy(x, y, round_down). Wrapped vs unwrapped refers to whether
line wrapping is on. Both seek types are valid whether or not lines are wrapped, but
the results may be surprising if you do not match the correct type. round_down is usually 0,
and the effect is subtle, it has to do with whether the y position should be rounded down or rounded
to the nearest line. x and y are specified in pixels to move the y up or down a while line use view.line_height.
+ To seek to a particular line and character index on that line use seek_line_char(line, char_index)
================
app->view_set_cursor(app, &view, seek, set_preferred_x)
Updates the cursor location in this view. See information on the Buffer_Seek struct above for more
information. set_preferred_x if true set's the "preferred_x" of view to match the x of the cursor. The
preferred_x is the x the cursor tries to stay at as it moves up and down. Most cursor motion does set
the preferred_x.
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->view_set_mark(app, &view, seek)
Updates the mark location in this view. See information on the Buffer_Seek struct above for more
information.
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->view_set_highlight(app, &view, start, end, on)
If on is 0 this call turns the highlight off.
If on is 1 this call turns the highlight on and sets the highlight to range from start to end.
While the highlight is on the view will follow the end of the highlight and the cursor will be hidden.
Be sure to turn the highlight off when you're done with it!
The function returns 1 on success and 0 on failure.
================
app->view_set_file(app, &view, file_id)
Set this view to look at a different buffer (the buffer must already be opened and have a file_id).
The function updates the data in the View_Summary.
The function returns 1 on success and 0 on failure.
================
app->get_user_input(app, get_type, abort_type);
This is a blocking operation that will allow 4coder to continue operating. The next input event
will be intercepted by this command, and will not be interpreted as normal. Input events include:
pressing a key
clicking left or right
rolling the mouse wheel
moving the mouse
The get_type flags specify a filter of what types of input you'd like to be notified about. Even if you
are not notified about keyboard input events, they are still not passed to any other systems to be
interpreted as commands or text input. The same is true for mouse input with the exception of
panel resizing, which can be done durring a command.
The abort_type flags specify the set of inputs you'd like to get an abort message on. It is good to
specify abort flags so that the system will know when your command is about to finish up. After
getting an abort message you can continue to do other work and call commands with exec_command
but you should not call app->get_user_input again. It will not cause an error if you do, but it could lead
to unexpected behavior. And in the future it might be that it IS an error to call get_user_input after an abort.
================
struct User_Input;
type: either UserInputKey or UserInputMouse
abort: true if this is an abort message, false otherwise
key: information about a key event
mouse: information about a mouse event
command: if this event would be translated into a command normally, this is the command.
Use CommandEqual to compare two commands in a typeless way since
cmdid_* and custom commands have different types.
================
key is of type:
struct Key_Event_Data;
keycode: always set to exactly the key that was pressed
character: a translation of the key press that takes into account Shift/Control/Alt/AltrGr/Caps-Lock
character_no_caps_lock: same as "character" but doesn't take Caps-Lock into account
modifiers[i]: flags for modifiers were held when this key was pressed
i: MDFR_SHIFT_INDEX, MDFR_CONTROL_INDEX, MDFR_ALT_INDEX, MDFR_CAPS_INDEX
TIP! Don't use MDFR_SHIFT, MDFR_CTRL, MDFR_ALT in the array! Those are bit masks, not indices!
================
mouse is of type:
struct Mouse_State;
l - whether the left button is down
r - whether the right button is down
press_l - whether the left button was just put down
press_r - whether the right button was just put down
release_l - whether the left button was just released
release_r - whether the right button was just released
wheel - values of 1, 0, -1. Does not report wheel amount, only direction.
out_of_window - 1 if the mouse is outside of the 4coder window, 0 otherwise
x, y - position of the mouse relative to the 4coder window
================
app->start_query_bar(app, &bar, 0);
Notify 4coder that you are using a Query_Bar and you want it rendered onto the screen.
While the query bar is still running any changes you make to prompt or string will be
shown right away, you don't have to ask 4coder to update it's bar because it reads straight
out of your Query_Bar.
If the pointer you pass goes bad, because a stack frame ends or you otherwise no longer
need the bar, you should call app->end_query_bar(app, &bar); so that 4coder doesn't try
to render a query bar from garbage memory. If the command finishes and there are query
bars that haven't been ended, 4coder automatically ends them.
There is a limit of 8 simultaneous queries bars and right now only file views support them.
The abillity to make a Query_Bar in other views including the empty view will come in the future though.
The 0 is there because Iintend to add flags for query bars in the future,
for modifying their appearance and behavior.
Returns 1 if it successfully started a query bar.
================
app->end_query_bar(app, &bar);
See start_query_bar for details.
================
Theme changing API
app->change_theme(app, name, len)
Set the theme to one of the prebuilt themes by name.
app->change_font(app, name, len)
Set the font to one of the fonts by name (not by ttf file name, by the name in the list).
app->set_theme_colors(app, colors, count)
Set colors of the current theme by tag color pairs.
Changes from 3.3 to 3.4:
-exposed command word complete
Changes from 3.2 to 3.3:
-exposed command build and added several example uses to the example file
-introduced directory navigation API
-slight tweaks to the API, moving away from macro translation
Changes from 3.1 to 3.2:
-exposed new commands relating to auto-tab
-removed old commands for whitespace cleaning
Changes from 3.0 to 3.1:
-start_hook eliminated, now bound through set_hook durring the get_bindings function
-vanilla_keys changed so that specific keys can be overriden
-you can now specify your own maps
-new parameter stack for communicating to some commands
-fulfill_interaction has been removed (push_parameter will be used to achieve it's effect)
-new hook for opening files, intended for file setting configuration
-exposed the new commands relating to history and the timeline scrub bar
Changes from 2.2.3 to 3.0:
-exposed the new undo / redo commands
Changes from 2.2.2 to 2.2.3:
-The binding API is remarkably different, but I included a
small set of helpers with this API that make the API look
almost exactly the same.
-you can now specify size for custom fonts
-you can now fulfill interacive commands
-fixed a bug that existed when some commands were used in exec_command
Changes from 2.2.1 to 2.2.2:
-added MDFR_SHIFT
-removed redundant keys from Key_Codes struct
-added bind_me
-added exec_command
-put bind, bind_me and exec_command into a struct
-added Custom_Command_Function
-added Start_Hook_Function

View File

@ -1,6 +1,13 @@
@echo off
pushd W:\4ed\meta
cl %OPTS% ..\code\readme_generator.c /Fereadmegen
popd
pushd W:\4ed\code
..\meta\readmegen
call "build_all.bat" /O2
copy ..\build\4ed.exe ..\current_dist\4coder\*
copy ..\build\4ed.pdb ..\current_dist\4coder\*
@ -9,7 +16,9 @@ copy ..\build\4ed_app.pdb ..\current_dist\4coder\*
copy ..\data\* ..\current_dist\4coder\*
copy README.txt ..\current_dist\4coder\*
copy TODO.txt ..\current_dist\4coder\*
del ..\current_dist\SUPERREADME.txt
del ..\current_dist\4coder\basic.cpp
del ..\current_dist\4coder\.4coder_settings
call "build_all.bat" /O2 /DFRED_SUPER
copy ..\build\4ed.exe ..\current_dist_super\4coder\*
@ -29,8 +38,10 @@ REM del ..\current_dist_super\4coder\*.pdb
del ..\current_dist_super\4coder\*.lib
del ..\current_dist_super\4coder\*.obj
del ..\current_dist_super\4coder\4coder_custom.dll
del ..\current_dist_super\4coder\.4coder_settings
del ..\current_dist_power\power\* /F /Q
copy power\* ..\current_dist_power\power\*
popd
popd

96
readme_generator.c Normal file
View File

@ -0,0 +1,96 @@
/*
* For generating the header of the TODO files so I don't have to
* keep doing that by hand and accidentally forgetting half the time.
* -Allen
* 12.05.2016 (dd.mm.yyyy)
*
*/
// TOP
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
char *header =
"Distribution Date: %d.%d.%d (dd.mm.yyyy)\n"
"\n"
"Thank you for contributing to the 4coder project!\n"
"\n"
"To submit bug reports or to request particular features email editor@4coder.net.\n"
"\n"
"Watch 4coder.net blog and @AllenWebster4th twitter for news about 4coder progress.\n"
"\n"
;
typedef struct Readme_Variables{
int day, month, year;
} Readme_Variables;
typedef struct File_Data{
char *data;
int size;
int file_exists;
} File_Data;
File_Data
dump(char *file_name){
File_Data result = {0};
FILE *file = fopen(file_name, "rb");
if (file){
result.file_exists = 1;
fseek(file, 0, SEEK_END);
result.size = ftell(file);
if (result.size > 0){
result.data = (char*)malloc(result.size + 1);
result.data[result.size + 1] = 0;
fseek(file, 0, SEEK_SET);
fread(result.data, 1, result.size, file);
}
fclose(file);
}
return(result);
}
void
generate(char *file_name_out, char *file_name_body, Readme_Variables vars){
File_Data in;
FILE *out;
in = dump(file_name_body);
if (in.file_exists){
out = fopen(file_name_out, "wb");
fprintf(out, header, vars.day, vars.month,vars.year);
if (in.size > 0){
fprintf(out, "%s", in.data);
}
fclose(out);
}
}
int
main(){
time_t ctime;
struct tm tm;
Readme_Variables vars;
ctime = time(0);
localtime_s(&tm, &ctime);
vars.day = tm.tm_mday;
vars.month = tm.tm_mon + 1;
vars.year = tm.tm_year + 1900;
generate("README.txt", "README_body.txt", vars);
generate("SUPERREADME.txt", "SUPERREADME_body.txt", vars);
return(0);
}
// BOTTOM