aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
AgeCommit message (Collapse)AuthorFilesLines
25 hourshide #recovery# files from auto-completions, unless you already typed '#'HEADmaster-fmsbw-cimasterRobin Haberkorn3-14/+26
* These files are created regularily and shouldn't be mangled with unless you're recovering from a crash. So it makes sense to hide them by default, just like the hidden .teco-* savepoint files. * Recovery file name creation and checks are now centralized in file-utils.h.
26 hours`A` without arguments is now equivalent to `0A`Robin Haberkorn1-3/+12
* It was equivalent to `1A` which is almost never what you want. I doubt that any existing macros would be broken by this. But neither do I replace all `0A` in the existing code base (yet). * `A` without arguments is a completely different "append" command in TECO-11, but it doesn't make sense in SciTECO and I don't see what else `A` could be repurposed for. It cannot be made an insertion command since it depends on the stack state which we don't track in parse-only mode. * Added test case.
27 hoursconditionals can be terminated with F" now in addition to a single-quote (')Robin Haberkorn3-31/+46
This is useful when writing small macros directly on the command-line as in `sciteco --eval`. If you use double quoted shell strings, too many characters have to be escaped. If you use single-quotes, though, embedding the conditional end (') is annoying -- it would have to be written as '\''.
27 hoursimplemented E*q to store the last command lineRobin Haberkorn2-3/+9
`*q` can only be used at the very beginning of the command line. We cannot support it everywhere as Video TECO did since we do not follow the operators in parse-only mode. `E*q` is a replacement, so you can store the previous command line at any later point. This also adds a test case.
39 hoursminor documentation update (sciteco(1) and sciteco(7)) and comment changesRobin Haberkorn2-15/+11
3 daysget rid of teco_qreg_vtable_t::undo_set_integer()Robin Haberkorn6-48/+18
It was never required as a separate callback/method, but was kept merely for consistency. Since we now call teco_current_doc_set_dot() in teco_qreg_dot_set_integer(), we'd have to split it up into an "undo" method as well. I decided to get rid of the superfluous Q-Reg method instead. It's quite likely we could get rid of the remaining undo_set_string(), undo_exchange_string() and undo_edit() callbacks as well (TODO).
3 daysrevised and improved the Unicode glyph-to-byte conversion heuristicsRobin Haberkorn20-145/+427
Previously almost all glyph-to-byte offset conversions consulted Scintilla's line index and counted characters on the resulting line. For instance a simple expression like `.+1J` would scan the same line twice completely, which would be very slow on pathologically long lines. Even insertions did that due to having to update the ^Y ranges. If you repeat such an operation over all characters as in `<.+1:J;>` you would have complexity O(n^2) for n = line length. Only commands with an explicit relative nature like `C` and `A` would use teco_view_glyph2bytes_relative() which scans beginning at dot as long as the relative movement is less than 1024 glyphs. Wit the new heuristics almost all glyph-to-byte and byte-to-glyph conversions can make use of that optimization. This requires that dot must at all times be known in glyphs as well - the byte position is managed by Scintilla (SCI_GETCURRENTPOS). We therefore introduced teco_current_doc_set_dot() and teco_current_doc_get_dot() to update dot in the current buffer or Q-Register -- it cannot be stored along with the view since Q-Registers share a single view. A number of auxiliary functions have been introduced for converting relative to a known (glyphs,bytes) offset pair and for converting absolute and relative positions with regard to the current doc and SCI_GETCURRENTPOS position. Of course this is error-prone since the glyph and dot positions are interdependant - they must always be kept in sync. With these new optimizations even pathologically long lines can (usually) be managed even in UTF-8 documents. It does not address slow-downs in Scintilla's line layout, yet. grosciteco.tes for instance runs twice as fast now.
2026-07-05terex is built with assertions now on --enable-debugRobin Haberkorn1-0/+2
* terex disables assertions by default unless you add `-DREG_DEBUG`. Since we heavily modified the original by Henry Spencer it makes sense to enable assertions. * dlmalloc will still be built without assertions even if --enable-debug is given since that has a significant speed impact and I consider dlmalloc to be rock solid. It would need `-DDEBUG=1` to enable assertions (among other things). We only disable additional checks in dlmalloc if --disable-debug.
2026-07-04FreeBSD: fixed crashes with `EC` or `EQq`Robin Haberkorn1-0/+20
* GSpawn ends up calling posix_spawnp() which passes down a small 4kb stack to the child process until it exec()s. This stack could be overflowed easily on code paths where the path is not already absolute and when many shared libraries are involved. * The crashes could therefore only be observed on Gtk builds and in UNIX shell emulation mode (0,128ED). Sample test case: gsciteco -e '0,128ED @EC"ls"' Theoretically a relative $SHELL variable could have also triggered it. * I assume that the bug will be fixed in libc at least by the time of FreeBSD 16. * As a workaround we resolve relative program paths before passing them to g_spawn_async_with_pipes().
2026-06-29regular expression matching can now be reliably interrupted using CTRL+CRobin Haberkorn1-16/+7
* The previous checks for interruptions only helped in a few corner cases like for very high search-repeat counts or during backwards searches across the entire buffer. * But even with terex' more predictable runtime properties a single regex execution can hang quite a long time. E.g. `S^EM^X$` on a huge buffer or even more so with backreferences as in `S^~(.*)\1$`. * We now use the new tere_set_is_interrupted_cb() to register teco_interface_is_interrupted(). Types should be compatible as long as gboolean resolves to int. * It's no longer necessary to manually check for teco_interface_is_interrupted() since tere_exec() now returns REG_EINTR in case the callback returned TRUE in which case it's handled by teco_error_regex_set().
2026-06-29fixed searching for `)`Robin Haberkorn1-1/+1
It for some strange reason had to be escaped for AREs even though a single freestanding `)` cannot mean anything.
2026-06-29implemented the ^~ pattern match construct: the rest of the pattern will be ↵Robin Haberkorn1-7/+22
an Advanced Regular Expression * Allows searching by regular expressions. We will never support all ARE constructs in TECO patterns, so this is useful to have available. * Can only be typed upcaret. This leaves ^E~q available as an escape-regexp string building construct. * Once we replace the pattern2regexp converter with a custom terex lexer, we might want to restrict ^~ to the beginning of the pattern. Currently, however it can be anywhere, so you can mix TECO patterns with regular expressions.
2026-06-28fixed block-wise backwards searchesRobin Haberkorn1-2/+2
The calculation of the block start was faulty and could cause underflows resulting in unpredictable behavior.
2026-06-28fixup: fixed searching for `|` - it must also be escaped when converted to a ↵Robin Haberkorn1-1/+1
regular expression
2026-06-28fixed ^EGq (character class) pattern construct for embedded null bytes and `-`Robin Haberkorn1-3/+50
This was using g_regex_escape_string() which always translates a null byte to `\0`, which is ambiguous if followed by other digits, so a null byte followed by a digit would result in a wrong regular expression. Actually the same could happen outside of character classes, ie. `@S/^@1/` was also broken. Also it does not escape `-`, so the result cannot be used in character classes. This is fixed now in a new custom implementation teco_regex_escape(). Once moving to a custom terex lexer, we won't need any of this of course unless we want to provide a regex escaping string building construct. We are now completely free of GRegex.
2026-06-28teco_globber_t is ported from GRegex to terexRobin Haberkorn3-43/+53
It's now a private struct, so we can include the regex_t wihout having to draw in the terex headers everywhere.
2026-06-28terex is the new regular expression engine now and replaces PCRE (GRegex)Robin Haberkorn4-129/+134
* terex is based on Henry Spencer's regular expression engine for Tcl. It is a hybrid NFA/DFA design which has better worst-time runtimes than the backtracking PCRE. Memory usage is also limited and can no longer increase catastrophically. * It should no longer be possible to crash SciTECO with pathological searches. * Since it reliably supports partial matches (REG_EXPECT) we can now enable the new backwards-search algorithm by default. This used to be broken because of a glib bug, which I already fixed. It would however take a long time until this ends up on the majority of glib installations. * Regexp executions can still be quite slow if you are looking for a pattern at the end of a huge file, which can hang the editor, but this can now at least theoretically be solved by adding hooks into terex to poll for interruptions. * We can now also get rid of a TECO-pattern to regexp translation step by directly generating terex tokens (TODO). * Performance-wise terex appears to be slower than PCRE for simple forward searches even when linking everything with optimzations (FIXME). * Having a stand-alone regular expression engine is also a huge step in getting rid of glib. See also: https://git.fmsbw.de/terex/about/
2026-06-07fixup aa7b0bb1445feeefafdcf47fd639b10500b45c03: some minor optimizationsRobin Haberkorn1-21/+21
A partial match __should__ always be at the end of the subject string (i.e. block), so we don't have to check for it. Also, partial matches will be rare, so we can discriminate against the branch that handles them.
2026-05-31implemented but disabled block-wise backwards search algorithmRobin Haberkorn3-72/+264
* The block-wise search algorithm allows for efficient backwards searches on large files. * On the downside the results are not entirely symmetric to forward searches. It therefore makes sense to still support the old correct but possibly slow algorithm. Since the old algorithm is just a special case of the new one (with a single block stretching the entire search range), you can configure the block size using `8EJ`. * Unfortunately, the new block-wise algorithm won't work due to a bug in GRegex (only in the glib wrapper code). It is therefore disabled for the time being by default and will probably only be enabled once we switch to a new regexp engine. See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/5199
2026-05-10allow CTRL+C interrupting forward and background searchesRobin Haberkorn1-0/+12
* You can provoke hangs in forward searches when opening large files: `100000S^X$` This cannot be sped up, but must be interruptible. * With backwards searches it is even easier to provoke. Go to the end of a large file and perform any backwards search, even `-S$`. Since we must always search from the beginning of the document, you will always produce all matches over the entire document. There might be ways to speed up backwards searches, but they must be interruptible anyway. * Perhaps we can extend back the search range in chunks of 1-4kb until we produce at least `-count` matches.
2026-05-10fixup: prevent warnings due to missing parameter namesRobin Haberkorn1-1/+1
This would be a C23 extension.
2026-05-10support "default colors"Robin Haberkorn5-71/+141
* The terminal's default foreground and background colors are now used by default (`sciteco --no-profile`), so SciTECO integrates naturally into all terminal color schemes, even dark-on-bright ones. * The default Scintilla colors use only 0x000000 (COLOR_BLACK) and 0xC0C0C0 (COLOR_WHITE) now. * You can use `7EJ` to configure the default colors in color schemes or your profile. All existing color schemes had to disable default colors (`-1,-1,7EJ`) since they wouldn't look well otherwise. * You may add `-1,7EJ` to ~/.teco_ini when using a terminal emulator with a washed-out palettized COLOR_BLACK. We cannot detect the terminal's default colors automatically. * Scinterm updated to v6.0. We require a not-yet-upstreamed patch: https://github.com/orbitalquark/scinterm/pull/40 * In fact, we might decide not to support default colors at all in Scinterm, so this feature should be considered experimental.
2026-04-26Curses: support arbitrary RGB colorsRobin Haberkorn4-249/+135
* Instead of supporting only 16 predefined RGB placeholder values in Scintilla messages and styles, you can now use arbitrary RGB values and colors are allocated via the terminal on the fly. You no longer need to call 3EJ to change the default color palette. * The placeholder RGB values are still available. Since you will usually want exact RGB values when using anything outside of the range of 16 default colors and the RGB placeholders will not always exactly correspond to their RGB value, you can now call `0,3EJ` to ignore the default palette and allocate all colors dynamically. * Allows for more than 16 colors on the screen simultaneously. Also simplifies the solarized.tes color scheme. Since both Scinterm and SciTECO try not to touch the 16 default colors, you also no longer have to deal with restoring the palette after program termination (which was never reliable anyway). * Color schemes with non-default colors (solarized.tes) may now be broken on TERM=linux-16color (Linux VT) since Scinterm will get only 8 colors, but solarized.tes needs 16.
2026-04-20do not execute `^A` in parse-only modeRobin Haberkorn1-0/+3
This was especially dangerous since the introduction of a message level parameter, which could still be popped from the expression stack in parse-only mode or during lexing. This effectively broke n^A interactively in GTK.
2026-04-19teco_view_load_from_channel() now temporarily releases the line character ↵Robin Haberkorn1-4/+4
index on the correct view * Had been broken since introduction in v2.3.0. * This slowed down EQq<filename>$ on large files.
2026-04-19UNIX: do not automatically restart syscalls on SIGINTRobin Haberkorn1-0/+14
* signal() sets SA_RESTART by default. * Some syscalls can theoretically block indefinitely. Even opening a special file could result in an indefinitely blocking operation, that should be interruptible. You must still poll teco_interrupted in these read() loops of course. * Also makes sure that clipboard operations are interruptible even if $SCITECO_CLIPBOARD_GET blocks. Although I couldn't provoke problems in practice, I did observe hangs with xclip on Wayland on Linux, that could only be resolved by manually killing xclip.
2026-04-17Curses: fixed rendering bright/light colors on 8-color terminalsRobin Haberkorn2-2/+8
* Scinterm was simply rendering them as black, thus effectively breaking the Linux and FreeBSD vts with terminal.tes. * I was considering to render light black as white on 8-color terminals, so it's always readable. However, if you add in A_BOLD there is a good chance that the color will end up grey - at least it does in the virtual terminals (consoles). * There is no need to use bright colors in the Scintilla view defaults. E.g. 0xFFFFF is "light white". However on 8-color terminals this will be rendered like white anyway. The new defaults are closer to what terminal.tes does.
2026-04-14`^A` now accepts an optional integer to specify the message severityRobin Haberkorn2-8/+31
* I.e. you can now log warnings and errors from SciTECO code as well. * We do not need a version of ^A accepting code points, since this is supported by ^T already.
2026-04-12GTK: SIGTERM/SIGHUP always terminates the program and dumps recovery filesRobin Haberkorn7-33/+56
* SIGTERM used to insert the ^KCLOSE key macro. However with the default ^KCLOSE macro, which inserts `EX`, this may fail to terminate the editor if buffers are modified. If the process is consequently killed by a non-ignorable signal, we may still loose data. * SIGTERM is used to gracefully shut down, so we now always terminate. Since we have recovery files, they are now dumped before terminating. This makes sure that recovery files are more up-to-date during unexpected but gracefull terminations. * The same functionality is planned on Curses, but requires more fundamental changes (TODO).
2026-04-05Gtk: fixed interaction between `^T` and main input handlingRobin Haberkorn1-6/+38
Between calls to `^T`, the original key-press-event handler might enqueue events, that we must first process and report with `^T`. Otherwise it would be easy to provoke apparent double-reporting of keys after input loops like `<^T:;>`.
2026-04-04Curses: handle window resizes when blocking in `^T` and don't return ↵Robin Haberkorn2-23/+53
function keys * There was a logic error in teco_interface_getch() that caused Curses function key codes to be returned directly. These codes however are useless to macro authors and can be confused with codepoints. You cannot report function keys in the same "namespace" along with Unicode codepoints. They are now filtered out. * Also make sure that Backspace and Return are reported as 8 and 10 respectively in all Curses variants. All control codes reported by Curses are passed down unmodified - in contrast to the command-line input handling. I.e. 13 is not normalized to 10. * PDCursesMod/WinGUI may return bogus key presses, that also have to be filtered out as we already did in the main input handling. A function teco_interface_check_key() has been introduced. * NOTE: teco_interface_blocking_getch() already makes sure that recovery files are dumped even when blocking in `^T`.
2026-03-09decreased default recovery interval to 120sRobin Haberkorn2-2/+2
5 minutes was probably a bit too conservative.
2026-02-22`-$$` and `-^C` always return -1 now instead of passing down the prefix signRobin Haberkorn1-8/+27
2026-02-06DEBUG_PAUSE in main.c now works on any system with a standard libcRobin Haberkorn1-3/+2
It's also sometimes useful on UNIX, e.g. when there is no gdbserver.
2026-02-03fixed scrolling at the end of a multi-line command-lineRobin Haberkorn1-0/+8
* You couldn't see the first character on a new line after wrapping at the end of a multiline command line. * This is only worked around. The real reason must be in Scintilla, perhaps in a faulty calculation in Editor::MaxScrollPos().
2026-02-02fixup color pair support: updated Scinterm againRobin Haberkorn1-2/+6
This is for some minor cleanup.
2026-02-01fixed auto completion of two-character Q-register namesRobin Haberkorn1-5/+1
* this was noticable only after the first character, i.e. after `#x`. * Q-register tables are case sensitive, so we must not call teco_rb3str_auto_complete() with case_sensitive == FALSE. And it's also entirely unnecesary since the Q-register name for two-character Q-registers is already case-folded.
2026-01-30fixup: high-color-pair support was still broken in ScintermRobin Haberkorn4-21/+18
* Also updated A_XXX attributes to WA_XXX, where the "new" wattr_set() APIs are used. This doesn't make a difference on ncurses and PDCurses, but the X/Open standard demands it. * Allow color pairs up to 32767 instead of only up to 32766. * We now always require Curses wide-character APIs due to Scinterm, which has to use mvwin_wch(). We were practically depending on wide-character support anyway, so this shouldn't really restrict portability. * teco_curses_add_wc() has been simplified, now that we can rely on wide-char APIs. Perhaps it should be removed altogether?
2026-01-26Curses: support up to 32767 color pairsRobin Haberkorn3-68/+62
* Instead of ORing COLOR_PAIR() into attributes, always pass separate `pair` arguments. Since they are `short` this allows for up to 32767 color pairs. Previously, we could only count on 256 color pairs (or 128 for SciTECO and Scinterm each). * Analoguous changes have been made to Scinterm. See also https://github.com/orbitalquark/scinterm/pull/37 Since it only correctly checks for overflows at the end of the color pair space, we allocate the second half of that space to Scinterm. It is now very unlikely to overflow the color pair space, though. * This wasn't critical of course since even the 128 pairs would be unlikely to exhaust as long as we support only 16 ANSI colors. Scinterm however supports arbitrary RGB colors and we might want to do so soon as well.
2026-01-24`ER` updates ^S/^Y now as any other text insertionRobin Haberkorn1-1/+6
2026-01-24GTK: fixed --detach and support stdout/stderr redirectionsRobin Haberkorn4-8/+29
* We fork after command line arguments have been parsed, which is after gtk_get_option_group() has been called. This means that GTK was already initialized and it wasn't safe to continue after forking. * As a workaround, we now re-exec with the original argv array, so GTK can be properly reinitialized. Since we did not remove `--detach` from argv (and that would be nontrivial), it would fork again endlessly, so we use an environment variable $__SCITECO_DETACHED to guard against recursive forks. * Also, do not close stdin/stdout/stderr if has been redirected to a file, so you can now e.g. call `gsciteco -d >some-file`. * This was broken since v2.5.0.
2026-01-21Curses: fixed colors on emulators with less than 256 color pairsRobin Haberkorn1-9/+17
* For instance on TERM=rxvt. Generally 8-color emulators will usually support only 65 color pairs. * On emulators that support more than 256 pairs, we must still limit them to 256 (or 128 for Scinterm and SciTECO) since we still use a single attribute for colors and misc. attributes (see COLOR_PAIR()).
2026-01-18fixed auto-completion of Unicode file namesRobin Haberkorn2-6/+28
* teco_string_diff() could return a number of bytes in the middle of an Unicode sequence. It now also requires Unicode strings. * Added a missing Unicode-validity check when replacing command lines (`{` and `}`). teco_cmdline_insert() should really be refactored, though (FIXME). * Added test case
2026-01-15Curses: fixed flickering of the hardware cursorRobin Haberkorn1-12/+15
* Disabling the cursor with every key press caused a cursor status change when using CARETSTYLE_CURSES, which resulted in flickering, especially when using the cursor keys or typing quickly. * Instead we now disable the cursor only if CARETSTYLE_CURSES is NOT used on the command line. * It would be good to use curs_set(2) for `^T` - in some emulators it causes e.g. a blinking cursor - but it wouldn't be visible in simpleterm. This is probably just because it doesn't guarantee any contrast. * This was broken in v2.5.1.
2026-01-10Curses: the hardware cursor is enabled by default now on the command lineRobin Haberkorn1-7/+32
If you dislike this, you can always revert to the old style by adding the following to your profile: 0,2048ED 2#16@ES/SETCARETSTYLE//$ 2048,0ED
2026-01-09GTK: fixed bogus "(Unnamed)" strings in the message lineRobin Haberkorn4-10/+22
* An empty message line would actually contain "(Unnamed)". * Info popups must discern the "(Unnamed)" string (e.g. a file with that name) from the actual unnamed buffer since when clicking the unnamed buffer, you must insert nothing (`EB$`). Therefore, the unnamed buffer is represented as an empty string. "(Unnamed)" is just a placeholder for rendering. This was carried over into TecoGtkLabel which always rendered the empty string as "(Unnamed)". But TecoGtkLabels are used for the info and message lines as well. * Therefore the fallback/placeholder string is now configurable per label. * On the downside, this wastes one more machine word per TecoGtkLabel. The alternative would have been to use {NULL, 0} as the representation for unnamed buffers, so you can actually discern the empty string from the unnamed buffer representation. However it feels wrong to have this kind of info-popup-specific handling in a more generic label widget. Also, for consistency we'd have to touch the Curses UI as well where the unnamed buffer is also currently internally represented by empty strings (as opposed to NULL). * Regression introduced by 0c89fb700957e411885e7e7835e15f441e8b5e84, so it was in v2.5.0.
2026-01-06PDCurses: fixed modifiers (CTRL, ALT, SHIFT) and mouse support on XCursesRobin Haberkorn1-3/+4
* While xcurses-config does define PDC_WIDE, it does not define PDC_NCMOUSE, which we currently rely on so that NCURSES_MOUSE_VERSION is set correctly. Therefore we check for it just like when using --with-interface=pdcurses. * The modifiers were broken on all variants of PDCurses. This was a regression from v2.4.0.
2026-01-06PDCurses/XCurses: fixed crashes on startupRobin Haberkorn1-0/+15
Must not (and don't have to) probe the clipboard on startup. We just assume there always is a clipboard.
2026-01-05minor documentation improvement for `ED`Robin Haberkorn1-1/+1
2026-01-05Curses: fixed mouse interactions on PDCursesRobin Haberkorn1-0/+16
* There is yet another PDCurses vs. ncurses incompatibility: ncurses has a mouse event queue so you must call getmouse() repeatedly for every KEY_MOUSE, while PDCurses apparently doesn't queue and would end up in an infinite loop. I.e. the program would hang once you press any mouse button. * This forced us to add an PDCurses-specific version of teco_interface_getmouse().