aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/cmdline.h
AgeCommit message (Collapse)AuthorFilesLines
2025-01-13updated copyright to 2025Robin Haberkorn1-1/+1
2024-09-12function key macros have been reworked into a more generic key macro featureRobin Haberkorn1-7/+20
* ALL keypresses (the UTF-8 sequences resulting from key presses) can now be remapped. * This is especially useful with Unicode support, as you might want to alias international characters to their corresponding latin form in the start state, so you don't have to change keyboard layouts so often. This is done automatically in Gtk, where we have hardware key press information, but has to be done with key macros in Curses. There is a new key mask 4 (bit 3) for that purpose now. * Also, you might want to define non-ANSI letters to perform special functions in the start state where it won't be accepted by the parser anyway. Suppose you have a macro M→, you could define @^U[^K→]{m→} 1^_U[^K→] This effectively "extends" the parser and allow you to call macro "→" by a single key press. See also #5. * The register prefix has been changed from ^F (for function) to ^K (for key). This is the only thing you have to change in order to migrate existing function key macros. * Key macros are enabled by default. There is no longer any way to disable function key handling in curses, as I never found any reason or need to disable it. Theoretically, the default ESCDELAY could turn out to be too small and function keys don't get through. I doubt that's possible unless on extremely slow serial lines. Even then, you'd have to increase ESCDELAY and instead of disabling function keys simply define an escape surrogate. * The ED flag has been removed and its place is reserved for a future mouse support flag (which does make sense to disable in curses sometimes). fnkeys.tes is consequently also enabled by default in sample.teco_ini. * Key macros are handled as an unit. If one character results in an error, the entire string is rubbed out. This fixes the "CLOSE" key on Gtk. It also makes sure that the original error message is preserved and not overwritten by some subsequent syntax error. It was never useful that we kept inserting characters after the first error.
2024-09-12teco_string_get_coord() returns character offsets now (refs #5)Robin Haberkorn1-1/+1
* This is used for error messages (TECO macro stackframes), so it's important to display columns in characters. * Program counters are in bytes and therefore everywhere gsize. This is by glib convention.
2024-09-11the SciTECO parser is Unicode-based now (refs #5)Robin Haberkorn1-10/+2
The following rules apply: * All SciTECO macros __must__ be in valid UTF-8, regardless of the the register's configured encoding. This is checked against before execution, so we can use glib's non-validating UTF-8 API afterwards. * Things will inevitably get slower as we have to validate all macros first and convert to gunichar for each and every character passed into the parser. As an optimization, it may make sense to have our own inlineable version of g_utf8_get_char() (TODO). Also, Unicode glyphs in syntactically significant positions may be case-folded - just like ASCII chars were. This is is of course slower than case folding ASCII. The impact of this should be measured and perhaps we should restrict case folding to a-z via teco_ascii_toupper(). * The language itself does not use any non-ANSI characters, so you don't have to use UTF-8 characters. * Wherever the parser expects a single character, it will now accept an arbitrary Unicode/UTF-8 glyph as well. In other words, you can call macros like M§ instead of having to write M[§]. You can also get the codepoint of any Unicode character with ^^x. Pressing an Unicode character in the start state or in Ex and Fx will now give a sane error message. * When pressing a key which produces a multi-byte UTF-8 sequence, the character gets translated back and forth multiple times: 1. It's converted to an UTF-8 string, either buffered or by IME methods (Gtk). On Curses we could directly get a wide char using wget_wch(), but it's not currently used, so we don't depend on widechar curses. 2. Parsed into gunichar for passing into the edit command callbacks. This also validates the codepoint - everything later on can assume valid codepoints and valid UTF-8 strings. 3. Once the edit command handling decides to insert the key into the command line, it is serialized back into an UTF-8 string as the command line macro has to be in UTF-8 (like all other macros). 4. The parser reads back gunichars without validation for passing into the parser callbacks. * Flickering in the Curses UI and Pango warnings in Gtk, due to incompletely inserted and displayed UTF-8 sequences, are now fixed.
2024-09-09implemented Unicode support for rubin/rubout and a number of commands (WIP) ↵Robin Haberkorn1-12/+2
(refs #5) certain test cases are still way too slow: 10000<@I/X^J/> 20000<R> or 10000<@I/X^J/> 20000<%a-1J> SCI_ALLOCATELINECHARACTERINDEX does not help much here. It probably speeds up only SCI_LINEFROMINDEXPOSITION and SCI_INDEXPOSITIONFROMLINE.
2024-01-21updated copyright to 2024Robin Haberkorn1-1/+1
2023-04-13cmdline.c: simplified the rubin-caseRobin Haberkorn1-1/+2
* We no longer need special NULL-values for teco_cmdline_insert(), as teco_cmdline_rubin() will simply take a character from the rubbed-out command line and is equivalent to typing a character from the rubbed-out command-line.
2023-04-05updated copyright to 2023Robin Haberkorn1-1/+1
2022-06-21updated copyright to 2022 and updated TODORobin Haberkorn1-1/+1
2021-05-30THE GREAT CEEIFICATION EVENTRobin Haberkorn1-82/+63
This is a total conversion of SciTECO to plain C (GNU C11). The chance was taken to improve a lot of internal datastructures, fix fundamental bugs and lay the foundations of future features. The GTK user interface is now in an useable state! All changes have been squashed together. The language itself has almost not changed at all, except for: * Detection of string terminators (usually Escape) now takes the string building characters into account. A string is only terminated outside of string building characters. In other words, you can now for instance write I^EQ[Hello$world]$ This removes one of the last bits of shellisms which is out of place in SciTECO where no tokenization/lexing is performed. Consequently, the current termination character can also be escaped using ^Q/^R. This is used by auto completions to make sure that strings are inserted verbatim and without unwanted sideeffects. * All strings can now safely contain null-characters (see also: 8-bit cleanliness). The null-character itself (^@) is not (yet) a valid SciTECO command, though. An incomplete list of changes: * We got rid of the BSD headers for RB trees and lists/queues. The problem with them was that they used a form of metaprogramming only to gain a bit of type safety. It also resulted in less readble code. This was a C++ desease. The new code avoids metaprogramming only to gain type safety. The BSD tree.h has been replaced by rb3ptr by Jens Stimpfle (https://github.com/jstimpfle/rb3ptr). This implementation is also more memory efficient than BSD's. The BSD list.h and queue.h has been replaced with a custom src/list.h. * Fixed crashes, performance issues and compatibility issues with the Gtk 3 User Interface. It is now more or less ready for general use. The GDK lock is no longer used to avoid using deprecated functions. On the downside, the new implementation (driving the Gtk event loop stepwise) is even slower than the old one. A few glitches remain (see TODO), but it is hoped that they will be resolved by the Scintilla update which will be performed soon. * A lot of program units have been split up, so they are shorter and easier to maintain: core-commands.c, qreg-commands.c, goto-commands.c, file-utils.h. * Parser states are simply structs of callbacks now. They still use a kind of polymorphy using a preprocessor trick. TECO_DEFINE_STATE() takes an initializer list that will be merged with the default list of field initializers. To "subclass" states, you can simply define new macros that add initializers to existing macros. * Parsers no longer have a "transitions" table but the input_cb() may use switch-case statements. There are also teco_machine_main_transition_t now which can be used to implement simple transitions. Additionally, you can specify functions to execute during transitions. This largely avoids long switch-case-statements. * Parsers are embeddable/reusable now, at least in parse-only mode. This does not currently bring any advantages but may later be used to write a Scintilla lexer for TECO syntax highlighting. Once parsers are fully embeddable, it will also be possible to run TECO macros in a kind of coroutine which would allow them to process string arguments in real time. * undo.[ch] still uses metaprogramming extensively but via the C preprocessor of course. On the downside, most undo token generators must be initiated explicitly (theoretically we could have used embedded functions / trampolines to instantiate automatically but this has turned out to be dangereous). There is a TECO_DEFINE_UNDO_CALL() to generate closures for arbitrary functions now (ie. to call an arbitrary function at undo-time). This simplified a lot of code and is much shorter than manually pushing undo tokens in many cases. * Instead of the ridiculous C++ Curiously Recurring Template Pattern to achieve static polymorphy for user interface implementations, we now simply declare all functions to implement in interface.h and link in the implementations. This is possible since we no longer hace to define interface subclasses (all state is static variables in the interface's *.c files). * Headers are now significantly shorter than in C++ since we can often hide more of our "class" implementations. * Memory counting is based on dlmalloc for most platforms now. Unfortunately, there is no malloc implementation that provides an efficient constant-time memory counter that is guaranteed to decrease when freeing memory. But since we use a defined malloc implementation now, malloc_usable_size() can be used safely for tracking memory use. malloc() replacement is very tricky on Windows, so we use a poll thread on Windows. This can also be enabled on other supported platforms using --disable-malloc-replacement. All in all, I'm still not pleased with the state of memory limiting. It is a mess. * Error handling uses GError now. This has the advantage that the GError codes can be reused once we support error catching in the SciTECO language. * Added a few more test suite cases. * Haiku is no longer supported as builds are instable and I did not manage to debug them - quite possibly Haiku bugs were responsible. * Glib v2.44 or later are now required. The GTK UI requires Gtk+ v3.12 or later now. The GtkFlowBox fallback and sciteco-wrapper workaround are no longer required. * We now extensively use the GCC/Clang-specific g_auto feature (automatic deallocations when leaving the current code block). * Updated copyright to 2021. SciTECO has been in continuous development, even though there have been no commits since 2018. * Since these changes are so significant, the target release has been set to v2.0. It is planned that beginning with v3.0, the language will be kept stable.
2017-03-07refactored commandline key processing: rewritten Cmdline::process_edit_cmd() ↵Robin Haberkorn1-11/+7
as State::process_edit_cmd() virtual methods * Cmdline::process_edit_cmd() was much too long and deeply nested. It used RTTI excessively to implement the state-specific behaviour. It became apparent that the behaviour is largely state-specific and could be modelled much more elegantly as virtual methods of State. * Basically, a state can now implement a method to customize its commandline behaviour. In the case that the state does not define custom behaviour for the key pressed, it can "chain" to the parent class' process_edit_cmd(). This can be optimized to tail calls by the compiler. * The State::process_edit_cmd() implementations are still isolated in cmdline.cpp. This is not strictly necessary but allows us keep the already large compilations units like parser.cpp small. Also, the edit command processing has little to do with the rest of a state's functionality and is only used in interactive mode. * As a result, we have many small functions now which are much easier to maintain. This makes adding new and more complex context sensitive editing behaviour easier. * State-specific function key masking has been refactored by introducing State::get_fnmacro_mask(). * This allowed us to remove the States::is_*() functions which have always been a crutch to support context-sensitive key handling. * RTTI is almost completely eradicated, except for exception handling and StdError(). Both remaining cases can probably be avoided in the future, allowing us to compile smaller binaries.
2017-03-03updated copyright to 2017Robin Haberkorn1-1/+1
2016-11-20fixed glib warnings about using g_mem_set_vtable() and revised memory limitingRobin Haberkorn1-1/+2
* we were basing the glib allocators on throwing std::bad_alloc just like the C++ operators. However, this always was unsafe since we were throwing exceptions across plain-C frames (Glib). Also, the memory vtable has been deprecated in Glib, resulting in ugly warnings. * Instead, we now let the C++ new/delete operators work like Glib by basing them on g_malloc/g_slice. This means they will assert and the application will terminate abnormally in case of OOM. OOMs cannot be handled properly anyway, so it is more important to have a good memory limiting mechanism. * Memory limiting has been completely revised. Instead of approximating undo stack sizes using virtual methods (which is unprecise and comes with a performance penalty), we now use a common base class SciTECO::Object to count the memory required by all objects allocated within SciTECO. This is less precise than using global replacement new/deletes which would allow us to control allocations in all C++ code including Scintilla, but they are only supported as of C++14 (GCC 5) and adding compile-time checks would be cumbersome. In any case, we're missing Glib allocations (esp. strings). * As a platform-specific extension, on Linux/glibc we use mallinfo() to count the exact memory usage of the process. On Windows, we use GetProcessMemoryInfo() -- the latter implementation is currently UNTESTED. * We use g_malloc() for new/delete operators when there is malloc_trim() since g_slice does not free heap chunks properly (probably does its own mmap()ing), rendering malloc_trim() ineffective. We've also benchmarked g_slice on Linux/glib (malloc_trim() shouldn't be available elsewhere) and found that it brings no significant performance benefit. On all other platforms, we use g_slice since it is assumed that it at least does not hurt. The new g_slice based allocators should be tested on MSVCRT since I assume that they bring a significant performance benefit on Windows. * Memory limiting does now work in batch mode as well and is still enabled by default. * The old UndoTokenWithSize CRTP hack could be removed. UndoStack operations should be a bit faster now. But on the other hand, there will be an overhead due to repeated memory limit checking on every processed character.
2016-01-28updated copyright to 2016Robin Haberkorn1-1/+1
2015-06-29<:Q> returns -1 for non-existent registers nowRobin Haberkorn1-1/+1
* added a new OPTIONAL behaviour for QRegSpecMachines * allows you to implement commands that have an optional Q-Register argument that should not be initialized if undefined. * Using QRegSpecMachine::fail() you may still check for existence of the register conditionally to emulate the QREG_REQUIRED behaviour. * Using :Q for checking for register existence makes sense, because usually you will want to check for both existence and non-emptyness as in :Qq">. So in this common case, you no longer have to keep in mind that the register may also be undefined. * This finally allows us to create arrays in the Q-Register tables without keeping a separate entry for the number of elements. E.g. an array.0 to array.N can be iterated like this: 0Ui <:Q[array.^E\i]:; ! work with element i ! %i>
2015-06-29MicroStateMachine::input() returns whether a result was set nowRobin Haberkorn1-1/+1
* this means that QRegSpecMachine::input() no longer has to return a dummy QRegister in parse-only mode. This saves an unnecessary QRegister table lookup and speeds up parsing. * QRegSpecMachine can now be easily extended to behave differently when returning a Q-Register, e.g. simply returning NULL if a register does not exist, or returning a register by prefix. This is important for some planned commands. * StateExpectQReg::got_register() now gets a QRegister *. It can theoretically be NULL - still we don't have to check for NULL in most cases since NULL is only passed in parse-only mode.
2015-05-29Modified ^W in string (and file name) arguments: ensure that we always rub ↵Robin Haberkorn1-0/+8
out beyond empty arguments * it was annoying not to be able to rub out anything with ^W if the current string argument was empty. * Now, the special file name and string argument handling for ^W is effective only if the current argument is non-empty, else we fall back to the rub-out-command behaviour. * So now, if you press ^W in a string argument, it is rubbed out until empty and on the next ^W press, the entire command will be rubbed out.
2015-03-16implemented automatic EOL translation supportRobin Haberkorn1-2/+0
* activated via bit 4 of the ED flag (enabled by default) * automatic EOL guessing on file loading and translation to LFs. * works with files that have inconsistent EOL sequences. * automatic translation to original EOL sequences on file saving * works with inconsistent EOL sequences in the buffer. This should usually not happen if the file was read in with automatic EOL translation enabled. * also works with the EC and EG commands * performance is OK, depending on the file being translated. When reading files with UNIX EOLs, the overhead is minimal typically-sized files. For DOS EOLs the overhead is larger but still acceptable. * Return (line feed) is now an immediate editing command. This centralizes EOL sequence insertion. Later, other features like auto-indent could be added to the editing command. * get_eol() has been moved to main.cpp (now called get_eol_seq() * Warn if file ownership could not be preserved when saving files. * IOView has been almost completely rewritten based on GIOChannels. The EOL translation code is also in IOView.
2015-03-07fixed 0EB command to display all buffers in the ringRobin Haberkorn1-1/+1
* the popup resetting was done after character insertion, so typing 0EB would clear the popup immediately * the new implementation is functionally equivalent to the old pre-reinsertion-commandline-handling, by resetting the popup based on the immediate editing command before insertion
2015-03-02introduced the ^G immediate editing command for toggling the undo/redo mode ↵Robin Haberkorn1-3/+5
(also replaces ^T) * CTRL+G toggles the behaviour of the rubout (Backspace, ^W, ^U) commands: When the so called immediate editing command modifier is enabled/active, the rubout commands will do the opposite and insert from the rubbed out command line. This command is somewhat similar to Emacs' C-g command. * The CTRL+G command also replaces the ^T immediate editing command for auto-completing filenames in any string argument. Now the TAB key can be used for that purpose after activating the ^G modifier. ^T is a classic TECO command that will be supported sooner or later by SciTECO, so it's good to have it available directly.
2015-03-01keep rubbed out command line for later re-insertion and massive Cmdline ↵Robin Haberkorn1-12/+60
cleanup/refactoring * characters rubbed out are not totally removed from the command line, but only from the *effective* command line. * The rubbed out command line is displayed after the command line cursor. On Curses it is grey and underlined. * When characters are inserted that are on the rubbed out part of the command line, the cursor simply moves forward. NOTE: There's currently no immediate editing command for reinserting the next character/word from the rubbed out command line. * Characters resulting in errors are no longer simply discarded but rubbed out, so they will stay in the rubbed out part of the command line, reminding you which character caused the error. * Improved Cmdline formatting on Curses UI: * Asterisk is printed bold * Control characters are printed in REVERSE style, similar to what Scinterm does. The controll character formatting has thus been moved from macro_echo() in cmdline.cpp to the UI implementations. * Updated the GTK+ UI (UNTESTED): I did only, the most important API adaptions. The command line still does not use any colors. * Refactored entire command line handling: * The command line is now a class (Cmdline), and most functions in cmdline.cpp have been converted to methods. * Esp. process_edit_cmd() (now Cmdline::process_edit_cmd()) has been simplified. There is no longer the possibility of a buffer overflow because of static insertion buffer sizes * Cleaned up usage of the cmdline_pos variable (now Cmdline::pc) which is really a program counter that used a different origin as macro_pc which was really confusing. * The new Cmdline class is theoretically 8-bit clean. However all of this will change again when we introduce Scintilla views for the command line. * Added 8-bit clean (null-byte aware) versions of QRegisterData::set_string() and QRegisterData::append_string()
2015-02-11updated copyright to 2015Robin Haberkorn1-1/+1
2014-11-11added all of SciTECO's declarations to the "SciTECO" namespaceRobin Haberkorn1-0/+4
normally, since SciTECO is not a library, this is not strictly necessary since every library should use proper name prefixes or namespaces for all global declarations to avoid name clashes. However * you cannot always rely on that * Scintilla does violate the practice of using prefixes or namespaces. The public APIs are OK, but it does define global functions/methods, e.g. for "Document" that clashed with SciTECO's "TECODocument" class at link-time. Scintilla can put its definitions in a namespace, but this feature cannot be easily enabled without patching Scintilla. * a "SciTECO" namespace will be necessary if "SciTECO" is ever to be turned into a library. Even if this library will have only a C-linkage API, it must ensure it doesn't clutter the global namespace. So the old "TECODocument" class was renamed back to "Document" (SciTECO::Document).
2014-02-15updated Copyright to year 2014Robin Haberkorn1-1/+1
2014-02-15removed most exception specifications: allow bad_allocs to propagateRobin Haberkorn1-1/+1
* specifications resulted in runtime errors (unexpected exception) when bad_alloc ocurred * specs should be used scarcely: only when the errors that may be thrown are all known and for documentary purposes
2013-02-22resolved enter-key handling by introducing get_eol()Robin Haberkorn1-0/+2
2013-02-16function key support (keys without printable representation) using keyboard ↵Robin Haberkorn1-0/+8
macros * if enabled, when a function key is pressed it is looked up in Q-Registers ^F... e.g. HOME key corresponds to register ^FHOME * the string if available is inserted as if it was entered by key-presses (later it may be entered as a single input token which may be removed in a single rubout) * only NCurses currently, key names directly correspond to Curses key names * on Curses if function keys are enabled ESCAPE will be inserted after a delay (because function keys are transmitted via escape sequences). A function key macro may be used to define an alternative escape character
2013-02-14option for q-reg spec state machine to allocate (insert) new q-registersRobin Haberkorn1-0/+3
* enabled for all modifying Q-Reg commands
2013-02-03first draft of commandline-editing commands ({ and } as in VideoTECO)Robin Haberkorn1-0/+1
* simplified traditional commandline editing. no need to extend cmdline string one character at a time when inserting multiple. instead there's a marker (cmdline_pos) specifying the macro length to execute in a "step" and also the anchor for generating undo tokens * implementation does not yet work in macro calls * while editing the commandline, other buffers/registers may not be edited (need push-down-list and auxiliary q-register)
2013-01-23cleaned up QRegister state interface (can pass register by reference)Robin Haberkorn1-1/+1
2013-01-23moved StateExpectQReg from parser.h to qregisters.hRobin Haberkorn1-0/+1
* parser.cpp|h should be reserved for generic and misc. stuff. the StateExpectQReg class is used almost exclusively by qregisters.cpp|h * resolves a circular header dependency issue
2013-01-23implemented special save last commandline command ("*" at beginning of ↵Robin Haberkorn1-0/+44
commandline macro) * only works as part of commandline macro, * at the beginning of other macros, it is treated like an arithmetic asterisk * variables defined in cmdline.cpp are now declared by new cmdline.h