aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
AgeCommit message (Collapse)AuthorFilesLines
2025-07-13implemented <ER> command for reading a file into the current bufferRobin Haberkorn6-27/+89
* This command exists in Video TECO. In Video TECO it also supports reading multiple files with a glob pattern -- we do not support that as I am not convinced of its usefulness. * teco_view_load() has been extended, so it can read into dot without discarding the existing document.
2025-07-13allow changing the default clipboard by setting the `~` integerRobin Haberkorn5-34/+113
* It continues to default to 67 (C), which is the system clipboard. But you can now overwrite it e.g. by adding `^^PU~` to the profile. * This fixes a minor memory leak: If you set one of the clipboard registers in the profile (initializing them as plain registers), the clipboard register had been leaked. The clipboard registers now replace any existing register, while at the same time preserving the numeric part. * All remaining Q-Reg table insertions use a new function teco_qreg_table_insert_unique() which adds an assertion, so that we notice any future possible memory leaks.
2025-07-13minor documentation fix in parser.cRobin Haberkorn1-1/+1
2025-07-11<EF> supports a numeric buffer id nowRobin Haberkorn3-46/+77
* ED hooks are not executed in this case * <EF> is now allowed even when editing a Q-Reg, unless you try to close the current buffer
2025-07-04implemented <^B> for returning the current dateRobin Haberkorn1-0/+42
* It is encoded with the same formula as on VAX/VMS on TECO-11, on TECOC and TECO-64. * As an extension, when colon-modified it returns the number of seconds since the epoch. It might be even more useful to return the microseconds since the epoch, but that would require 64-bit integers, which can theoretically be disabled at build time.
2025-07-03implemented ^E<code> string building constructs for embedding bytes and ↵Robin Haberkorn2-30/+110
codepoints in a strtoul()-like manner
2025-07-01GTK: handle (smooth) scrolling with a scroll controllerRobin Haberkorn1-15/+42
* On interfaces, which only support smooth scrolling, we had to emulate discrete events. Moreover, once we enabled GDK_SMOOTH_SCROLL_MASK, systems that would previously report discrete UP/DOWN events, would suddenly report GDK_SCROLL_SMOOTH. * Converting from smooth scroll events to discrete scroll events turned out to be trickier than anticipated. Scrolling was therefore more sluggish than it used to be before 2f448c976889fe60aba8557b5aa4aa0a0d939281. * Scrolling is therefore now delegated to a GtkEventControllerScroll, which is used to synthesize a discrete GDK_SCROLL event that's fed into the usual event pipeline via teco_interface_input_cb().
2025-06-27fixed ^S/^Y for <Gq> and <EN>Robin Haberkorn2-8/+9
* We must call teco_interface_bytes2glyphs() only ever with byte offsets that already exist in the buffer. * regression, introduced in aaa1d51a4c85fcc627e88ef7cf5292d9c5f5f840
2025-06-27fixed an asterisk in the <EN> manpage entryRobin Haberkorn1-1/+1
* We have to avoid `/*` within comments, so one of the two characters will have to use a named glyph. \[**] is actually a special symbol, which wasn't noticed until supporting Unicode. There is no named glyph for the plain asterisk. Thus we now use \[sl] to escape the `/` character. `/\c*` might have also worked. * grosciteco now supports the `sl` glyph.
2025-06-15PDCurses/Wincon: disable hardware cursor after window resizeRobin Haberkorn1-0/+5
2025-06-15require and adapted to PDCurses v4.5.1Robin Haberkorn1-8/+12
* PDCurses is practically used only for Windows builds, which only I build presumably, so it should be okay to bump the version. * Older PDCurses versions had serious problems like not detecting BUTTONX_RELEASED events. This was worked around and is fixed now. Even the Wincon version behaves like ncurses now with regard to mouse events. * We no longer have to support processing BUTTONX_CLICKED events. On the downside the mouse mask had to be adapted. * See also https://github.com/Bill-Gray/PDCursesMod/issues/330 * We also no longer have to call resize_term(0,0).
2025-06-15Revert "PDCurses/Win: more or less fixed mouse support"Robin Haberkorn1-37/+6
This reverts commit 8cc704b897f33d6150156c77202a29222b9ee667. This is no longer necessary with PDCurses v4.5.1. Keeping compatibility with old PDCurses versions is not very important as only I currently build and provide Windows binaries. Also, the previous workaround decreases usability on PDcurses/wincon even with a newer PDCurses library.
2025-06-12GTK: fixed scrolling on systems that only support smooth scrollingRobin Haberkorn1-4/+12
* Apparently, we cannot disable smooth scrolling on a per-application basis, so I have to handle both discrete and smooth scrolling events. * Since SciTECO's scroll API (-EJ) is based on discrete scrolling, we now emulate discrete scroll events by accumulating the delta_y of smooth scroll events. The threshold value of 12 is chosen arbitrarily, but based on an example in the Gtk documentation.
2025-06-08^S/^Y calculates the glyph offsets earlierRobin Haberkorn6-29/+62
* Previously, deleting text after a text match or insertion could result in wrong ^S/^Y results. In particular, the amount of characters deleted by <FD> at the end of a buffer couldn't be queried. * This also fixes the M#rf (reflow paragraph) macro.
2025-06-07initialize some variables in teco_state_expectqreg_input() to silence the ↵Robin Haberkorn1-2/+2
Clang static analyzer There was the possibility that an unitialized value is passed into a got_register_cb(). This could only happen in normal parse mode and it's unlikely to have caused problems in practice as all callbacks should not rely on qreg being valid in parse-only mode. This sort of bug would have also been catched by Valgrind. The rest of the scan-build-reported warnings are bogus (caused by not being g_auto-aware).
2025-06-07added <FN> as a search-and-replace variant of <N>Robin Haberkorn3-3/+53
* This is not in Video TECO, but TECO-11 has a search-and-replace variant of <N>. <N> however is a search-over-page-boundary command in TECO-11, which has been repurposed as search-over-buffer-boundary in Video TECO and SciTECO. * <N> and <FN> no longer call the edit hook after *every* invocation, but only if the current buffer changes. This is not really relevant with the current default hook from fallback.teco_ini, but might be depending on the use case. * Added testcases both for <N> and <FN>.
2025-06-01<nA> and <nQq> now return -1 in case the index n is out of rangeRobin Haberkorn4-33/+22
* The old behavior of throwing an error was inherited from Video TECO. * The command is now more similar to TECO-11. * Since -1 is taken, invalid and incomplete UTF-8 byte sequences are now reported as -2/-3. I wasn't really able to provoke -3, though.
2025-05-24<EI> has been repurposed and is the macro file inclusion (indirect file) ↵Robin Haberkorn5-29/+22
command now * Improves DEC TECO-11 compatibility. * <EM> is still supported as a synonym, but considered deprecated and is no longer documented. A warning is printed when invoked. It can be repurposed at any time in the future. * `EI$` is not yet supported. I am unsure whether this makes any sense.
2025-05-24new string building construct ^P disables all further string building magicRobin Haberkorn2-23/+25
* Now, `I^P` can replace `EI`. EI is therefore now free to be repurposed as the new "mung file" command for improved TECO-11 compatibility. * On the downside when inserting large blocks of TECO code, you will have to write something like `@I{^P !...! }` * The construct is also useful when searching for carets as in `S^P^Q^`.
2025-05-23<^C> is a plain "return" command now, while <^C^C> exits from the programRobin Haberkorn2-97/+180
* This may break existing macros! ^C is now essentially a synonym for $$ and may not terminate the program when called from a non-toplevel macro frame. However it improves compatibility with TECO-11. * In contrast to TECO-11, ^C^C (exit) can be typed completely in upcaret mode. Otherwise it wouldn't have been possible to use the exit command in ASCII-only scripts. * The implementation of ^C^C uses a lookahead state similar to ^[ (escape). ^C does not return immediately, but the following character determines whether it will perform a return or exit. It's one of the rare cases in SciTECO where this is possible and safe since ^C is also disallowed on the command-line to avoid undesired command-line terminations after ^C interruptions. (You can only use $$ to terminate the command-line interactively.)
2025-05-18allow process exit status to be determined by macrosRobin Haberkorn2-5/+18
* Any value left on the numeric stack now determines the exit code. This ensures you can call n^C as the SciTECO version of exit(n). It will also work with n$$ in the top level macro. But you don't necessarily need any of these commands. * Could be useful in shell scripting as in `sciteco -e "@EB/file/ :@S/foo/\"F1'"` to fail `foo` is not found.
2025-05-03disallow command-line termination ($$) while editing the command-line ↵Robin Haberkorn1-0/+12
replacement register (after `{`) I found that terminating the command-line while editing the replacement register, leaves you in a hard-to-recover state. You can/should no longer call `}`, so you would have to go back to the last buffer (Q*U*). Instead, this is now checked against and a test case has also been added.
2025-05-03fixed teco_doc_undo_exchange(): use reference counting nowRobin Haberkorn1-1/+3
* When popping from the Q-Register stack to local Q-Registers in macro calls, problems would arise when rubbing out that macro call since we would eventually restore a pointer that has been permanently freed along with the local Q-Registers. * Naturally this could result in everything from Valgrind warnings to crashes. * Added test case. * There is still a test case that fails when run under `--valgrind`, but it's apparently due to a glib-internal memory leak.
2025-05-02implemented folding for the SciTECO lexerRobin Haberkorn1-1/+26
* This currently folds only {...} string arguments and embedded braces, most prominently `@^Um{...}` macro definitions.. * Any additional folding for loops and IF-statements should rely on book keeping by the main parser. This would also help catch syntactic errors, like dangling IFs. * We do keep track of the loop nesting, but currently only in execution mode. * It cannot be disabled via the "fold" property. Lexers in the container do not have properties.
2025-05-02auto-expand folds even after mouse eventsRobin Haberkorn3-6/+12
The ^KMOUSE macro can also change dot and it was possible to place dot into invisible areas at the end of the document.
2025-04-27support folding via F1 and clicks in the folding marginRobin Haberkorn2-0/+6
* Set up the folding margin in the currently empty margin column after the line number. On Gtk, this meant resetting all the marker symbols and their foreground/background colors as well as the margin's colors themselves. This looks like a bug. It's not necessary on Scinterm, which apparently uses the default/linenumber styles by default. Perhaps we should try upgrading Scintilla? * The folding state is considered not to be directly controlled by the language (just like the scroll position and zoom level). That's why we can directly control it by clicking on the margin column. * F1 can be used to toggle all folds globally. * The only support within the C core necessary for folding is to make sure that the current line is unfolded after every keypress. * We might add custom folding commands to the language later on (e.g. F+, F-). In this case, the key macros will have to be changed of course.
2025-04-19Gtk: fixed setting the mouse cursor after changing the active bufferRobin Haberkorn2-2/+12
* The GdkWindow stacking order obviously got messed up when swapping out the child widget in the GtkEventBox. * This was probably also responsible for input events coming through to the Scintilla view even though the GtkEventBox should block all input events from reaching the Scintilla view. The event masking in teco_view_new() is probably no longer necessary - but better keep it to be on the safe side.
2025-04-18Gtk: prevent drag-and-drop interaction and block more possibly dangerous ↵Robin Haberkorn1-1/+12
touch and scroll events * You could drag and drop text into the Scintilla views, which would confuse SciTECO. * In the future, we might actually want to support programmable drag-and-drop support via special key macros.
2025-04-16curses: minor cleanup - avoid preprocessor statementsRobin Haberkorn1-11/+6
2025-04-15try hard to preserve the vertical scrolling position when auto-scrolling dotRobin Haberkorn2-5/+23
* There are cases, especially where the entire buffer is piped through some external process or when removing and reinserting large parts of the buffer, that dot changes very little, but the vertical scrolling position gets resets. This is especially noticable with the macro @^U{[: HECcat$ ]:}, but also with M#cf (clang-format wrapper from "Useful macros"). * We now try to preserve the vertical position ("first visible line") before scrolling caret.
2025-04-13Gtk: do not attempt automatic ANSI key translation for dead keysRobin Haberkorn1-0/+5
* At least on Windows it was observed that teco_interface_get_ansi_key() would find ANSI keys on other layouts, but nothing corresponding to the key itself. For instance, for a dead caret (^), we'd find backslash. This made it impossible to type caret in the parser start states. * We clumsily detect whether a keyevent refers to a dead key by checking its symbolic name and pass it down to the input method unmodified. * Fixes entering dead keys, at the very least on Windows, but potentially on all other systems as well.
2025-04-13fixed error message for nW and nP if it would move the pointer beyond the ↵Robin Haberkorn1-2/+2
document's boundaries
2025-04-13Curses: the mouse now scrolls two lines per event in the popup windowRobin Haberkorn1-2/+2
This is hardcoded, but in line with the current defaults from fnkeys.tes.
2025-04-13PDCurses/Win: more or less fixed mouse supportRobin Haberkorn1-6/+37
* Both the WinGUI and Wincon variants have their own idiosyncrasies: * WinGUI ignores `mouseinterval(0)` and may report BUTTONX_CLICKED for very quick clicks. Therefore we now emulate separate PRESSED/RELEASED events. * Wincon does not report BUTTONX_RELEASED at all. Therefore we still enable click detection, so that fnkeys.tes will work at least partially. Therefore we also enable REPORT_MOUSE_POSITION, so that right-click-dragging will work. This should still be fixed in PDCurses upstream, though. * See also https://github.com/Bill-Gray/PDCursesMod/issues/330
2025-04-13fixed undoing bitfields on WindowsRobin Haberkorn15-182/+178
* It turns out that `bool` (_Bool) in bitfields may cause padding to the next 32-bit word. This was only observed on MinGW. I am not entirely sure why, although the C standard does not guarantee much with regard to bitfield memory layout and there are 64-bit available due to passing anyway. Actually, they could also be layed out in a different order. * I am now consistently using guint instead of `bool` in bitfields to prevent any potential surprises. * The way that guint was aliased with bitfield structs for undoing teco_machine_main_t and teco_machine_qregspec_t flags was therefore insecure. It was not guaranteed that the __flags field really "captures" all of the bit field. Even with `guint v : 1` fields, this was not guaranteed. We would have required a static assertion for robustness. Alternatively, we could have declared a `gsize __flags` variable as well. This __should__ be safe since gsize should always be pointer sized and correspond to the platform's alignment. However, it's also not 100% guaranteed. Using classic ANSI C enums with bit operations to encode multiple fields and flags into a single integer also doesn't look very attractive. * Instead, we now define scalar types with their own teco_undo_push() shortcuts for the bitfield structs. This is in one way simpler and much more robust, but on the other hand complicates access to the flag variables. * It's a good question whether a `struct __attribute__((packed))` bitfield with guint fields would be a reliable replacement for flag enums, that are communicated with the "outside" (TECO) world. I am not going to risk it until GCC gives any guarantees, though. For the time being, bitfields are only used internally where the concrete memory layout (bit positions) is not crucial. * This fixes the test suite and therefore probably CI and nightly builds on Windows. * Test case: Rub out `@I//` or `@Xq` until before the `@`. The parser doesn't know that `@` is still set and allows all sorts of commands where `@` should be forbidden. * It's unknown how long this has been broken on Windows - quite possibly since v2.0.
2025-04-10fixed formatting of the smallest possible integerRobin Haberkorn2-2/+3
* In other words, fixed `-9223372036854775808\` on --with-teco-integer=64 (which is the default). * The reason is that ABS(G_MININT64) == G_MININT64 since -G_MININT64 == G_MININT64. It is therefore important not to call ABS() on arbitrary teco_int_t's.
2025-04-09fixup: <EI> command can be at-modified as in `@EI/foo/`Robin Haberkorn1-1/+2
2025-04-09tightened rules for specifying modifiersRobin Haberkorn4-49/+157
* Instead of separate stand-alone commands, they are now allowed only immediately in front of the commands that accept them. * The order is still insignificant if both `@` and `:` are accepted. * The number of colon modifiers is now also checked. We basically get this for free. * `@` has syntactic significance, so it could not be set conditionally anyway. Still, it was possible to provoke bugs were `@` was interpreted conditionally as in `@ 2<I/foo/$>`. * Even when not causing bugs, a mistyped `@` would often influence the __next__ command, causing unexpected behavior, for instance when typing `@(233C)W`. * While it was theoretically possible to set `:` conditionally, it could also be "passed through" accidentally to some command where it wasn't expected as in `:Ifoo$ C`. I do not know of any real useful application or idiom of a conditionally set `:`. If there would happen to be some kind of useful application, `:'` and `:|` could be re-allowed easily, though. * I was condidering introducing a common parser state for modified commands, but that would have been tricky and introduce a lot of redundant command lists. So instead, we now simply everywhere check for excess modifiers. To simplify this task, teco_machine_main_transition_t now contains flags signaling whether the transition is allowed with `@` or `:` modifiers set. It currently only has to be checked in the start state, after `E` and `F`.
2025-04-08minor improvements of TECO_DEFINE_STATE_COMMENT() documentationRobin Haberkorn1-2/+6
All state definition macros document their "base" states as well since they form an inheritance hierarchy.
2025-04-08improved rubbing out commands with modifiersRobin Haberkorn2-57/+105
* This was actually broken if the command is preceded by `@` and `:` characters, which are __not__ modifiers. E.g. `Q:@I/foo^W` would have rubbed out the `:` register as well. * Also, since it was all done in teco_state_process_edit_cmd(), it would also rub out modifier characters from within string arguments, E.g. `@I/::^EQ^W` * Real commands now have their own ^W rubout implementation, while the generic fallback just rubs out until the start state is re-established. This fails to rub out modifiers as in `@I/^W`, though. * Real command characters now use the common TECO_DEFINE_STATE_COMMAND(). * Added test cases for CTRL+W rub out. A few control characters are now portably available to tests via environment variables `$ESCAPE`, `$RUBOUT` and `$RUBOUT_WORD`.
2025-04-04scroll caret __almost__ always automatically after key pressesRobin Haberkorn2-7/+10
* The old heuristics - scroll if dot changes after key press - turned out to be too simplistic. They broke the clang-format macro (M#cf), which left the view at the top of the document since the entire document is temporarily erased. Other simplified examples of this bug would be: @^Um{[: HECcat$ ]:} Mm Or even: @^Um{[: H@X.aG.a ]:} Mm * Actually, the heuristics could be tricked even without deleting any significant amount of text from the buffer. The following test case replaces the previous character with a linefeed in a single key press: @^Um{-DI^J$} Mm If executed on the last visible line, dot wouldn't be scrolled into the view since it did not change. * At the same time, we'd like to keep the existing mouse scroll behavior from fnkeys.tes, which is allowed to scroll dot outside of the visible area. Therefore, dot is scrolled into view always, except after mouse events. You may have to call SCI_SCROLLCARET manually in the ^KMOUSE macro, which is arguably not always straight forward. * Some macros like M#cf may still leave the vertical scrolling position in unexpected positions. This could either be fixed by eradicating all remaining automatic scrolling from Scintilla or by explicitly restoring the vertical position from the macro (FIXME). * This was broken since the introduction of mouse support, so it wasn't in v2.3.0.
2025-03-29^W also rubs out/in `@` and `:` modifiersRobin Haberkorn1-0/+15
* It makes little sense to e.g. rub out until `I` in `@I/foo/`, but leave the `@` modifier. Modifiers have to be considered part of the command, even though the state machine is not currently modelled like that.
2025-03-29added `@W`, `@P`, `@V` and `@Y` command variantsRobin Haberkorn3-134/+138
* They swap the default order of skipping characters. For positive arguments: first non-word chars, then word chars. * This is especially useful after executing the non-at-modified versions. For instance, at the beginning of a word, `@W` jumps to its end. `@V` would delete the remainder of the word. * Since they have to evaluate the at-modifier, which has syntactic significance, the command implementations can no longer use transition tables, so they are in the switch-statements instead.
2025-03-23the ES command (send Scintilla message) now supports passing both wParam and ↵Robin Haberkorn2-18/+44
lParam as null-terminated strings * Being able to embed null bytes into the lParam string is practically useless - there aren't any messages where this is useful and where there are no native SciTECO counterparts - so this case is now catched and the null-byte separates wParam from lParam. * wParam can be the empty string, but it is not supported to pass wParam as a string and lParam as the empty string. If the second string argument ends in ^@, lParam is popped from the stack instead. * This is a temporary workaround until we can properly parse the Scintilla.iface and generate more elegant per-message wrappers. * It in particular unlocks the SCI_SETREPRESENTATION and SCI_SETPROPERTY messages. The former allows us to write a special hex-editor macro which sets hexadecimal character representations, while the latter allows you to set lexer properties. * The C-based lexers ("cpp" in Lexilla) can now take preprocessor definitions into account. This is disabled by default, unless you set lexer.c.defines before opening a file. You can also set it interactively and re-set the lexer. For instance: ^U[lexer.c.defines]NDEBUG$ M[lexer.set.c]
2025-03-23refactored Lexilla/Scintillua support: it's now in teco_create_lexer()Robin Haberkorn1-59/+80
2025-03-23the ^W immediate editing command now mimics `Y` more closely and also rubs ↵Robin Haberkorn3-6/+28
out no-op commands (whitespace) * In string arguments, ^W first rubs out non-word chars (usually whitespace), so it makes sense if ^W would work analogously at the command level. A non-command would be one of the no-ops.
2025-03-22added `P` command as a reverse form of `W`Robin Haberkorn3-4/+38
* All the movement commands have shortcuts for their negative forms: `R` instead of `-C`, `B` instead of `-L`. Therefore there was always the need for a `-W` shortcut as well. * `P` is a good choice because it is a file IO command in TECO-11, that does not make sense supporting. In Video TECO it toggles between display windows (ie. split screens) and I do not plan to support multiple windows in SciTECO. * Added to the cheat sheet.
2025-03-22factored out all cursor movement and deletion commands into the new ↵Robin Haberkorn4-599/+676
compilation unit move-commands.c * This made sense to include both `W` and `V`, so we also included `D` and `K`. `^Q` is included since it converts between lines and glyphs. * These are all single-letter commands, so they aren't complete parser states but callbacks to be referenced in teco_machine_main_transition_t.
2025-03-22harmonized all word-movement and deletion commands: they move/delete until ↵Robin Haberkorn3-22/+95
the beginning of words now * All commands and their documentations were inconsistent. * ^W rubbed out to the beginning of words. * Shift+Right (fnkeys.tes) moved to the beginning of the next word if invoked at the beginning of a word and to the end of the next word otherwise. * <W> (and <V> and <Y> by extension) moved to the end of the next word. * The cheat sheet would claim that <W> moves to the beginning of the next word. * Video TECO's <W> command would differ again from everything else. With positive arguments, it moved to the beginning of words, while with negative it moved to end of words. I decided not to copy this behavior. * It has been decided to adopt a consistent beginning-of-words policy. -W therefore differs from Video TECO in moving to the beginning of the current or previous word. * teco_find_words() is now based on parsing the document pointer, instead of relying on SCI_WORDENDPOSITION, since the latter cannot actually be used to skip strictly non-word characters. This requires a constant amount of Scintilla messages but will require fewer messages only when moving for more than 3 words. * The semantics of <W> are therefore now consistent with Vim and Emacs as well. * Shift+Right/Left is still based on SCI_WORDENDPOSITION, so it's behavior differs slightly from <W> for instance at the end of lines, as it will stop at linebreaks. * Unfortunately, these changes will break lots of macros, among others the M#rf, M#sp and git.blame macros ("Useful macros" from the wiki).
2025-03-21fixed rubout of Q-Register specificationsRobin Haberkorn4-4/+12
* This was a regression introduced by 257a0bf128e109442dce91c4aaa1d97fed17ad1a. * The undo token that frees newly allocated teco_machine_qregspec_t must actually reset the pointer as well since any subsequent token, pushed by teco_undo_qregspec_own(), will expect a valid pointer. * Could have been done via ctx->expectqreg = NULL; teco_undo_qregspec_own(ctx->expectqreg); but using a special clear function requires less memory and is easier to understand. * Added test case. This wouldn't always crash, but should definitely show up in Valgrind.