=Intro=
This is API for [[CudaText]] in Python. 

* Main Py module is cudatext. Main module has constants, funcs, class Editor, objects of class Editor.
* Additional module: cudatext_cmd has constants for command runner func.

=Event plugins=

To make plugin react to events, add method to class Command (like methods of command plugin). E.g. method "on_save" will be called by editor event on_save. Event methods have additional parameter ed_self: Editor object in which event occured (this object is the same as "ed" in 99% cases, but in rare cases event occurs in non-focused editor).

==Common==

* on_open(self, ed_self): Called after file is opened from disk.
* on_open_pre(self, ed_self, filename): Called before file opening. Method can return False to disable opening, other value is ignored.
* on_close(self, ed_self): Called just before closing tab (closing editor still active).
* on_tab_move(self, ed_self): Called after closing tab (another tab already activated), or moving tab (by drag-n-drop, or UI command).
* on_save_pre(self, ed_self): Called before saving file. Method can return False to disable saving, other value is ignored.
* on_save(self, ed_self): Called after saving file.
* on_change(self, ed_self): Called after text is changed.
* on_change_slow(self, ed_self): Called after text is changed, after few seconds. This is for Lint plugins, they need to react to change after a delay.
* on_caret(self, ed_self): Called after caret position/selection changed.
* on_key(self, ed_self, key, state): Called when user presses a key. key is int key code. state is string of chars: "a" if Alt pressed, "c" if Ctrl pressed, "s" if Shift pressed, "m" if Meta (Windows-key) pressed. Method can return False do disable key processing, other return value is ignored.
* on_key_up(self, ed_self, key, state): Called when user unpresses a key. Only for Ctrl/Shift/Alt (to not slow down).
* on_focus(self, ed_self): Called after editor is focused.
* on_lexer(self, ed_self): Called after lexer is changed.
* on_start(self, ed_self): Called once on program start (ignore ed_self).
* on_state(self, ed_self, state): Called after some app-state is changed. Param state is one of EDSTATE_nnnn numbers.
* on_snippet(self, ed_self, snippet_id, snippet_text): Called when user chooses snippet to insert, in ed.complete_alt call.

==Clicks==

* on_click(self, ed_self, state): Called after mouse click. state has the same meaning as in on_key.
* on_click_dbl(self, ed_self, state): Called after mouse double-click. state has the same meaning as in on_key. Method can return False to disable default processing.
* on_click_gap(self, ed_self, state, nline, ntag, size_x, size_y, pos_x, pos_y): Called after mouse click on inter-line gap: see Editor.gap().

==Code parsing==

* on_complete(self, ed_self): Called by auto-completion command (default hotkey: Ctrl+Space). Method should call Editor.complete API. Method must return True if it handled command, otherwise None.  
* on_goto_def(self, ed_self): Called by go-to-definition command (in editor context menu). Method must return True if it handled command, otherwise None.
* on_func_hint(self, ed_self): Called by function-hint command (default hotkey: Ctrl+Shift+Space). Method must return function-hint string (comma-separated parameters, brackets are optional). Empty str or None means no hint found.

==Panels==

* on_console(self, ed_self, text): Called on entering text command in Python Console panel. Method can return False to disable internal command processing, other value is ignored. Ignore ed_self.
* on_console_nav(self, ed_self, text): Called on dbl-clicking line, or calling context menu item "Navigate", in Python Console panel. Ignore ed_self. Text is line with caret.
* on_output_nav(self, ed_self, text, tag): Called on clicking line, or pressing Enter, in Output or Validate panel. Ignore ed_self. Text is clicked line, tag is int value associated with line. Event is called only if app cannot parse output line by itself using given regex (or regex isn't set at all).
* on_panel(self, ed_self, id_control, id_event): Called when event in side panel occured. Id_control is int handle of control in panel. Id_event is one of:
** "on_click"
** "on_dbl_click"
** "on_sel"
** "on_menu"

==Macros==

* on_macro(self, ed_self, text): Called when command "macros: stop recording" runs. In text the "\n"-separated list of macro items is passed. These items were run after command "macros: start recording" and before command "macros: stop recording".
** if item is "number" then it's simple command.
** if item is "number,string" then it's command with str parameter (usually it's command cCommand_TextInsert).
** if item is "py:string_module,string_method,string_param" then it's call of Python plugin (usually string_param is empty).

Notes:

* To run each on_macro item (with number) later, call ed.cmd(): number is command code, string after comma is command text.

==Events priority==

By default all events in all plugins have prior=0. So for any event, if 2+ plugins have this event, they're called in order on module names (e.g. cuda_aa, then cuda_dd, then cuda_mmm).

You may want to handle some event first.
To change prior for your plugin event, write in install.inf event like this: "on_key+", "on_key++"... with any number of "+" up to 4. Each "+" makes higher prior. So first called "on_key" with maximal number of "+", last called "on_key" w/o "+".

=Global funcs=

===version===

 app_exe_version()

Gets version of program (string).

 app_api_version()

Gets version of API (string, contains 3 numbers, dot-separated).

Example of version check:

  from cudatext import *
  
  if app_api_version() < '1.0.140':
      msg_box('Plugin MyName needs newer app version', MB_OK+MB_ICONWARNING)

===app_path===

 app_path(id)

Gets some path. Possible values of id:

* APP_DIR_EXE: Dir of program executable.
* APP_DIR_SETTINGS: Dir "settings".
* APP_DIR_DATA: Dir "data".
* APP_DIR_PY: Dir "py" with Python files.
* APP_DIR_INSTALLED_ADDON: Dir of last installed addon (for plugins it is folder in "py", for data-files it is folder in "data", for lexers it is folder "lexlib"). This dir is updated only if addon installed via file_open() or from app (Open dialog or command line).
* APP_FILE_SESSION: Filename of current session. Default filename is "history session.json" without path. Missing path means that folder "settings" will be used. 
* APP_FILE_RECENTS: Str: "\n"-separated filenames of recent files.

Note: to get path of dir "settings_default", use base dir of "settings".

===app_proc===

 app_proc(id, text)

Performs application-wide action. Possible values of id:

====Misc properties====

* PROC_GET_LANG: Gets string id of active translation. E.g. "ru_RU" if translation file is "ru_RU.ini". Or "translation template" if such file is used. Empty string if built-in English translation is used.
* PROC_GET_GROUPING: Gets grouping mode in program, it's one of GROUPS_nnnn int contants.
* PROC_SET_GROUPING: Sets grouping mode in program, pass str(value) where value is one of GROUPS_nnnn int contants.
* PROC_GET_FIND_OPTIONS: Gets options of finder-object as string.
* PROC_SET_FIND_OPTIONS: Sets options of finder-object from string. Note: Find dialog don't apply these opts immediately.
* PROC_GET_FIND_STRINGS: Gets strings of finder-object, 2-tuple, (str_search_for, str_replace_with), or None if finder-object not inited.
* PROC_GET_GUI_HEIGHT: Gets height (pixels) of GUI element for dlg_custom(). Possible values of text: 'button', 'label', 'combo', 'combo_ro', 'edit', 'spinedit', 'check', 'radio', 'checkbutton'. Gets None for other values.

====Clipboard====

* PROC_GET_CLIP: Gets clipboard text.
* PROC_SET_CLIP: Copies text to clipboard.

====Plugin calls====

* PROC_SET_EVENTS: Subscribe plugin to events. Param text must be 4 values ";"-separated: "module_name;event_list;lexer_list;keycode_list". 
** event_list is comma-separated event names. e.g. "on_open,on_save", or empty str to unsubscribe from all. 
** lexer_list is comma-separated lexer names.
** keycode_list is comma-separated int key codes, it can be used when on_key event was specified (event will fire only for specified key codes).
* PROC_GET_LAST_PLUGIN: Gets info about last plugin which run from program. It is str "module_name,method_name", values are empty if no plugins run yet.
* PROC_SET_SUBCOMMANDS: Adds command items for plugin (for fixed module/method). Param text must be ";"-separated: "module_name;method_name;param_list". Param_list is "\n"-separated items. Each item is s_caption+"\t"+s_param_value. s_caption is caption for Commands dialog item, s_param_value is parameter for Python method (it can be any primitive type: 20, None, False, 'Test here', or expression).
* PROC_GET_COMMAND: Gets info about item from application commands-list, with index int(text), 0-based. Gets tuple: (command_int_code, command_name, hotkey_str_1, hotkey_str_2), or None if index not correct. To enumerate all commands: call it from index "0", until you get None result.
* PROC_GET_COMMAND_INITIAL: Same as PROC_GET_COMMAND, but gets info only about "initial state", which was before reading hotkey configs (main config and lexer-specific configs). 
* PROC_GET_COMMAND_PLUGIN: Allows to enumerate all command plugins (and items which were set in PROC_SET_SUBCOMMANDS). Call it with str(N), from N=0, until you get None. Gets 5-tuple about N-th item (caption, module, method, param, lexers).

====Hotkeys====

Notes:

* command_id can be: str(int_command_code) or "module,method" or "module,method,param".

Actions:

* PROC_GET_ESCAPE: Gets Esc-key state (bool). This flag is set when user presses Esc key (each Esc press is counted since app start). Note: to allow app to handle key press in long loop, call msg_status('text', True).
* PROC_SET_ESCAPE: Sets Esc-key flag. Text must be "0"/"1".
* PROC_GET_HOTKEY: Gets hotkeys strings for given command_id. Examples of result: "F1", "Ctrl+B * B", "Ctrl+B * B * C|Ctrl+B * D" (two hotkeys for one command). Gets empty str for unknown command_id.
* PROC_SET_HOTKEY: Sets hotkeys for given command_id from strings. Text must be "command_id|hotkey1|hotkey2", where hotkey1/hotkey2 examples: "F1", "Ctrl+B * B", "Ctrl+B * B * C". Symbol "*" can be without near spaces. Gets bool: command_id exists, changed.
* PROC_GET_KEYSTATE: Gets state of pressed special keys. String has "c" for Ctrl pressed, "a" for Alt, "s" for Shift, "m" for Meta (Windows key).
* PROC_HOTKEY_INT_TO_STR: Converts given int hotkey to string. Gets empty str for unknown code.
* PROC_HOTKEY_STR_TO_INT: Converts given string hotkey to int. Gets 0 for incorrect string. Example: converts "alt+shift+z" to "41050", which is then converted to "Shift+Alt+Z".

====Python====
* PROC_EXEC_PYTHON: Runs Python string in the context of Console (it is not the same as exec() call). Also gets string: result of command.
* PROC_EXEC_PLUGIN: Runs Python plugin's method. Text must be ","-separated: "module_name,method_name,param_string", where param_string can be missed, this is parameter(s) for method.

====Themes====

Notes:
* Theme names are short strings, lowercase, e.g. "cobalt", "sub". Empty string means built-in theme.
* Setting default theme (empty str) resets both UI + syntax themes.
* To enumerate themes, you need to list themes folder.

Actions:

* PROC_THEME_UI_GET: Gets UI-theme name.
* PROC_THEME_UI_SET: Sets UI-theme name.
* PROC_THEME_SYNTAX_GET: Gets syntax-theme name.
* PROC_THEME_SYNTAX_SET: Sets syntax-theme name.

====Sessions====

Session is a set of opened files + untitled tabs, with some properties of editors in these tabs, with group-indexes of tabs, with layout of groups. Session format is JSON.

* PROC_SAVE_SESSION: Saves session to file with given name. 
* PROC_LOAD_SESSION: Loads session from file with given name. 
* PROC_SET_SESSION: Tells to app filename of session. Session with this filename will be saved on exit, loaded on start, shown in app title in {} brackets. Don't set here empty string. Default filename is "history session.json" without path. Missing path means that folder "settings" will be used.

====Menus====

menu_id can be:

* str(int_value) to specify menu item by unique int value
* "top" to specify top menu
* "top-file"/"top-edit"/"top-sel"/"top-sr"/"top-view"/"top-op"/"top-help" to specify submenus File/Edit/Selection/Search/View/Options/Help
* "text" to specify editor context menu
* "side:"+tab_caption to specify context menu of sidebar panel (e.g. "side:Tree", "side:Project")
* "btm:"+tab_caption to specify context menu of bottom panel
* "toolmenu:"+name to specify drop-down submenu of toolbar button

Actions:

* PROC_MENU_ENUM: Enumerates sub-items in menu item. Param text must be menu_id. Gets str: "\n"-separated strings for sub-items. These strings are:
** for usual command items: "caption|int_command|menu_id" 
** for plugin command items: "caption|plugin_module,plugin_method|menu_id" 
** for separator items: "-||menu_id"
** for submenu items: 2nd part (between "|" chars) is not a command code, such items are "caption||menu_id" or "caption|string_hint|menu_id"

* PROC_MENU_CLEAR: Removes all sub-items from menu item. Param text must be menu_id.

* PROC_MENU_ADD: Adds sub-item to menu item. This returns string, menu_id for newly added sub-item. Param text must be "menu_id;menu_cmd;menu_caption;menu_index". Parts are:
** menu_id is item in which you add sub-item. 
** menu_caption is caption, or "-" for menu separator.
** menu_index is str(index) for 0-based index at which to insert sub-item; empty menu_index or "-1": add item at end.
** menu_cmd can be:
*** str(int_command) - int command code, from module cudatext_cmd (pass 0 if item does nothing)
*** special values: 
**** "recents", "_recents" - recent-files submenu
**** "enc", "_enc" - encodings submenu (has subitems "reload as", "convert to")
**** "langs", "_langs" - translations submenu
**** "lexers", "_lexers" - lexers submenu
**** "plugins", "_plugins" - plugins submenu
**** "themes-ui", "_themes-ui" - ui-themes submenu 
**** "themes-syntax", "_themes-syntax" - syntax-themes submenu 
*** str_module+","+str_method - method in command plugin. Also allowed to add here ","+s_param - to pass parameter to method (param can be of any primitive type).
*** any string (e.g. empty string), if item will be used as submenu (item will be submenu, if any sub-items will be added to it)

====Side panel====

* PROC_SIDEPANEL_ADD: Adds tab+control to sidebar. Text is ","-separated params: "tab_caption,tab_index,control_type": caption of tab, index of tab (0-based, -1 to append), type of GUI control. Types of control allowed: "tree" to use tree_proc() API, "listbox" to use listbox_proc() API. Gets bool: params ok, tab was added.
* PROC_SIDEPANEL_REMOVE: Removes tab. Text is caption of tab. (Note: actually it hides tab, so control/menu for this tab is still in memory). Gets bool: tab was found/removed.
* PROC_SIDEPANEL_ACTIVATE: Activates tab in sidebar. Text is caption of tab. Gets bool: tab was found/activated.
* PROC_SIDEPANEL_ENUM: Enumerates tabs. Gets str, "\n"-separated captions of tabs.
* PROC_SIDEPANEL_GET_CONTROL: Gets int handle of control, inserted into tab. Pass this handle to tree_proc() or listbox_proc() API. Text is caption of tab. Gets None if cannot find tab.

==== Bottom panel====

* PROC_BOTTOMPANEL_ADD: Adds tab. Same as for PROC_SIDEPANEL_ADD.
* PROC_BOTTOMPANEL_REMOVE: Removes tab. Same as for PROC_SIDEPANEL_REMOVE.
* PROC_BOTTOMPANEL_ACTIVATE: Activates tab. Same as for PROC_SIDEPANEL_ACTIVATE.
* PROC_BOTTOMPANEL_ENUM: Enumerates tabs. Same as for PROC_SIDEPANEL_ENUM.
* PROC_BOTTOMPANEL_GET_CONTROL: Gets int handle of control. Same as for PROC_SIDEPANEL_GET_CONTROL.

====Splitters====

* PROC_GET_SPLIT: Gets info about splitter position, 4-tuple: (is_vertical_0_1, is_visible_0_1, splitter_pos, parent_panel_size). Text must be splitter id (incorrect value gives parent_panel_size=0).
* PROC_SET_SPLIT: Sets position of splitter. Text must be "splitter_id;splitter_pos".

Splitter id can be:
* "L": left splitter (near Side panel)
* "B": bottom splitter (near Bottom panel)
* "G1"..."G3": splitters between groups. Note: positions are determined by grouping view, in one view splitter may be horizontal with one parent panel, in other view - vertical with another parent panel.

How groups-splitters are placed in views:
<pre>
2VERT     t G1 t          
2HORZ     t               
          G1              
          t               
3VERT     t G1 t G2 t     
3HORZ     t               
          G1              
          t               
          G2              
          t               
1P2VERT    t G3 t
               G2
                t
1P2HORZ    t
           G3
           t G2 t
4VERT     t G1 t G2 t G3 t
4HORZ     t               
          G1              
          t               
          G2              
          t               
          G3              
          t               
4GRID     t G1 t          
          G3              
          t G2 t          
6GRID     t G1 t G2 t     
          G3              
          t G1 t G2 t     
</pre>

====Toolbar====

Btn_command can be:

* str(int_command) for predefined commands
* "module,method,params" for plugin commands
* "toolmenu:"+name for button which shows menu (customize this menu using PROC_MENU_nnnnn)

Id:

* PROC_TOOLBAR_ENUM: Enumerates toolbar buttons. Gets "\n"-separated lines for buttons: 
** "btn_hint;btn_string_id;btn_caption" for predefined buttons (btn_string_id is not a number, it is short string)
** "btn_hint;btn_command;btn_caption" for new buttons.
* PROC_TOOLBAR_ADD: Adds toolbar button. Text must be "btn_hint;icon_index;btn_command;btn_caption" or empty str to add separator. Styles of buttons:
** caption (e.g. "hint;-1;2700;caption")
** icon + caption (e.g. "hint;0;2700;caption")
** arrow (e.g. "hint;-1;toolmenu:main;")
** caption + arrow (e.g. "hint;-1;toolmenu:main;caption")
** separator line ("")

* PROC_TOOLBAR_DELETE: Deletes one toolbar button. Text must be str(button_index).
* PROC_TOOLBAR_DELETE_ALL: Deletes all toolbar buttons.
* PROC_TOOLBAR_ICON_ADD: Adds icon to imagelist of toolbar. Text must be path to .bmp or .png file. Gets int icon index (0-based), or None if cannot read icon.
* PROC_TOOLBAR_ICON_SET: Changes icon of toolbar button. Text must be "btn_index,icon_index". Indexes are 0-based.
* PROC_TOOLBAR_ICON_GET_SIZE: Gets icon size of toolbar, as 2-tuple (size_x, size_y).
* PROC_TOOLBAR_ICON_SET_SIZE: Sets icon size of toolbar. Text must be str(size_x)+","+str(size_y).

====Show/Hide UI elements====

Actions can get show-state of UI elements, or set show-state (pass "0" to hide, "1" to show):

* PROC_SHOW_STATUSBAR_GET
* PROC_SHOW_STATUSBAR_SET
* PROC_SHOW_TOOLBAR_GET
* PROC_SHOW_TOOLBAR_SET
* PROC_SHOW_SIDEPANEL_GET
* PROC_SHOW_SIDEPANEL_SET
* PROC_SHOW_BOTTOMPANEL_GET
* PROC_SHOW_BOTTOMPANEL_SET
* PROC_SHOW_TABS_GET
* PROC_SHOW_TABS_SET

====Screen coordinates====

Notes:

* When getting coords, you get 4-tuple of int: (x1, y1, x2, y2)
* When setting coords, you should pass such string: '%d,%d,%d,%d' % (x1, y1, x2, y2)

Actions:

* PROC_COORD_WINDOW_GET: Gets coords of app window.
* PROC_COORD_WINDOW_SET: Sets coords of app window.
* PROC_COORD_DESKTOP: Gets coords of virtual desktop, which includes all monitors.
* PROC_COORD_MONITOR: Gets coords of monitor with app window.
* PROC_COORD_MONITOR0: Gets coords of 1st monitor.
* PROC_COORD_MONITOR1: Gets coords of 2nd monitor, or None if no such monitor.
* PROC_COORD_MONITOR2: Gets coords of 3rd monitor, or None if no such monitor.
* PROC_COORD_MONITOR3: Gets coords of 4th monitor, or None if no such monitor.

===app_log===

 app_log(id, text, tag=0)

Controls panels in the bottom panel: Console, Output, Validate, and additional panels.

Possible values of id:

* LOG_CLEAR: Clears active log panel, text is ignored.
* LOG_ADD: Adds line to active log panel. Param tag is used here: it's int value associated with line, it's passed in on_output_nav.
* LOG_SET_PANEL: Sets active log panel. Text must be LOG_PANEL_OUTPUT, LOG_PANEL_VALIDATE, or caption of additional panel (see LOG_PANEL_ADD). Incorrect text will stop next operations with panels, until correct value set.
* LOG_SET_REGEX: Sets parsing regex for active log panel. Regex must have some groups in round brackets, indexes of these groups must be passed in separate API calls. All lines in log panel, which can be parsed by this regex, will allow navigation to source code by click or double-click.
* LOG_SET_LINE_ID: Sets index of regex group for line-number. text is one-char string from "1" to "8", and "0" means "not used".
* LOG_SET_COL_ID: Sets index of regex group for column-number.
* LOG_SET_NAME_ID: Sets index of regex group for file-name.
* LOG_SET_FILENAME: Sets default file-name, which will be used when regex cannot find file-name in a string. 
* LOG_SET_ZEROBASE: Sets flag: line and column numbers are zero-based, not 1-based. text is one-char string "0" or "1".
* LOG_GET_LINES: Gets str: "\n"-separated lines in listbox. Each line is text+"\r"+str(tag).
* LOG_GET_LINEINDEX: Gets index of selected line in listbox.
* LOG_SET_LINEINDEX: Sets index of selected line in listbox.
* LOG_PANEL_ADD: Adds new panel next to Output/Validate. Text is caption of panel. Gets True if panel was added; gets False for incorrect caption: caption of standard or already added panel.
* LOG_PANEL_DELETE: Deletes panel added with LOG_PANEL_ADD. Text is caption of panel. Gets True if panel found and deleted.
* LOG_PANEL_FOCUS: Focuses panel added with LOG_PANEL_ADD. Text is caption of panel. Gets True if panel found and focused.

For "Python console" panel:

* LOG_CONSOLE_CLEAR: Clears controls in console. 
** If text empty or has "m" then memo-control (above) is cleared. 
** If text empty or has "e" then edit-control (below) is cleared.
** If text empty or has "h" then combobox history list is cleared.
* LOG_CONSOLE_ADD: Adds line to console, combobox and memo.
* LOG_CONSOLE_GET: Gets "\n"-separated lines of console combobox history.
* LOG_CONSOLE_GET_LOG: Gets "\n"-separated lines of console memo text.

Example for regex:

For line "line 10 column 20: text message here" the following regex and indexes can be used:

* regex "\w+ (\d+) \w+ (\d+): .+"
* line-number index "1"
* column-number index "2"
* file-name index "0" (not used)
* zero-base flag "0" (off)

===app_idle===

 app_idle(wait=False)

Performs application's message-processing. If wait=True, also waits for new UI event.

===msg_box===

 msg_box(text, flags)

Shows modal message-box with given text.

Param flags is sum of button-value (OK, OK/Cancel, Yes/No etc) and icon-value (Info, Warning, Error, Question):

* MB_OK
* MB_OKCANCEL
* MB_ABORTRETRYIGNORE
* MB_YESNOCANCEL
* MB_YESNO
* MB_RETRYCANCEL

* MB_ICONERROR
* MB_ICONQUESTION
* MB_ICONWARNING
* MB_ICONINFO

Gets int code of button pressed:

* ID_OK
* ID_CANCEL
* ID_ABORT
* ID_RETRY
* ID_IGNORE
* ID_YES
* ID_NO

===msg_status===

 msg_status(text, process_messages=False)

Shows given text in statusbar.

Param process_messages: if True, function also does UI messages processing. It takes some time, it is needed to refresh status of Esc-key pressed. After call msg_status(..., True) you can get state of Esc-key pressed via PROC_GET_ESCAPE, else plugin gets old state, until UI messages are processed.

===msg_status_alt===

 msg_status_alt(text, seconds)

Shows given text in alternative statusbar, just above normal statusbar. Status has entire window width. Status shows only for some seconds (1..30).

===dlg_input===

 dlg_input(label, defvalue)

Shows modal dialog to input one string.

Gets entered string or None of cancelled.

===dlg_input_ex===

 dlg_input_ex(number, caption,
               label1   , text1="", label2="", text2="", label3="", text3="",
               label4="", text4="", label5="", text5="", label6="", text6="",
               label7="", text7="", label8="", text8="", label9="", text9="",
               label10="", text10="")

Shows modal dialog to enter 1 to 10 strings. Param number is count of strings.

Gets list of entered strings or None if cancelled.

===dlg_file===

 dlg_file(is_open, init_filename, init_dir, filters)

Shows file-open or file-save-as modal dialog.

Gets filename (str) or None if cancelled. Params:

* is_open: True for open dialog, False for save-as dialog.
* init_filename: Initial filename for save-as dialog. Can be empty.
* init_dir: Initial dir for dialog. Can be empty.
* filters: Sets file filters for dialog. Can be empty. Example, 2 filters: "Texts|*.pas;*.txt|Include|*.inc"

To allow multi-select in open dialog, pass init_filename="*". If single filename selected, result is str. If several filenames selected, result is list of str.

To disable check "filename exists" in open dialog, start init_filename with "!".

===dlg_dir===

 dlg_dir(init_dir)

Shows dialog to select folder. Gets folder path, or None if cancelled.

===dlg_menu===

 dlg_menu(id, text, focused=0)

Shows menu dialog.
Gets index of selected item (0-base), or None of cancelled. Param focused is index of initial item.

Possible values of id:

* MENU_LIST: Dialog with listbox similar to Commands dialog of CudaText, with filter field.
* MENU_LIST_ALT: Like MENU_LIST but each item has 2x height, and instead of right-aligning, part of an item shows below.

Param text is string items, separated by "\n" char. Each item can be simple str or str1+"\t"+str2 (str2 shows right-aligned or below).

===dlg_color===

 dlg_color(value)

Shows select-color dialog with given initial color (int).

Gets int color, or None if cancelled.

===dlg_hotkey===

 dlg_hotkey(title="")

Shows dialog to input hotkey. Gets str of hotkey (e.g. "F1", "Ctrl+Alt+B") or None if cancelled.

===dlg_hotkeys===

 dlg_hotkeys(command, lexer="")

Shows dialog to configure hotkeys of internal command or plugin. Gets bool: OK pressed and hotkeys saved (to keys.json).

Param command can be:

* str(int_command): for internal command codes (module cudatext_cmd).
* "module_name,method_name" or "module_name,method_name,method_param": for command plugin.

Param lexer is optional lexer name. If not empty, dialog enables checkbox "For current lexer" and (if checkbox checked) can save hotkey to "keys lexer NNNN.json".

===dlg_custom===

 dlg_custom(title, size_x, size_y, text, focused=-1)

Shows dialog with controls of many types.

Parameter text is "\n"-separated items, one item per control. Each item is chr(1)-separated props. Each prop is s_name+"="+s_value. Possible names (and names' values):

* "type": type of control, values:
** "label"
** "check" (checkbox, checked/unchecked/grayed)
** "radio" (radio checkbox, only one of these can be checked)
** "edit" (one-line edit)
** "combo" (combobox editable, value is text)
** "combo_ro" (combobox read-only, value is index)
** "listbox"
** "button"
** "checkbutton" (looks like button, but don't close dialog, checked/unchecked)
** "memo" (multi-line edit)
** "checkgroup" (group of checkboxes)
** "radiogroup" (group of radiobuttons)
** "checklistbox" (listbox with checkboxes)
** "spinedit" (edit for numbers, has min-value, max-value, increment)
** "listview" (list with columns, with column headers, value is index)
** "checklistview" (listview with checkboxes, value is check-flags)
** "linklabel" (label which activates URL on click)
** "tabs" (set of tabs headers, note: not pages which have controls)
** "colorpanel" (panel with caption, color of background, color of font)

* "pos": position, ","-separated values: left, top, right, bottom (e.g. "10,10,200,30"); some one-line controls ignore bottom-value and do autosize
* "cap": caption of control (not for all)
* "hint": tooltip/hint string, it can be multiline, "\r"-separated
* "en": enabled-state, bool
* "act": active-state, bool, for many controls (check, radio, combo_ro, checkbutton, listbox'es, listview's, tabs), means that control's change closes dialog

* "items": 
** for combo, combo_ro, listbox, checkgroup, radiogroup, checklistbox, tabs: "\t"-separated lines
** for listview, checklistview: "\t"-separated items.
*** first item is column headers: title1+"="+size1 + "\r" + title2+"="+size2 + "\r" +... 
*** size1...sizeN can be with lead char to specify alignment of column: L (default), R, C
*** other items are data: cell1+"\r"+cell2+"\r"+... (count of cells may be less than count of columns)

* "props": control-specific properties:
** for button: default_for_enter (bool value, "1"/"0")
** for edit, memo: read_only+","+font_monospaced+","+show_border (bool value)
** for spinedit: str(min_value)+","+str(max_value)+","+str(increment)
** for linklabel: URL (with http: or mailto:)
** for listview: show_grid (bool value)
** for tabs: tabs_at_bottom (bool value)
** for colorpanel: str(border_width_from_0)+","+str(int_color_fill)+","+str(int_color_font)+","+str(int_color_border)

* "val": value of control (not for all):
** for check: value "0"/"1" or "?" (grayed)
** for radio, checkbutton: value "0"/"1"
** for edit, combo, spinedit: text
** for memo: "\t"-separated lines (in lines "\t" must be replaced to chr(2))
** for combo_ro, listbox, radiogroup, listview: index
** for checkgroup: ","-separated checks (values "0"/"1")
** for checklistbox, checklistview: index+";"+checks
** for tabs: index of active tab (0-based)

Parameter focused is index of control (0-base) which is focused on showing.

====Result====
Dialog is closed by clicking any button or by changing of any control which has "act=1". Gets 2-tuple: (control_index, state_text), gets None if cancelled.

* control_index: index of control which closed dialog (0-based).
* state_text: "\n"-separated values of controls. Same count of items as in text, plus optional additional lines in the form "key=value":
** focused=N: index of last focused control (0-based) or -1.

====Notes====

* Property "act=" must be last for control.
* Controls sizes differ on Win/Linux/OSX, picture shows controls (Linux/Win) auto-aligned, not in CudaText, only example app:

[[File:controls_autosizes.png]]

* Control "tabs" height cannot auto-size, please make correct height for control (it is usually like big buttons).

===file_open===

 file_open(filename, group=-1)

Opens editor tab with given filename. If filename already opened, activates its tab. Pass empty str to open untitled tab.

Param group is index of tab-group (0-based), default means "current group". If you pass index of currently hidden group, group won't show, you need to call editor command to show it, see [[#cmd]].

Gets bool: filename is empty or sucessfully opened.

Note: "ed" is always the current editor, after file_open() current editor changes, and "ed" is the new cur editor.

===file_save===

 file_save(filename="")

Saves current tab to disk. 

Shows save-as dialog for untitled tab. 
If param filename not empty, uses it (untitled tab becomes titled).
Gets bool: file was saved.

===ed_handles===

 ed_handles()

Gets range object: it contains int handles of all editor tabs. Pass each handle to Editor() to make editor object from handle.

Example command in console, prints filenames of all tabs:

<syntaxhighlight>
for h in ed_handles(): print(Editor(h).get_filename())
</syntaxhighlight>

===ed_group===

 ed_group(index)

Gets Editor object for active editor in tab-group with given group-index. Group-index: currently 0..5. Gets None for incorrect index, or if no tabs in this group.

===ini_read/ini_write===

 ini_read(filename, section, key, value)
 ini_write(filename, section, key, value)

Reads or writes single string to ini file. Params:

* filename: Path of ini file. Can be name w/o path, this means that path of "settings" dir is used.
* section: str: Section of ini file.
* key: str: Key in section.
* value: str:
** on read: default value which is returned if no such filename/section/key was found.
** on write: value to write. 

On read: gets string value. On write: gets None.

===lexer_proc===

 lexer_proc(id, value)

Do some lexer-related action, get/set property. 

Parameter value gives ";"-separated substrings. Lexer name, if it's needed, is 1st substring. If lexer name needed and incorrect name passed, function gets None.

Possible values of id:

* LEXER_GET_EXT: Gets file-extensions field for given lexer, space-separated.
* LEXER_GET_ENABLED: Gets enabled-flag for given lexer. True means checkmark in lexer-library dialog (so lexer is visible in menu).
* LEXER_GET_COMMENT: Gets string "comment until end of line" for given lexer.
* LEXER_GET_COMMENT_STREAM: Gets "comment for range" for given lexer. If such comments are specified in "Lexer Properties" dialog, gets tuple (comment_start, comment_end), else gets None.
* LEXER_GET_COMMENT_LINED: Gets "comment for range of full lines" for given lexer. If such comments are specified in "Lexer Properties" dialog, gets tuple (comment_start, comment_end), else gets None.
* LEXER_GET_LIST: Gets string: "\n"-separated list of lexer names in library.   
* LEXER_GET_LINKS: Gets string: "\n"-separated list of sublexers names in the given lexer. 
* LEXER_GET_STYLES: Gets string: "\n"-separated list of styles names in the given lexer.
* LEXER_GET_STYLES_COMMENTS: Gets string: ","-separated list of styles of "syntax comments", for given lexer.
* LEXER_GET_STYLES_STRINGS: Gets string: ","-separated list of styles of "syntax strings", for given lexer.
* LEXER_SET_NAME: Sets for lexer with given name (substring 1) new name (substring 2).
* LEXER_SET_ENABLED: Sets for lexer with given name enabled-flag (substring 2: "0" or "1").
* LEXER_SET_EXT: Sets for lexer with given name file-extensions field (substring 2).
* LEXER_SET_LINKS: Sets for given lexer - names of its sublexers. Substring 2 must be "|"-separated list of lexer names (any number allowed, only actual number will be used).
* LEXER_DETECT: Detects lexer name by given file name. Gets None if cannot detect. Function sees file extension, or even filename before extension (e.g. "/dd/makefile.gcc" gives "Makefile").
* LEXER_DELETE: Deletes given lexer from library.
* LEXER_IMPORT: Imports lexer into library, from given filename (substring 1). Gets name of this lexer, or None if import failed.

===tree_proc===

 tree_proc(id_tree, id_action, id_item=0, index=0, text="", image_index=-1)

Perform action on treeview UI-control.

* Param id_tree is int handle of treeview. 
* Param id_item is int handle of tree-item. Can be 0 for invisible root-item:
** can clear entire tree using root-item
** can enumerate root level using root-item.

Possible values of id_action:

* TREE_ITEM_ENUM: Enumerates subitems on given item. Param id_item. Gets list of 2-tuples: (int_handle, str_caption), or None.
* TREE_ITEM_ADD: Adds subitem as item's child. Param id_item. Param index: at which subitem index to insert (0-based), or -1 to append. Param text: caption of item. Param image_index: index in tree's icon list or -1 to not show icon. Gets int handle of subitem.
* TREE_ITEM_DELETE: Deletes item (with all subitems). Param id_item.
* TREE_ITEM_SET_TEXT: Sets item's text. Params: id_item, text.
* TREE_ITEM_SET_ICON: Sets item's icon. Params: id_item, image_index.

* TREE_ITEM_SELECT: Selects item.
* TREE_ITEM_GET_SELECTED: Gets int handle of selected item (id_item ignored). Gets None if none selected.
* TREE_ITEM_GET_PROP: Gets props of item, 4-tuple: (str_caption, int_index, int_image_index, int_level). Gets None for root-item.
* TREE_ITEM_GET_PARENT: Gets int handle of parent-item for item. 0 means no parent.

* TREE_ITEM_FOLD: Folds item w/o subitems.
* TREE_ITEM_FOLD_DEEP: Folds item with subitems. Root-item allowed too.
* TREE_ITEM_UNFOLD: Unfolds item w/o subitems.
* TREE_ITEM_UNFOLD_DEEP: Unfolds item with subitems. Root-item allowed too.

* TREE_ITEM_GET_SYNTAX_RANGE: Gets position of range, associated with given tree-node, as 4-tuple (start_x, start_y, end_x, end_y). Can be called only for tree-nodes of Syntax Tree panel.

* TREE_ICON_ADD: Adds icon to icon list. Param text: filename of icon, 16x16 bmp or png file. Gets icon index or -1 if cannot add.
* TREE_ICON_DELETE: Deletes icon from icon list (note: icons after this index will shift, will have less index). Param image_index. Gets bool: index existed before.

* TREE_PROP_SHOW_ROOT: This allows to hide lines for invisible root-item. If hidden, tree (folded) looks like listbox. Param text: "0"/"1" to hide/show.

* TREE_LOCK: Disables repainting of control.
* TREE_UNLOCK: Enables repainting of control.

===listbox_proc===

 listbox_proc(id_listbox, id_action, index=0, text="", tag=0)

Perform action on listbox UI-control.

* Param id_listbox: int handle of listbox.
* Param index: index of item (0-base). 

Possible values of id_action:

* LISTBOX_GET_COUNT: Gets number if items.
* LISTBOX_ADD: Adds item (str) with associated tag (int). Param index: at which index to add, -1 to append.
* LISTBOX_DELETE: Deletes item with given index.
* LISTBOX_DELETE_ALL: Deletes all items.
* LISTBOX_GET_ITEM: Gets item with given index as 2-tuple (text, tag). Gets None if index incorrect.
* LISTBOX_SET_ITEM: Sets item with given index, to given text and tag.
* LISTBOX_GET_SEL: Gets selected index. -1 for none.
* LISTBOX_SET_SEL: Sets selected index. -1 for none.
* LISTBOX_GET_TOP: Gets index of top visible item.
* LISTBOX_SET_TOP: Sets index of top visible item.

===canvas_proc===

 canvas_proc(id_canvas, id_action,
   text="", color=-1, size=-1,
   x=-1, y=-1, x2=-1, y2=-1,
   style=-1, p1=-1, p2=-1)

Performs action on canvas (drawing surface of some GUI control).
Id_canvas is handle of canvas of some GUI control. Special value 0 means testing empty panel, it appears at the top of app, when used.

Possible values of id_action:

* CANVAS_SET_FONT: Sets props of font. Params: 
** text - font name; 
** color; 
** size; 
** style - 0 for normal, or sum of values FONT_B (bold), FONT_I (italic), FONT_U (underline), FONT_S (strikeout)

* CANVAS_SET_PEN: Sets props of pen. Params: 
** color; 
** size; 
** style - one of PEN_STYLE_nnnn; 
** p1 - end caps style - one of PEN_CAPS_nnnn; 
** p2 - line joining style - one of PEN_JOIN_nnnn

* CANVAS_SET_BRUSH: Sets props of brush. Params:
** color;
** style - one of BRUSH_nnnn. Usually used: BRUSH_SOLID (filled background), BRUSH_CLEAR (transparent background).

* CANVAS_SET_ANTIALIAS: Sets anti-aliasing mode of canvas. Params: style - ANTIALIAS_NONE, _ON, _OFF.
* CANVAS_GET_TEXT_SIZE: Gets size of text on canvas, as 2-tuple (size_x, size_y). Uses font. Params: text.
* CANVAS_TEXT: Paints text at given coords. Uses font and brush. Params: text, x, y.
* CANVAS_LINE: Paints line at given coords. Uses pen. Params: x, y, x2, y2.
* CANVAS_PIXEL: Paints one pixel at given coords. Params: x, y, color.
* CANVAS_IMAGE: Paints picture from file [png, gif, jpeg, bmp] at given coords. Params: text - file name, x, y. Gets bool: file correct.
* CANVAS_IMAGE_SIZED: Paints picture from file, sized for given rectangle. Params: text - file name, x, y, x2, y2. Gets bool: file correct.
* CANVAS_RECT: Paints rectangle. Uses pen and brush. Params: x, y, x2, y2.
* CANVAS_RECT_FRAME: Paints rectangle. Uses only pen. Params: x, y, x2, y2.
* CANVAS_RECT_FILL: Paints rectangle. Uses only brush. Params: x, y, x2, y2.
* CANVAS_RECT_ROUND: Paints rounded rectangle. Uses pen and brush. Params: x, y, x2, y2, style - radius of corners.
* CANVAS_ELLIPSE: Paints ellipse or circle. Uses pen and brush. Params: x, y, x2, y2.
* CANVAS_POLYGON: Paints polygon from any number of points (>2). Uses pen and brush. Params: text - comma separated list of (x,y) coords. Example: "10,10,200,50,10,100" - 3 points.
* CANVAS_SET_TESTPANEL: Sets height of testing panel at the top. Params: size. If it's "too small", panel hides; for big size, size is limited.

===more===

=Editor class=

Editor class has methods to work with editor. Global objects of Editor exist:

* ed: refers to currently focused editor (for any tab)
* ed_bro: refers to "brother" of ed. If tab is splitted, 2 editors are shown: 1st/2nd. 1st and 2nd are "brother" editors.

==Carets==
===get_carets===

 get_carets()

Returns list of 4-tuples, each item is info about one caret: (PosX, PosY, EndX, EndY).

* PosX is caret's column (0-base). Tab-chars give x increment 1, like others.
* PosY is caret's line (0-base).
* EndX/EndY is position of selection edge for this caret. Both -1 if no selection for caret.

===set_caret===

 set_caret(posx, posy, endx=-1, endy=-1, id=CARET_SET_ONE)

Controls carets. Possible values of id:

* CARET_SET_ONE: Removes multi-carets and sets single caret with given coords (posx, posy, endx, endy). 
* CARET_ADD: Adds caret (multi-carets feature) with given coords. Also gets count of carets after that (same as len(get_carets()) ).
* CARET_DELETE_ALL: Removes all carets. (Note: you must add caret then to enable text editing to user.)
* CARET_SET_INDEX + N (any N>=0): Changes single caret with index N to given coords.

==Text read/write==

===get_text_all/set_text_all===

 get_text_all()
 set_text_all(text)

Gets/sets entire text in the editor (str).

Note: get_text_all is simple wrapper around get_text_line/get_line_count, it uses "\n" as line sep.

===get_text_line/set_text_line===

 get_text_line(num)
 set_text_line(num, text)

Gets/sets single line (str) with given index (0-base).

Line must be w/o CR LF. Gets None if index incorrect.

To add new line, call set with num=-1.

===get_text_substr===

 get_text_substr(x1, y1, x2, y2)

Gets substring from position (x1, y1) to position (x2, y2). Second position must be bigger than first.

===delete===

 delete(x1, y1, x2, y2)

Deletes range from position (x1, y1) to bigger position (x2, y2). (Too big x1/x2 are allowed).

Note: don't pass tuple from get_carets()[0], this tuple has not sorted pos=(x1, y1), end=(x2, y2), you need to sort them (first sort by y, then by x).

Example replaces selection of 1st caret with text:

<syntaxhighlight lang="Python">
        x0, y0, x1, y1 = ed.get_carets()[0]
        if (y1>y0) or ((y1==y0) and (x1>=x0)):
            pass
        else:
            x0, y0, x1, y1 = x1, y1, x0, y0 
        
        ed.set_caret(x0, y0)
        ed.delete(x0, y0, x1, y1)
        ed.insert(x0, y0, text)
</syntaxhighlight>

===insert===

 insert(x, y, text)

Inserts given text at position (x, y). Text can be multi-line, all CR LF are converted to currently used line-ends.

Gets 2-tuple (x, y) of position after inserted text. It is on the same line, if text is single line.

==Selection==

===get_text_sel===

 get_text_sel()

Returns selected text for 1st caret (empty, if no selection).

===get_sel_mode===

 get_sel_mode()

Gets kind of selection: normal or column selection: SEL_NORMAL, SEL_COLUMN.

===get_sel_lines===

 get_sel_lines()

Gets 2-tuple, indexes of 1st and last lines affected by 1st caret selection. Both -1 if no selection.

===get_sel_rect/set_sel_rect===

 get_sel_rect()
 set_sel_rect(x1, y1, x2, y2)

Gets/sets coords of column selection.

Gets 4-tuple (x1, y1, x2, y2). All 0 if no column selection.

==Properties==

===get_line_count===

 get_line_count()

Gets number of lines.

===get_filename===

 get_filename()

Gets filename (str) of the editor's tab. 

* Empty str for untitled tab. 
* String "?" if picture file loaded in tab.

===get_split===

 get_split()

Gets tab splitting: each tab can be splitted to primary/second editors.

Gets 2-tuple: (state, percent):

* int: state of splitting, one of the values
** TAB_SPLIT_NO: tab is not splitted
** TAB_SPLIT_HORZ: tab is splitted horizontally
** TAB_SPLIT_VERT: tab is splitted vertically
* float: percent of splitting, e.g. it's 0.5 if tab splitted 50/50.

===set_split===

 set_split(state, percent)

Sets tab splitting. Meaning of params is the same as for get_split().

===get_prop===

 get_prop(id, text="")

Gets editor's property. 

Param text gives additional parameter(s) if mentioned. Possible values of id:

* PROP_GUTTER_NUM: bool: is gutter column for line numbers shown.
* PROP_GUTTER_FOLD: bool: is gutter column for folding shown.
* PROP_GUTTER_BM: bool: is gutter column for bookmarks shown.
* PROP_EOL: str: end-of-line chars. Currently always gets "\n" since it's ignored in "insert" method.
* PROP_WRAP: int: word-wrap mode. 0: no wrap; 1: wrap at window edge; 2: wrap at fixed margin.
* PROP_RO: bool: read-only mode.
* PROP_MARGIN: int: position of fixed margin.
* PROP_MARGIN_STRING: str: user-defined margins positions, e.g. "20 25".
* PROP_INSERT: bool: insert/overwrite mode.
* PROP_MODIFIED: bool: editor is modified.
* PROP_MODIFIED_VERSION: int: counter which is incremented on each text change.
* PROP_RULER: bool: horz ruler is shown.
* PROP_LINE_STATE: int: state of the line with index int(text). One of values: LINESTATE_NORMAL, LINESTATE_CHANGED, LINESTATE_ADDED, LINESTATE_SAVED.
* PROP_COLOR: int: color property. Text must be one of COLOR_ID values, see module cudatext_colors. Gets None for incorrect id.
* PROP_LINE_TOP: int: index of line visible at the top of editor.
* PROP_LINE_BOTTOM: int: index of line visible at the bottom of editor (considers word-wrap).
* PROP_COLUMN_LEFT: int: index of left visible column (horiz scroll pos).
* PROP_ENC: str: encoding name.
* PROP_LEXER_FILE: str: name of lexer for entire file (empty str if none is active).
* PROP_LEXER_POS: str: name of lexer at specified position: text must be str(column)+","+str(line), column/line 0-based.
* PROP_LEXER_CARET: str: name of lexer at the position of 1st caret.
* PROP_INDEX_GROUP: int: index of group with editor's tab, 0-based.
* PROP_INDEX_TAB: int: index of editor's tab in group, 0-based.
* PROP_UNPRINTED_SHOW: bool: unprinted chars: global enable-flag.
* PROP_UNPRINTED_SPACES: bool: unprinted chars: show spaces/tabs.
* PROP_UNPRINTED_ENDS: bool: unprinted chars: show line ends.
* PROP_UNPRINTED_END_DETAILS: bool: unprinted chars: show line end details.
* PROP_TAG: str: some string attached to editor's tab. Param text must be "key:defvalue" or simply "defvalue". Saved value for "key" is returned, or "defvalue" returned if value for key was not set. Empty key means key "_".
* PROP_CARET_SHAPE: int: shape of caret, normal mode.
* PROP_CARET_SHAPE_OVR: int: shape of caret, overwrite mode.
* PROP_CARET_SHAPE_RO: int: shape of caret, read-only mode.
* PROP_CARET_VIRTUAL: bool: caret position is allowed after line-ends.
* PROP_MACRO_REC: bool: currently macro is recording.
* PROP_MARKED_RANGE: 2-tuple: numbers of lines for "marked range" (both -1 if not set).
* PROP_VISIBLE_LINES: int: max count of lines that fit to window (doesn't consider word-wrap).
* PROP_VISIBLE_COLUMNS: int: max count of columns that fit to window.
* PROP_PICTURE: properties of picture file as 3-tuple: (picture_filename, size_x, size_y), or None if not picture loaded in tab. For picture ed.get_filename() gets "?".
* PROP_MINIMAP: bool: minimap is visible.
* PROP_MICROMAP: bool: micromap is visible.
* PROP_LINK_AT_POS: str: URL in the document, at given position, text must be str(pos_x)+","+str(pos_y).
* PROP_TAB_SPACES: bool: tab-key inserts spaces (not tab-char).
* PROP_TAB_SIZE: int: size of tab-char.
* PROP_TAB_COLLECT_MARKERS: bool: tab-key collects (jumps to and deletes) markers (if markers placed).
* PROP_TAB_TITLE: str: title of tab, useful for untitled tabs, for tabs with picture files.
* PROP_TAB_COLOR: int: color of tab containing editor; COLOR_NONE if not set.
* PROP_TAB_ID: int: unique tab's identifier (one number for main/secondary editors in tab), it is not changed when tab is moved.

===set_prop===

 set_prop(id, value)

Sets editor's property.

Param value is str. If needed bool - pass "0"/"1"; if needed int - pass str(int_value).
Possible values of id:

* PROP_GUTTER_NUM: bool: show gutter column "line numbers".
* PROP_GUTTER_FOLD: bool: show gutter column "folding". This don't enable/disable folding conmands, only showing of area.
* PROP_GUTTER_BM: bool: show gutter column "bookmarks".
* PROP_WRAP: int: word-wrap mode. 0: no wrap; 1: wrap at window edge; 2: wrap at fixed margin. 
* PROP_RO: bool: read-only mode.
* PROP_MARGIN: int: position of fixed margin.
* PROP_MARGIN_STRING: str: space-separated user-margins columns.
* PROP_INSERT: bool: insert/overwrite mode.
* PROP_MODIFIED: bool: editor is modified. 
* PROP_RULER: bool: show ruler.
* PROP_COLOR: color property, value must be "color_id,color_int_value", where color_id is constant from module cudatext_colors.
* PROP_LINE_TOP: int: index of line visible at the top of editor (allows to scroll editor).
* PROP_COLUMN_LEFT: int: index of left visible column (horiz scroll pos).
* PROP_ENC: str: encoding name. Possible values are shown in menu of encodings.
* PROP_LEXER_FILE: str: name of lexer.
* PROP_INDEX_GROUP: int: index of group with editor's tab, 0-based.
* PROP_INDEX_TAB: int: index of editor's tab in group, 0-based.
* PROP_UNPRINTED_SHOW: bool: unprinted chars: global enable-flag.
* PROP_UNPRINTED_SPACES: bool: unprinted chars: show spaces/tabs.
* PROP_UNPRINTED_ENDS: bool: unprinted chars: show line ends.
* PROP_UNPRINTED_END_DETAILS: bool: unprinted chars: show line end details.
* PROP_TAG: str: some string attached to editor's tab. Param text must be pair "key:value" or simply "value", this sets value for specified key (internally it is dictionary). Empty key means key "_".
* PROP_CARET_SHAPE: int: shape of caret, normal mode.
* PROP_CARET_SHAPE_OVR: int: shape of caret, overwrite mode.
* PROP_CARET_SHAPE_RO: int: shape of caret, read-only mode.
* PROP_CARET_VIRTUAL: bool: caret position is allowed after line-ends.
* PROP_EXPORT_HTML: this is not property, this is action to export text with hiliting to HTML. Value is ";"-separated parameters: "file_path;page_title;font_name;font_size;bool_show_numbers;int_color_background;int_color_numbers".
* PROP_MARKED_RANGE: str: numbers of lines for "marked range" as "num1,num2" (pass empty str or "-1,-1" to remove range).
* PROP_MINIMAP: bool: minimap is visible.
* PROP_MICROMAP: bool: micromap is visible.
* PROP_TAB_SPACES: bool: tab-key inserts spaces.
* PROP_TAB_SIZE: int: size of tab-char.
* PROP_TAB_COLLECT_MARKERS: bool: tab-key collects (jumps to and deletes) markers.
* PROP_TAB_COLOR: int: color of tab containing editor; set COLOR_NONE to reset.
* PROP_TAB_TITLE: str: title of tab, useful for untitled tabs.

===bookmark===

 bookmark(id, nline, nkind=1, ncolor=-1, text="")

Controls bookmarks. Possible values of id:

* BOOKMARK_GET: Gets kind of bookmark at line=nline. 0 means no bookmark, 1 means usual bookmark.
* BOOKMARK_SET: Sets bookmark with kind=nkind at line=nline. 1 means usual bookmark with usual color and icon. Other kind values mean custom bookmark, which must be setup via BOOKMARK_SETUP. Param text: hint, shown when mouse is over bookmark gutter icon.
* BOOKMARK_CLEAR: Removes bookmark from line=nline (nkind ignored).
* BOOKMARK_CLEAR_ALL: Removes all bookmarks (nline, nkind ignored).
* BOOKMARK_SETUP: Setup custom bookmarks with kind=nkind (nline ignored). Setup is:
** ncolor: Color of bookmarked line. Can be COLOR_NONE to not show bg-color.
** text: Path to icon file for gutter, 16x16 .bmp or .png file. Empty str: don't show icon.
* BOOKMARK_GET_LIST: Gets list of line indexes with bookmarks (nline, nkind ignored).
* BOOKMARK_CLEAR_HINTS: Clears all bookmark hints. Maximum about 250 separate lines can have hints, later hints will not show, so you need to clear hints before adding bunch of bookmarks to editor.

Notes:

* nkind must be 1..255.
* nkind values 240..249 have setup by default: they have blue icons "0" to "9".

===folding===

 folding(id, index=-1, item_x=-1, item_y=-1, item_y2=-1, item_staple=False, item_hint="")

Performs action on folding ranges. Values of id:

* FOLDING_GET_LIST: Gets list of folding ranges. List of 5-tuples (y, y2, x, staple, folded), or None.
** y: int: line of range start.
** y2: int: line of range end. If y==y2, then range is simple and don't have gutter-mark and staple.
** x: int: x-offset of range start (char index in start line).
** staple: bool: range has block staple.
** folded: bool: range is currently folded.
* FOLDING_FOLD: Folds range with given index (index in list from FOLDING_GET_LIST).
* FOLDING_UNFOLD: Unfolds range with given index.
* FOLDING_ADD: Adds folding range. Params needed: item_x, item_y, item_y2. Params optional: item_staple, item_hint (hint shows when range is folded). Meaning is like in FOLDING_GET_LIST. If index is 0..last, then range inserts at this index, else appends.
* FOLDING_DELETE: Deletes folding range with given index.
* FOLDING_DELETE_ALL: Deletes all folding ranges.
* FOLDING_FIND: Gets index of range, which starts at line index =item_y, or None.
* FOLDING_CHECK_RANGE_INSIDE: For 2 ranges with indexes [index, item_x], detects: 1st range is inside 2nd. Gets bool. Gets False if indexes incorrect.
* FOLDING_CHECK_RANGES_SAME: For 2 ranges with indexes [index, item_x], detects: ranges are same (x/y/y2 may differ). Gets bool. Gets False if indexes incorrect.

===get_sublexer_ranges===

 get_sublexer_ranges()

Gets list of ranges which belong to nested lexers (sublexers of current lexer for entire file, e.g. "HTML" inside "PHP", or "CSS" inside "HTML"). Gets list of 5-tuples, or None if no ranges. Each tuple is:

* str: sublexer name
* int: start column (0-based)
* int: start line (0-based)
* int: end column
* int: end line

===get_token===

 get_token(id, index1, index2)

Gets info about one token ("token" is minimal text fragment for syntax parser). 

Gets 4-tuple, or None if no such token. Tuple is:

* (start_x, start_y)
* (end_x, end_y)
* string_token_type
* string_style_name

Possible values of id:

* TOKEN_AT_POS: Token at position (x=index1, y=index2).
* TOKEN_INDEX: Token with index=index1 (in tokens collection), 0-based.

===markers===

 markers(id, x=0, y=0, tag=0, len_x=0, len_y=0)

Controls markers (used e.g. in Snippets plugin). Possible values of id:

* MARKERS_GET: Gets list of markers. Each list item is [x, y, len_x, len_y, tag]. Gets None if no markers.

* MARKERS_ADD: Adds marker. Also gets number of markers. Params are used here:
** x, y: Start of marker (like caret pos).
** Param tag>0 is needed if you want to place multi-carets when command "goto last marker (and delete)" runs. All markers with the same tag>0 will get multi-carets (after markers will be deleted). 
** Params len_x, len_y are needed if you want to place selection at marker, when "goto last marker" command goes to this marker.
*** if len_y==0: len_x is length of selection (single line),
*** if len_y>0: len_y is y-delta of selection-end, and len_x is absolute x-pos of selection-end.

* MARKERS_DELETE_ALL: Deletes all markers.
* MARKERS_DELETE_LAST: Deletes last added marker.

===attr===

 attr(id, tag=0, x=0, y=0, len=0,
      color_font=COLOR_NONE, color_bg=COLOR_NONE, color_border=COLOR_NONE,
      font_bold=0, font_italic=0, font_strikeout=0,
      border_left=0, border_right=0, border_down=0, border_up=0 )

Controls additional color attributes. Possible values of id:

* MARKERS_ADD: Adds fragment with specified properties. Also gets number of fragments. Props:
** tag: any int value attached to fragment (several plugins must add fragments with different tags, to be able to remove only fragments for them)
** x, y: position of fragment start (like caret).
** len: length of fragment.
** color_nnnn: RGB color values for font, background, borders. E.g. 0x0000FF is red, 0x00FF00 is green.
** font_nnnn: font attributes: 0 - off, 1 - on.
** border_nnnn: border types for edges, values from 0: none, solid, dash, solid 2pixel, dotted, rounded, wave.
* MARKERS_GET: Gets list of fragments, each item is list, int fields, same as function params.
* MARKERS_DELETE_ALL: Deletes all fragments.
* MARKERS_DELETE_LAST: Deletes last added fragment.
* MARKERS_DELETE_BY_TAG: Deletes all fragments for specified tag value.

Note:

* color_bg value can be COLOR_NONE: it uses usual back-color.
* color_font, color_border value can be COLOR_NONE: it uses usual text-color.

==Misc==

===save===

 save(filename="")

Saves editor's tab to disk.

Shows save-as dialog for untitled tab. 
If param filename not empty, uses it (untitled tab becomes titled).
Gets bool: file was saved.

===cmd===

 cmd(code, text="")

Command runner, it runs any command in editor by its int code.

See codes in module cudatext_cmd. Param text is needed for rare commands (e.g. by cCommand_TextInsert).

===focus===

 focus()

Activates editor's tab and focuses editor itself. It's needed when you want to activate inactive tab. You can get Editor objects of inactive tabs using ed_handles().

===lock/unlock===

 lock()
 unlock()

These lock, then unlock editor. Locked editor is not painted and shows text label "Wait...".

===convert===

 convert(id, x, y, text="")

Converts coordinates in editor. Possible values of id:

* CONVERT_CHAR_TO_COL: Convert char-coordinates (x,y) to column-coordinates 2-tuple (column,y).
* CONVERT_COL_TO_CHAR: Convert column-coordinates (x,y) to char-coordinates 2-tuple (chars,y).
* CONVERT_LINE_TABS_TO_SPACES: Convert line (parameter text) from tab-chars to spaces (line not changed if no tab-chars in it), gets str.

Gets None if coordinates incorrect (e.g. x<0).

===complete===

 complete(text, len1, len2, selected=0, alt_order=False)

Shows auto-completion listbox with given items.

Function gets None and listbox stays open. When user chooses listbox item, its data is inserted.

* Param text: string with items, must be formatted as shown in the [[ATSynEdit#Auto-completion_lists]].
* Param len1: count of chars to the left of the caret, to be replaced.
* Param len2: count of chars to the right of the caret, to be replaced.
* Param selected: index of initially selected listbox item (0-based).
* Param alt_order:
** alt_order=False: pass items in each line: prefix, id, desc. Listbox shows prefix at the left edge.
** alt_order=True: pass items in each line in such order: id, prefix, desc. Listbox shows id at the left edge. Use it if plugin needs to show long "prefixes".

Note: listbox disappears if you move caret or type text, unlike usual auto-completion listboxes (they can recalculate items for new caret pos).

===complete_alt===

 complete_alt(text, snippet_id, len_chars, selected=0)

Shows alternative completion listbox. This listbox allows to insert complex snippets, not only simple words. E.g. snippet text like "myobj.myfunc(${1:value1}, ${2:value2});".

Function gets None and listbox stays open. When user chooses listbox item, event on_snippet is called, event gets:

* snippet_id from parameter (on_snippet should handle only known value of snippet_id)
* snippet_text which is text of selected item (last column)

Params:

* Param text: "\n"-separated lines, one line per snippet. Each line has 3 columns "\t"-separated.
** Column 1 is shown on left side of listbox (good to show here name of function)
** Column 2 is shown on right side of listbox (good to show here type of function)
** Column 3 is snippet text in any format. Can contain "\t" but not "\n". Can have any chars escaped in any form.
* Param snippet_id: any short string just to identify snippet kind between all plugins. E.g. plugin1/plugin2 may have snippets in different formats, they must handle only their snippets.
* Param len_chars: listbox shows lefter than caret, by this count of chars.
* Param selected: index of initially selected listbox item (0-based).

===gap===

 gap(id, num1, num2, tag=-1)

Performs action on inter-line gaps (they don't overlap text above/below).
Possible values of id:

* GAP_GET_LIST: Gets list of gaps. List of 4-tuples (nline, ntag, bitmap_size_x, bitmap_size_y), or None.

* GAP_MAKE_BITMAP: Makes new bitmap for future gap. Size of bitmap is num1 x num2. Gets 2-tuple (id_bitmap, id_canvas). 
** id_bitmap is needed to later call GAP_ADD.
** id_canvas is needed to paint an image on bitmap, by canvas_proc().

* GAP_ADD: Adds gap to editor, with ready bitmap. Gets bool: params correct, gap added. Params: 
** num1 - line index 
** num2 - id_bitmap you got before
** tag - some int value to separate gaps from few plugins. (Internally it's signed 64-bit.)

* GAP_DELETE: Deletes gaps for lines: from num1 to num2.
* GAP_DELETE_ALL: Deletes all gaps.

Example plugin:

<syntaxhighlight lang="python">
from cudatext import *
class Command:
    def run(self):
        for i in range(ed.get_line_count()//2):
            self.do_gap(i*2)

    def do_gap(self, num):
        id_bitmap, id_canvas = ed.gap(GAP_MAKE_BITMAP, 600, 50)
        canvas_proc(id_canvas, CANVAS_SET_BRUSH, color=0xa0ffa0)
        canvas_proc(id_canvas, CANVAS_POLYGON, '200,0,300,30,200,50')
        canvas_proc(id_canvas, CANVAS_SET_BRUSH, color=0xffffff, style=BRUSH_CLEAR)
        canvas_proc(id_canvas, CANVAS_TEXT, x=230, y=10, text='gap %d'%(num+1))
        canvas_proc(id_canvas, CANVAS_SET_BRUSH, color=0xffffff, style=BRUSH_SOLID)
        ed.gap(GAP_ADD, num, id_bitmap)
</syntaxhighlight>

===lexer_scan===

 lexer_scan(nline)

Runs lexer analysis (if lexer active) from given line index. Waits until analysis finishes.

Use case: plugin appends n lines to text (line by line), then lexer needs to rescan text from 1st added line, else folding won't appear for these lines.

===more===

=Tech info=

==Format of text for cmd_MouseClick==

Text is "X,Y" where X/Y are position of caret relative to top-caret (other carets removed when command runs). If Y is 0, X is addition to caret's x. 
If Y not 0, Y is addition to caret's y, and X is absolute caret's x.

==Format of text for cmd_FinderAction==

Text is chr(1) separated items:

* item 0: find-action, one of: 
** 'findfirst'- find first
** 'findnext'- find next
** 'findprev'- find prev
** 'rep'- replace next, find
** 'repstop'- replace next, don't find
** 'repall'- replace all
** 'findcnt'- count all
** 'findsel' - find all, make selections
** 'findmark'- find all, place markers
* item 1: text to find
* item 2: text to replace with
* item 3: several chars, each char is find-option: 
** 'c' for case-sens
** 'r' for regex
** 'w' for whole-words
** 'f' for from-caret
** 'o' for confirm-replaces
** 'a' for wrapped-search

=History=

1.0.164
* change: ed.gap: tag is 64-bit signed (was 32-bit)

1.0.163
* change: app_proc toolbar api: _add allows to set caption; _enum gets also captions

1.0.162
* add: ed.gap (Gaps api)
* add: ed.folding (Folding api)
* add: ed.lexer_scan
* add: canvas_proc
* add: on_click_gap
* delete: ed.get_ranges (use ed.folding)

1.0.161
* add: dlg_custom: colorpanel has new "props" value, color_border

1.0.160
* add: can add to side/bottom panel UI-control "listbox"
* add: listbox_proc func
* add: menu api prefix "btm:"

1.0.159
* add: app_proc: PROC_GET_GUI_HEIGHT

1.0.158 
* add: events priority (e.g. "on_key++")
* add: app_proc: PROC_BOTTOMPANEL_ADD, PROC_BOTTOMPANEL_REMOVE, PROC_BOTTOMPANEL_ACTIVATE, PROC_BOTTOMPANEL_ENUM

1.0.157
* add: lexer_proc: LEXER_DETECT

1.0.156
* add: ed.complete: added param alt_order
* add: app_proc: PROC_HOTKEY_INT_TO_STR, PROC_HOTKEY_STR_TO_INT
* add: dlg_custom: "type=colorpanel"
* add: dlg_custom: result has additional line "focused=N"
* add: file_open can install addons, where files are not in root, but in subdir
* add: install.inf: can write lexers list in [info] $var=Name1,Name2,Name3 ; use it like "lexers=$var"
* add: install.inf: can write lexers list with regex, e.g. [info] $var=regex:.*SQL.*

1.0.155
* add: lexer_proc:
** LEXER_GET_COMMENT_STREAM
** LEXER_GET_COMMENT_LINED
** LEXER_GET_STYLES_COMMENTS
** LEXER_GET_STYLES_STRINGS
* add: app_proc: 
** PROC_GET_COMMAND_INITIAL
** PROC_SHOW_STATUSBAR_GET, PROC_SHOW_STATUSBAR_SET
** PROC_SHOW_TOOLBAR_GET, PROC_SHOW_TOOLBAR_SET
** PROC_SHOW_SIDEPANEL_GET, PROC_SHOW_SIDEPANEL_SET
** PROC_SHOW_BOTTOMPANEL_GET, PROC_SHOW_BOTTOMPANEL_SET
** PROC_SHOW_TABS_GET, PROC_SHOW_TABS_SET
** PROC_COORD_WINDOW_GET, PROC_COORD_WINDOW_SET
** PROC_COORD_DESKTOP
** PROC_COORD_MONITOR* 
* add: app_path: APP_FILE_RECENTS
* delete: lexer_proc: LEXER_GET_MODIFIED

1.0.154
* add: app_proc: PROC_THEME_UI_*, PROC_THEME_SYNTAX_*
* add: ed.get_prop/set_prop: PROP_CARET_VIRTUAL

1.0.153
* add: app_path: APP_DIR_INSTALLED_ADDON

1.0.152
* add: ed.get_prop/set_prop: PROP_COLUMN_LEFT

1.0.151
* add: on_state called with EDSTATE_MODIFIED (when ed modifies)

1.0.150
* add: ed.markers(MARKERS_ADD, ...) has param len_y
* change: ed.markers(MARKERS_GET, ...) gets items with value len_y

1.0.149
* add: on_open_pre

1.0.148
* add: app_proc: PROC_SIDEPANEL_REMOVE
* add: dlg_hotkeys: added param "lexer"

1.0.147
* add: ed.get_sublexer_ranges()

1.0.146
* add: dlg_custom: "type=tabs"

1.0.145
* add: dlg_custom: "check" has 3rd value "?"

1.0.144
* add: ed.complete, ed.complete_alt: added param "selected"
* add: app_proc: PROC_GET_FIND_STRINGS

1.0.143
* add: ed.convert: CONVERT_LINE_TABS_TO_SPACES
* add: app_proc: PROC_GET_KEYSTATE
* chg: app_proc(PROC_GET_COMMAND..) dont give plugin/lexer items

1.0.142
* add: on_key_up

1.0.141
* add: dlg_hotkey: title

1.0.140

* add: ed.get_prop: PROP_TAB_ID
* add: ed.get_prop/set_prop: PROP_TAG extended, it has values for keys
* add: dlg_custom: prop "act=1"
* add: app_idle()
* add: tree_proc: TREE_ITEM_GET_SYNTAX_RANGE

1.0.139

* add: on_state
* add: ed_group()
* change: msg_status default process_messages=False

1.0.138

* add: on_snippet
* add: ed.complete_alt (uses on_snippet)
* add: msg_status has param process_messages
* add: ed.set_prop: PROP_TAB_TITLE writable

1.0.137

* change: cudatext_colors.py deleted, moved to cudatext.py
* add: ed.attr: color_font, color_border can be COLOR_NONE

1.0.136

* add: dlg_hotkey
* add: dlg_custom: listview props=
* add: app_proc: PROC_GET_HOTKEY, PROC_SET_HOTKEY
* add: app_log: LOG_CONSOLE_GET_LOG

1.0.135

* add: ed.get_prop: PROP_MODIFIED_VERSION

1.0.134

* add: app_proc: menu_id can be with "_": "_recents/_themes/_langs/_plugins"
* add: app_proc: menu_id "lexers/_lexers"
* add: app_proc: menu_id "enc/_enc"

1.0.133

* lexer-lib file not used, used .lcf files
* delete: LEXER_SAVE_LIB, LEXER_EXPORT

1.0.132

* change: app_proc:
** result of PROC_MENU_ENUM has item_id
** result of PROC_TOOLBAR_ENUM has string_id for std buttons
* add: can load .png icons (was: only .bmp)
* add: app_proc: PROC_TOOLBAR_ICON_GET_SIZE, PROC_TOOLBAR_ICON_SET_SIZE

1.0.131

* add: app_proc: PROC_GET_LANG
* add: app_proc: PROC_MENU_ENUM gives also hints for menu "top"

1.0.130

* add: dlg_dir
* add: dlg_custom: type=checkbutton

1.0.129

* add: ed.set_prop: can use PROP_MODIFIED

1.0.128

* add: ed.get_prop: PROP_LINK_AT_POS

1.0.127

* add: on_tab_move
* add: on_panel: id_event="on_menu"
* add: tree_proc: TREE_LOCK, TREE_UNLOCK
* add: ed.bookmark: BOOKMARK_SET specifies hint
* add: ed.bookmark: BOOKMARK_CLEAR_HINTS

1.0.126

* change: deleted get_top/set_top/get_enc/set_enc/get_tabcolor/set_tabcolor; instead use get_prop/set_prop: PROP_LINE_TOP, PROP_ENC, PROP_TAB_COLOR  
* add: get_prop: PROP_TAB_TITLE

1.0.125

* add: app_proc: PROC_TOOLBAR_nnnnn
* add: app_proc: PROC_BOTTOMPANEL_GET_CONTROL

1.0.124

* add: get_prop/set_prop: PROP_MINIMAP, PROP_MICROMAP

1.0.123

* add: ed.get_filename() can be "?" for picture
* add: ed.get_prop PROP_PICTURE

1.0.122

* add: ed.get_prop PROP_VISIBLE_LINES, PROP_VISIBLE_COLUMNS
* add: ed.get_prop PROP_LINE_BOTTOM

1.0.121

* add: app_proc: PROC_SIDEPANEL_*
* add: tree_proc
* add: on_panel
* add: on_close
* add: on_click_dbl
* add: Editor.get_token
* add: optional param in file_save, ed.save

1.0.120

* add: dlg_custom: type=linklabel, hint=
* add: app_log: LOG_CONSOLE_CLEAR can have text "m","e","h"

1.0.119

* add: msg_status_alt
* add: on_func_hint
* add: app_proc: PROC_GET/SET_FIND_OPTIONS
* change: app_log: LOG_GET_LINES result

1.0.118

* add: on_click
* add: on_lexer
* add: ed.set_prop/get_prop PROP_COLOR
* add: ed.set_prop/get_prop PROP_MARKED_RANGE
* add: ed.set_prop/get_prop PROP_CARET_SHAPE*
* delete: dlg_checklist

1.0.117

* add: app_log: LOG_PANEL_ADD, LOG_PANEL_DELETE, LOG_PANEL_FOCUS
* add: app_log: LOG_GET_LINES, LOG_GET_LINEINDEX, LOG_SET_LINEINDEX
* add: ed.set_prop: PROP_EXPORT_HTML
* add: app_proc: PROC_SET_SPLIT, PROC_GET_SPLIT

1.0.116

* add: on_output_nav
* add: app_log: param tag for LOG_ADD
* add: app_proc: PROC_GET_COMMAND_PLUGIN

1.0.115

* add: dlg_custom: props for "edit"; align-chars for "listview"
* add: app_proc: PROC_GET_ESCAPE PROC_SET_ESCAPE

1.0.114

* change: attr() has param "tag"
* add: dlg_custom: some props, added "listview", "checklistview"

1.0.113

* add: dlg_custom
* add: dlg_menu(.., focused)
* add: set_prop PROP_INDEX_GROUP, PROP_INDEX_TAB
* add: result for ed.save(), file_save()

1.0.112

* add: Editor.attr()
* add: app_proc PROC_SET_SUBCOMMANDS
* add: app_proc PROC_EXEC_PLUGIN
* add: get_prop PROP_MACRO_REC
* add: dlg_hotkeys()

1.0.111

* add: Editor.markers()
* add: Editor.save()
* add: get/set_prop PROP_TAB_COLLECT_MARKERS
* add: get/set_prop PROP_TAG
* add: app_proc PROC_GET_LAST_PLUGIN
* add: app_proc PROC_GET_GROUPING, PROC_SET_GROUPING
* add: app_proc PROC_EXEC_PYTHON

1.0.110

* add: on_console_nav

1.0.109

* add: on_start
* add: app_proc PROC_SET_EVENTS

1.0.108

* add: Editor.convert()
* add: Editor.set_prop()
* add: app_proc: PROC_MENU_CLEAR, PROC_MENU_ADD
* add: get_prop/set_prop: PROP_UNPRINTED*.
* add: Editor.get_ranges()

1.0.107

* add: event plugins
* add: lexer_proc()
* change: set_caret()
* del: add_caret()

1.0.106

* add: dlg_file: can take filename "!"
* add: app_path: APP_FILE_SESSION
* add: app_proc: PROC_SAVE_SESSION, PROC_LOAD_SESSION, PROC_SET_SESSION
