aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/interface-gtk
AgeCommit message (Collapse)AuthorFilesLines
2024-09-12function key macros have been reworked into a more generic key macro featureRobin Haberkorn1-13/+35
* 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-11the SciTECO parser is Unicode-based now (refs #5)Robin Haberkorn1-5/+5
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-09Xq and ]q inherit the document encoding from the source document (refs #5)Robin Haberkorn1-1/+1
* ^Uq however always sets an UTF8 register as the source is supposed to be a SciTECO macro which is always UTF-8. * :^Uq preserves the register's encoding * teco_doc_set_string() now also sets the encoding * instead of trying to restore the encoding in teco_doc_undo_set_string(), we now swap out the document in a teco_doc_t and pass it to an undo token. * The get_codepage() Q-Reg method has been removed as the same can now be done with teco_doc_get_string() and the get_string() method.
2024-09-09Gtk: ignore the keyboard layout whereever possible (refs #5)Robin Haberkorn1-22/+78
* Eg. when typing with a Russian layout, CTRL+I will always insert ^I. * Works with all of the start-state command Ex, Fx, ^x commands and string building constructs. This is exactly where process_edit_cmd_cb() case folds case-insensitive characters. The corresponding state therefore sets an is_case_insensitive flag now. * Does not yet work with anything embedded into Q-Register specifications. This could only be realized with a new state callback (is_case_insensitive()?) that chains to the Q-Register and string building states recursively. * Also it doesn't work with Ё on my Russian phonetic layout, probably because the ANSI caret on that same key is considered dead and not returned by gdk_keyval_to_unicode(). Perhaps we should directly wheck the keyval values? * Whenever a non-ANSI key is pressed in an allowed state, we try to check all other keyvals that could be produced by the same hardware keycode, ie. we check all groups (keyboard layouts).
2024-09-09input and displaying of Unicode characters is now possible (refs #5)Robin Haberkorn1-8/+0
* All non-ASCII characters are inserted as Unicode. On Curses, this also requires a properly set up locale. * We still do not need any widechar Curses, as waddch() handles multibyte characters on ncurses. We will see whether there is any Curses variant that strictly requires wadd_wch(). If this will be an exception, we might keep both widechar and non-widechar support. * By convention gsize is used exclusively for byte sizes. Character offsets or lengths use int or long.
2024-02-03GTK: allow disabling client-side decorations by setting $GTK_CSD=0Robin Haberkorn1-7/+2
* This is the same variable used by gtk3-nocsd, but we will now work even without preloading any libraries. Also, it turns out that gtk3-nocsd does not ship as a FreeBSD port and hasn't been updated in a long time. * Setting this in .teco_ini wouldn't have been easy since the teco_interface_init() is called before any TECO code. Also, you might not even want disable this globally but depending on the window manager. * Therefore, you are advised to `export GTK_CSD=0` in ~/.xsession. * The --no-csd command line option is kept for the time being, but probably serves no more purpose.
2024-02-03Gtk: set icons a bit later after calling gtk_widget_show()Robin Haberkorn1-39/+44
* Also turns out, I will have to use gtk_window_set_icon_list(). * This fixes icons in tabbed and st (when embedding SciTECO).
2024-01-21updated copyright to 2024Robin Haberkorn5-5/+5
2023-06-19the SciTECO data installation path is now configurable via --with-scitecodatadirRobin Haberkorn1-1/+1
* This is also the base of $SCITECOPATH. * Changing it is useful for packaging where it is not possible to factor out the common files between Curses and Gtk builds into a "sciteco-common" package. As an alternative, you can now create disjunct sciteco-curses and sciteco-gtk packages. * You will most likely want to use this for Gtk builds as in: --with-interface=gtk --program-prefix=g --with-scitecodatadir=/usr/local/share/gsciteco.
2023-06-18fixed caret scrolling on startupRobin Haberkorn1-61/+64
* Since Scintilla no longer automatically scrolls the caret (see 941f48da6dde691a7800290cc729aaaacd051392), the caret wouldn't always end up in the view on startup. * Added teco_interface_refresh() which includes SCI_SCROLLCARET and is invoked on startup. This helps with the Curses backend. It also reduces code redundancies. * On Gtk, the caret cannot be easily scrolled on startup as long as no size is allocated to the window, so we also added a size-allocate callback to the window's event box. Sizes are less often allocated to the event box than to the window itself for some strange reason.
2023-05-14resolved warning in gtk-label.c due to wrong enum typeRobin Haberkorn1-1/+1
* This probably did not cause any bugs.
2023-05-09fixed CTRL+C interruptions on Windows; optimized CTRL+C polling on Gtk+Robin Haberkorn1-22/+25
* teco_interrupt() turned out to be unsuitable to kill child processes (eg. when <EB> hangs). Instead, we have Win32-specific code now. * Since SIGINT can be ignored on UNIX, pressing CTRL+C was not guaranteed to kill the child process (eg. when <EB> hangs). At the same time, it makes sense to send SIGINT first, so programs can terminate gracefully. The behaviour has therefore been adapted: Interrupting with CTRL+C the first time will kill gracefully. The second time, a more agressive signal is sent to kill the child process. Unfortunately, this would be relatively tricky and complicated to do on Windows, so CTRL+C will always "hard-kill" the child process. * Moreover, teco_interrupt() killed the entire process on Windows when called the second time. This resulted in any interruption to terminate SciTECO unexpectedly when tried the second time on Gtk/Win32. * teco_sigint_occurred renamed to teco_interrupted: There may be several different sources for setting this flag. * Checking for CTRL+C on Gtk involves driving the main event loop repeatedly. This is a very expensive operation. We now do that only every 100ms. This is still sufficient since keyboard input comes from humans. This optimization saves 75% runtime on Windows and 90% on Linux. * The same optimization turned out to be contraproductive on PDCurses/WinGUI.
2023-04-27Gtk: fixed scrolling in the command line widgetRobin Haberkorn1-7/+2
* The caret wasn't always kept out of the UZ and at some point would totally leave the view. This was apparently cause by executing two SCI_SCROLLCARETs per teco_interface_cmdline_update(). * Instead, we now use a CARET_EVEN scroll policy which also works sufficiently well.
2023-04-27Gtk: fixed entering dead keysRobin Haberkorn1-25/+63
* This is using an Input Method now. * Entering dead keys has probably always been broken in Gtk which I only did not notice because I use a keyboard layout without dead keys. This affects the ^ and ` keys on a German layout. * Once we support Unicode input, it would make sense to abuse Scintilla's already existing input method support. Unfortunately, forwarding keyboard events to the Scintilla view breaks event freezing and results in flickering.
2023-04-19fixup: reverted the last Scintilla patch and unref Scintilla objects via ↵Robin Haberkorn1-9/+1
g_object_unref() * Turns out that using gtk_widget_destroy(), the finalize handler never gets called!? This means we were leaking memory. * Using g_object_unref() fixes that and the initial Scintilla patch is no longer necessary. * There have previously been use-after-free bugs when *not* using gtk_widget_destroy(). This has apparently been fixed in the meantime in Scintilla.
2023-04-18no longer try to avoid automatic scrolling - this is patched out of ↵Robin Haberkorn1-5/+2
Scintilla now * The patch avoids all automatic scrolling consistently, including in SCI_UNDO. This speads up Undo (especially after interruptions). * Also, the patch disables a very costly and pointless (in SciTECO) algorithm that effectively made <Ix$> uninterruptible. * Effectively reverts large parts of 8ef010da59743fcc4927c790f585ba414ec7b129. I have never liked using unintuitive Scintilla messages to avoid scrolling.
2023-04-05updated copyright to 2023Robin Haberkorn5-5/+5
2022-11-28fixed a number of crashes due to empty string arguments or uninitialized ↵Robin Haberkorn1-0/+1
registers * An empty but valid teco_string_t can contain NULL pointers. More precisely, a state's done_cb() can be invoked with such empty strings in case of empty string arguments. Also a registers get_string() can return the NULL pointer for existing registers with uninitialized string parts. * In all of these cases, the language should treat "uninitialized" strings exactly like empty strings. * Not doing so, resulted in a number of vulnerabilities. * EN$$ crashed if "_" was uninitialized * The ^E@q and ^ENq string building constructs would crash for existing but uninitialized registers q. * ?$ would crash * ESSETILEXER$$ would crash * This is now fixed. Test cases have been added. * I cannot guarantee that I have found all such cases. Generally, it might be wise to change our definitions and make sure that every teco_string_t must have an associated heap object to be valid. All functions returning pointer+length pairs should consequently also never return NULL pointers.
2022-06-21updated copyright to 2022 and updated TODORobin Haberkorn5-5/+5
2022-06-21Gtk+: fixed interpretation of Alt-Gr-keypressesRobin Haberkorn1-1/+6
* this is a regression in Gtk+ 3 * nowadays, Alt-Gr-keycombos are sometimes reported as Ctrl+Alt which resulted in control characters to be inserted
2022-06-21Gtk+: Stop memory limiting when idlingRobin Haberkorn1-0/+8
* the same is done in the Curses UI * important for platforms that require busy polling of memory usage (Win32)
2021-12-22Curses: added teco_interface_is_interrupted() fallback and standardized how ↵Robin Haberkorn1-0/+10
to detect interactive/batch mode * Adds support for CTRL+C interruptions on Curses variants like PDCurses/GUI and XCurses. This also affects the current Win32 nightly builds which should now support CTRL+C interruptions. * The fallback is of course less efficient than the existing platform optimizations (existing for UNIX and Win32 console builds) and slows down parsing in interactive mode. * Use teco_interface.cmdline_window consistently to detect interactive mode. This may theoretically speed up SciTECO code execution slightly on shutdown.
2021-10-15Gtk: disabled ^Z suspension on Unix for the time beingRobin Haberkorn1-9/+0
* This has always been broken as Gtk will not hide the window before suspending. * It has been deemed to complicated to implement at the moment. Even if we can catch SIGTSTP (not that trivial), it seems to be impossible - at least without some lower level Xlib interaction - to hide the program window before raising SIGTSTP. * Even if everything worked, it is unclear whether it is actually desirable to suspend a GUI application - ^Z may be pressed accidentally and it will be inconvenient to resume the job. So we would additionally have to check for the existence of an attached console.
2021-10-15Gtk: solve the key-repeat problem once and for all (or improved on it at least)Robin Haberkorn1-1/+2
* Keeping a key pressed could still result in missing graphics updates and thus visual feedback. * Now try to process all Gdk events after thawing the window. It no longer appears to happen. * On the downside, key processing is much slower now which may result in keys being queued up and processed some time even after releasing it. There may be workarounds for that as well...
2021-10-15Gtk: prevent hard to predict teco_interface_key_pressed_cb() recursionsRobin Haberkorn1-1/+5
* Due to introducing another gtk_main_iteration_do(), there could indeed be unforseen recursions of teco_interface_key_pressed_cb() that resulted in additional teco_interface_handle_key_press() calls. * This did not cause crashes, but we better prevent recursions altogether. While emptying the key event queue, we only allow other events to be queued by all possibly recursive invocations of teco_interface_key_pressed_cb().
2021-10-13GTK: Support for Xembed protocol via --xembedRobin Haberkorn1-1/+18
* This was surprisingly easy to implement as Gtk+ 3 already supports it via GtkPlug. * Allows embedding SciTECO into other Xembed-aware applications. * Unfortunately there are very few generic Xembed hosts. tabbed (https://tools.suckless.org/tabbed/) would be one of them. It could be used to add tabs to SciTECO even on non-tiling window managers: $ tabbed sciteco --xembed * Unfortunately, it does not seem to be possible to use this feature to let SciTECO replace the contents of a terminal window even though many terminal emulators provide $WINDOWID.
2021-10-13GTK: revised the key processing again to prevent crashesRobin Haberkorn1-41/+35
* Processing a queued list of key events with an idle timer turned out to be tricky. Since teco_interface_pop_key_idle_cb() would eventually drive the main loop with gtk_main_iteration_do() which may result in a recursive invocation of teco_interface_pop_key_idle_cb() which will eventually crash. * We'd have to mask the idle watcher during the execution time of teco_interface_pop_key_idle_cb(). * Therefore it has been decided to use a tight loop again to process the event queue. After thawing the window, we now manually drive the event loop with gtk_main_iteration_do() to make sure that the UI is updated. This could result in a recursive invocation of teco_interface_key_pressed_cb() of course but the callback is already secured against this.
2021-10-13improved default selection colors and made them configurable via color.tesRobin Haberkorn1-1/+2
* NOTE: Selections are currently only used to highlight search results. * The default selection colors were not always visible well with default settings (--no-profile) and they were not uniform across platforms. On Curses, the selection would be reversed, while on Gtk it had a lighter foreground color. They are now always reversed (black on white background). The default styles do not assume any color support - they use only black and white. * Since these defaults cannot possibly work on every color scheme, color.selfore and color.selback has been added to color.tes. All existing color schemes have been updated to configure selections as reversed to the default colors. This especially fixes selection colors on Gtk. * On solarized.tes, the caret style was already distinct from inversed default colors. On terminal.tes, the color of the caret is now bright white, so it stands out from the selection colors. * In Curses, the caret color is currently __not__ applied to the command line where it is continued to be drawn reversed. The command line drawing code is considered deprecated and will eventually be replaced with a Scintilla minibuffer. * In Gtk, we now apply the caret style to the commandline view as well. * Fixed the comment color in solarized.light.
2021-10-13GTK: fixed teco_view_free() (hopefully)Robin Haberkorn1-20/+7
* The old implementation could apparently result in use-after-free situations that are not related to unstopped watchers in Scintilla. This would result in frequent crashes. Possibly, this only now manifests after upgrading to Scintilla 5. * The old implementation also had the bug that freeing views (e.g. via <EF>) would not release any memory in batch mode since the main loop is not triggered. * I don't pretend to understand why we need gtk_widget_destroy() instead of g_object_unref().
2021-10-13GTK: prevent crashes when pressing keys very quicklyRobin Haberkorn1-1/+2
* teco_interface_key_pressed_cb() could be called multiple times __before__ the idle timer (teco_interface_pop_key_idle_cb()) fires. The recursion check would consequently not work and we started the idle timer multiple times. This would eventually crash. * We now process the first queued key immediately. The alternative would be to store the idle watcher id. * The idle watcher's priority has been increased. Since redrawing is guaranteed to take place at G_PRIORITY_HIGH_IDLE, it is sufficient to process keys at G_PRIORITY_DEFAULT_IDLE. * Should also reduce latency slightly. * fixes up 71bf522231d2998f1fb183f343c2b1f9dbcd3b15
2021-10-11Gtk+ 3 UI: Don't use deprecated functions and make sure that the UI is ↵Robin Haberkorn1-37/+38
updated regularily when holding down a key * gdk_window_freeze_toplevel_updates_libgtk_only() is apparently no longer necessary with Scintilla 5. * When holding down a key constantly, it was not uncommon that the display would not be updated until it is released. This is now worked around by using a low priority idle timer for emptying the teco_interface.event_queue. This ensures that Gtk can call other watchers after every keypress.
2021-10-11optimized caret scrolling: this is a costly operation and is now done only ↵Robin Haberkorn1-0/+10
once per keypress * Esp. costly since Scintilla 5. * We now avoid any Scintilla message that automatically scrolls the caret (makes the caret visible) and instead call SCI_SCROLLCARET only once after every keypress in the interface implementation. * From nowon, use * SCI_SETEMPTYSELECTION instead of SCI_GOTOPOS * SCI_SETEMPTYSELECTION(SCI_POSITIONFROMLINE(...)) instead of SCI_GOTOLINE * SCI_SETSELECTIONSTART and SCI_SETSELECTIONEND instead of SCI_SETSEL * With these optimizations we are significantly faster than before the Scintilla upgrade (6e67f5a682ff46d69888fec61b94bf45cec46721). It is now even safe to execute the Gtk test suite during CI.
2021-10-11upgraded to Scintilla 5.1.3 and Scinterm 3.1Robin Haberkorn1-2/+2
* Previous Scintilla version was 3.6.4 and Scinterm was 1.7 (with lots of custom patches). All of the patches are now either irrelevant or have been merged upstream. * Since Scintilla 5 requires C++17, this increases the minimum GCC version at least to 5.0. We may actually require even newer versions. * I could not upgrade the scintilla-mirror (which was imported from Mercurial), so the old sciteco-dev branch was renamed to sciteco-dev-pre-v2.0.0, master was deleted and I reimported the entire Scintilla repo using git-remote-hg. This means that scintilla-mirror now contains two entirely separate trees. But it is still possible to clone old SciTECO repos. * The strategy/workflow of maintaining hotfix branches on scintilla-mirror has been changed. Instead of having one sciteco-dev branch that is rebased onto new Scintilla upstream releases and tagging SciTECO releases in scintilla-mirror (to keep the commits referenced), we now create a branch for every Scintilla version we are based on (eg. sciteco-rel-5-1-3). This branch is never rebased or deleted. Therefore, we are guaranteed to be able to clone arbitrary SciTECO repo commits - not only releases. Releases no longer have to be tagged in scintilla-mirror. On the downside, fixup commits may accumulate in these new branches. They can only be squashed once a new branch for a new Scintilla release is created (e.g. by cherry-picking followed by rebase). * Scinterm does no longer have to reside in the Scintilla subdirectory, so we added it as a regular submodule. There are no more recursive submodules. The Scinterm build system has not been improved at all, but we use a trick based on VPATH to build Scinterm in scintilla/bin/. * Scinterm is now in Git and we reference the upstream repo for the time being. We might mirror it and apply the same branching workflow as with Scintilla if necessary. The scinterm-mirror repository still exists but has not been touched. We will also have to rewrite its master branch as it was a non-reproducible Mercurial import. * Scinterm now also comes with patches for Scintilla which we simply applied on our sciteco-rel-5-1-3 branch. * Scintilla 5 outsourced its lexers into the Lexilla project. We added it as yet another submodule. * All submodules have been moved into contrib/. * The Scintilla API for setting lexers has consequently changed. We now have to call SCI_SETILEXER(0, CreateLexer(name)). As I did not want to introduce a separate command for setting lexers, <ES> has been extended to allow setting lexers by name with the SCI_SETILEXER message which effectively replaces SCI_SETLEXERLANGUAGE. * The lexer macros (SCLEX_...) no longer serve any purpose - they weren't used in the SciTECO standard library anyway - and have consequently been removed from symbols-scilexer.c. The style macros from SciLexer.h (SCE_...) are theoretically still useful - even though they are not used by our current color schemes - and have therefore been retained. They can be specified as wParam in <ES>. * <ES> no longer allows symbolic constants for lParam. This never made any sense since all supported symbols were always wParam. * Scinterm supports new native cursor modes. They are not used for the time being and the previous CARETSTYLE_BLOCK_AFTER caret style is configured by default. It makes no sense to enable native cursor modes now since the command line should have a native cursor but is not yet a Scintilla view. * The Scintilla upgrade performed much worse than before, so some optimizations will be necessary.
2021-10-08Gtk: fixed message bar's background colorRobin Haberkorn1-7/+7
* Was only broken on Gtk+ 3.24 for Windows with the builtin theme engine. * The warning level was also not themed correctly because of a typo.
2021-10-08revised icon loading on Windows and packaging againRobin Haberkorn1-19/+28
* We don't need the PNG icons on Windows as the compiled-in ICO should suffice * Ship the dependencies of the SVG pixbuf loader. * The PNG pixbuf loader is still distributed, as we at least need it for loading the icon theme. * Install a loaders.cache - without it, the pixbuf loaders won't be found. This file can be generated by gdk-pixbuf-query-loaders but apparently has to be modified by hand. * Regenerate the icon cache using gtk-update-icon-cache. * Icon themes are found now. Unfortunately, we have to distribute the entire Adwaita icon theme as distributing only the scalable (SVG) icons does not work for some strange reason (FIXME).
2021-06-08Gtk UI: fixed lookup of icons and fallback.css on WindowsRobin Haberkorn1-33/+39
* Since we don't have an absolute and known installation directory, we should look for these files in the same directory as sciteco.exe. * For the time being, we look for them in $SCITECOCONFIG which defaults to that directory. * Cannot be a final solution as you may tweak $SCITECOCONFIG to fit an Unix-like environment (eg. set SCITECOCONFIG=$HOME). In such configurations it may also not be suitable to always look in the directory of sciteco.exe since that may be some /bin dir. Considering that GTK+ forces us to preserve some kind of UNIX-like directory hierarchy even for portable builds, we should perhaps install the icons into the hicolor icon theme. This would also simplify Debian packaging.
2021-06-08get rid of the GObject Builder (GOB2): converted teco-gtk-info-popup.gob and ↵Robin Haberkorn8-715/+812
teco-gtk-label.gob to plain C * Using modern GObject idioms and macros greatly reduces the necessary boilerplate code. * The plain C versions of our GObject classes are now "final" (cannot be derived) This means we can hide the instance structures from the headers and avoid using explicit private fields. * Avoids some deprecation warnings when building the Gtk UI. * GOB2 is apparently no longer maintained, so this seems like a good idea in the long run. * The most important reason however is that there is no precompiled GOB2 for Windows which prevents compilation on native Windows hosts, eg. during nightly builds. This is even more important as Gtk+3 is distributed on Windows practically exclusively via MSYS. (ArchLinux contains MinGW gtk3 packages as well, so cross-compiling from ArchLinux would have been an alternative.)
2021-05-30THE GREAT CEEIFICATION EVENTRobin Haberkorn10-6697/+1759
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-04-30removed CLANG and HAVE_SIZED_DEALLOCATION conditionalsRobin Haberkorn1-8/+2
Automakefiles could be simplified by updating CXXFLAGS in configure.ac instead.
2017-03-08yet another revision of memory limiting: the glibc mallinfo() approach has ↵Robin Haberkorn1-0/+3
been shown to be unacceptably broken, so the fallback implementation has been improved * mallinfo() is not only broken on 64-bit systems but slows things down linearilly to the memory size of the process. E.g. after 500000<%A>, SciTECO will act sluggish! Shutting down afterwards can take minutes... mallinfo() was thus finally discarded as a memory measurement technique. * Evaluating /proc/self/statm? has also been evaluated and discarded because doing this frequently is even slower. * Instead, the fallback implementation has been drastically improved: * If possible use C++14 global sized deallocators, allowing memory measurements across the entire C++ code base with minimal runtime overhead. Since we only depend on C++11, a lengthy Autoconf check had to be introduced. * Use malloc_usable_size() with global non-sized deallocators to measure the approx. memory usage of the entire process (at least the ones done via C++). The cheaper C++11 sized deallocators implemented via SciTECO::Object still have precedence, so this affects Scintilla code only. * With both improvements the test case sciteco -e '<@EU[X^E\a]"^E\a"%a>' is handled sufficiently well now on glibc and performance is much better now. * The jemalloc-specific technique has been removed since it no longer brings any benefits compared to the improved fallback technique. Even the case of using malloc_usable_size() in strict C++ mode is up to 3 times faster. * The new fallback implementation might actually be good enough for Windows as well if some MSVCRT-specific support is added, like using _msize() instead of malloc_usable_size(). This must be tested and benchmarked, so we keep the Windows-specific implementation for the time being.
2017-03-03updated copyright to 2017Robin Haberkorn4-4/+4
2016-11-22Gtk interface: make sure that the default display is openedRobin Haberkorn1-2/+10
* this has been broken since cb5e08b40d
2016-11-18improved command line option handlingRobin Haberkorn2-5/+9
* it turns out that option-like arguments could not be reliably passed to SciTECO scripts for two reasons: a) "--" arguments are not removed from argv by GOption if it detects and following option-like argument. "--" would thus be passed as a script argument which will disable option parsing in scripts that interpret "--". b) A script run via the Hash-Bang line "#!...sciteco -m" would require an explicit "--" to turn of GOption parsing. However it is __impossible__ to insert after the script file name on UNIX. * Therefore, SciTECO now removes leading "--" arguments left over by GOption. * If possible (Glib >= 2.44), option parsing is performed in strict POSIX mode which inhibits parsing after the first non-option argument. This reduces the number of cases where an explicit "--" is required. * --mung no longer takes an argument. Instead, the first non-option argument is expected to be the script file name. This looks weird at first but is more consistent with how other interpeters work. Once we revise argument passing to scripts, the script name can also be passed to the script which is more consistent with it being the first non-option argument. Also, with strict POSIX parsing, this fixed Hash-Bang lines since the script file name constructed by the kernel will automatically switch off option parsing, passing all option-like script arguments uninterpreted to the script. * Since we're supporting Glib < 2.44, the Hash-Bang lines are still broken for certain builds. Therefore, a wrapper script is installed to libexecdir (it never has to be executed by users and Hash-Bang lines need absolute paths anyway) which transparently inserts "--" into the SciTECO command line and should be used as the interpreter in portable SciTECO scripts. The wrapper script is generated and points to the exact SciTECO binary installed. This is important when doing parallel installs of Curses and Gtk binaries since each one will get its own working wrapper script. The wrapper-script workaround can be removed once we depend on Glib >= 2.44 (some day...). * The default /usr/bin/env Hash-Bang lines are no longer used in the scripts since they are broken anyway (UNIX incl. Linux cannot pass multiple arguments to the interpreter!). Scripts that get installed will get a fixed-up Hash-Bang line referring to the installed SciTECO binary anyway. * Interface::main() has been renamed to Interface::init() and is optional now. The Interface::main() method was introduced because of the misconception that interfaces will find their options in the argv array and have to do their own parsing. This is wrong, since their option group already cares about parsing. Therefore, gtk_init() does not have to called explicitly, too.
2016-08-19Integrated clipboard supportRobin Haberkorn2-1/+79
* mapped to different registers beginning with "~" * on supported platforms accessing the clipboard is as easy as X~ or G~. Naturally this also allows clipboards to be pasted in string arguments/insertions (^EQ~). * Currently, Gtk+, PDCurses and ncurses/XTerm are supported. For XTerm clipboard support, users must set 0,256ED to enable it since we cannot check for XTerm window ops programmatically (at least without libX11). * When clipboard regs exist, the clipboard can also be deemed functional. This allows macros to fall back to xclip(1) if necessary. * EOL handling has been moved into a new file eol.c and eol.h. EOL translation no longer depends on GIOChannels but can be memory-backed as well.
2016-02-10avoid unnecessary undo token allocations in batch mode: greatly speeds up ↵Robin Haberkorn1-2/+2
batch mode * by using variadic templates, UndoStack::push() is now responsible for allocating undo tokens. This is avoided in batch mode. * The old UndoStack::push(UndoToken *) method has been made private to avoid confusion around UndoStack's API. The old UndoStack::push() no longer needs to handle !undo.enabled, but at least asserts on it. * C++11 support is now required, so variadic templates can be used. This could have also been done using manual undo.enabled checks; or using multiple versions of the template with different numbers of template arguments. The latter could be done if we one day have to support a non-C++11 compiler. However since we're depending on GCC 4.4, variadic template use should be OK. Clang supports it since v2.9. * Sometimes, undo token pushing passed ownership of some memory to the undo token. The old behaviour was relied on to reclaim the memory even in batch mode -- the undo token was always deleted. To avoid leaks or repeated manual undo.enabled checking, another method UndoStack::push_own() had to be introduced that makes sure that an undo token is always created. In batch mode (!undo.enabled), this will however create the object on the stack which is much cheaper than using `new`. * Having to know which kind of undo token is to be pushed (taking ownership or not) is inconvenient. It may be better to add static methods to the UndoToken classes that can take care of reclaiming memory. * Benchmarking certain SciTECO scripts have shown 50% (!!!) speed increases at the highest possible optimization level (-O3 -mtune=native -march=native).
2016-02-07Gtk UI: use GtkCanonicalizedLabels and many styling improvementsRobin Haberkorn4-34/+127
* the canonicalized labels are used in title bars and popups * title labels and popup labels are selectable. The latter only makes sense as long as there is no mouse support for selecting popup entries. * message bar labels are selectable * title bars can be styled according to the current document type (.info-qregister and .info-buffer classes) * .dirty has been introduced for dirty buffers. This way, dirty buffer file names can be printed in italics without hardcoding that behaviour. It can be customized in the user CSS. * The style of highlighted popup entries is now themeable as well using the .highlight style class.
2016-02-07added GtkCanonicalizedLabel: a label for displaying SciTECO stringsRobin Haberkorn2-3/+233
* those strings can contain control characters * the canonicalized label will automatically escape the non-printable characters according to the same mapping used elsewhere and shows them in "reverse" video. * reverse video is hard to achieve in Gtk, esp. for Pango versions that don't support transparent foregrounds * the current implementation does not need dedicated styling for reverse video characters; but this may be an option in order to get it right even on older Gtk versions
2016-02-04Gtk UI: refactored fallback.css - use one section per UI componentRobin Haberkorn1-13/+12
2016-02-04Gtk UI: --no-csd in the main option group now, so it shows up in --helpRobin Haberkorn1-1/+2
2016-02-04Gtk UI: fixed segfaults because of unsynchronized ViewGtk destructionRobin Haberkorn2-12/+26
* this was worked around by using an idle watcher which can be registered thread-safe. * this workaround can be reverted once we're single-threaded again.