sciteco(7)

๐Ÿ“ฆ version 2.5.2, in alpine 3.24

sciteco(7) โ€” Miscellaneous Information Manual

โœจ NAME โœจ

sciteco โ€” language reference for the SciTECO text editor and language ๐Ÿ’…

๐ŸŒธ INTRODUCTION AND PHILOSOPHY ๐ŸŒธ

Okay bestie, so SciTECO is a powerful editor and an interactive programming language following a unique paradigm of text editing. It is different from popular screen editors like ex and traditional command-based editors like ed. Both of those paradigms can be understood as language-based, though.

Screen editors use simple languages based on commands that closely correspond with key presses โ€” keyboard commands, basically. Command-based editors use more complex languages, often turing-complete. Screen editors interpret their language immediately, while command-based editors do so only after complete input of an expression. Some editors like Vi or emacs support both screen-editing and command-lines in different modes of operation. Those editors are a compromise between both paradigms โ€” they support both paradigms to some extent โ€” while SciTECO represents a synthesis. In SciTECO, the screen-editing and command languages are the same! The SciTECO language can be interpreted interactively, and commands can be as simple as single key presses or as complex as nested high-level structured programming constructs. While screen editors often support an undo-stack to undo simple operations, SciTECO supports undoing and redoing on a per-character, per-command or even user-configurable level, undoing most of the side-effects on the overall editor state. Obsessed.

SciTECO is a member of the TECO family of text editor languages, invented by Dan Murphy in the 1960s. TECO was initially a purely command-driven editor that evolved screen editing features later on, culminating in the invention of Emacs as a TECO customization (macro package) in the 1970s. Emacs later became an independent program that eventually dropped TECO as its scripting language in favour of Lisp. SciTECO is not the first attempt to devise a TECO-based interactive screen editor. It is very similar to Video TECO, a little known editor that pioneered the concept. When Video TECO wanted to โ€œoutdo classic TECOs in every wayโ€, SciTECO wants to outdo Video TECO in every way. Periodt. ๐Ÿ’…

When you use SciTECO in interactive mode, it is important to know exactly how SciTECO translates and processes user input. Generally speaking, the user inputs TECO code that is parsed and executed on the fly by a stream parser/executor. Deleting characters from the end of the input stream is called rub out, and it has the effect of reversing the side-effects of the rubbed out characters. Rubbed out characters are kept and displayed to the user, who has the possibility of re-inserting rubbed out characters into the input stream. The input stream is called command line macro. Since SciTECOโ€™s undo capabilities requires memory and other resources, command lines may be terminated, reclaiming all resources and emptying the command line macro. The language of the command-line macro is basically the same as the language used in batch processing, with the exception of some commands that depend on the command line macro or undo-capabilities that are disabled in batch mode. To add to or remove from the command line macro, SciTECO supports a number of special keys called immediate editing commands. The key-processing for immediate editing commands is described in the next two sections. While immediate editing commands can be understood as yet another โ€” albeit limited โ€” language for screen editing, SciTECO also supports regular commands for command-line editing. ๐Ÿฆ‹

๐Ÿ”‘ KEY TRANSLATION โœจ

ok so here's the tea bestie: when you press a key (or a lil combo of keys), SciTECO first translates it into a UTF-8 string. the rules go like this:

  1. keys that have a printable vibe (letters, digits, special chars) get translated to their printable representation according to your current keyboard layout and whatever modifier keys you're holding ๐Ÿ’…. on the Gtk UI, SciTECO tries to automatically take ANSI letter values in situations where the parser accepts only ANSI characters. on Curses though? you might need key macros to pull off the same glow-up.
  2. control-combinations (like Ctrl+A) get translated to control codes, meaning a code smaller than 32. you can calculate the control code by stripping the seventh bit from the uppercase letter's ASCII code. so for instance, upper or lowercase A (65) becomes code 1, B (66) becomes code 2, etcetera ๐ŸŽ€. SciTECO will always use latin letters regardless of your current keyboard layout, no cap. SciTECO echoes control codes as a caret followed by the corresponding uppercase letter, so you seldomly need to know a control code's actual numeric code. for instance, control code 2 โ€” typed Ctrl+B โ€” will be echoed โ€œ^Bโ€. SciTECO also treats caret-letter combinations as equivalent to control codes under most circumstances โœจ.
  3. a few keys with non-printable representation also get translated to control codes. the most prominent is the Escape key โ€” it's translated to code 27. the Backspace key will always be translated to code 8, and the Tab key to code 9. the Return/Enter key is always translated to code 10 (line feed). naturally, all of these control codes can also be typed using a Control-key combination (e.g. Ctrl+I for the tab character) and there's often an equivalent typed with the caret character (e.g. โ€œ^Iโ€) ๐Ÿฆ‹.
  4. a selection of other keys without printable representation (we call these function keys) get looked up as key macros, which lets user-definable character sequences be inserted, including immediate editing commands ๐Ÿ‘‘. if there's no matching key macro, nothing is inserted. the whole key macro feature is explained in the next subsection, keep reading bestie.
  5. all keys with printable representations are also looked up as key macros, so you can remap them just like function keys. otherwise the corresponding UTF-8 strings get inserted into the command stream ๐Ÿ’–.
  6. the result of key macro lookups (or the default printable representations) are processed as immediate editing commands in a context-sensitive manner (peep the section COMMANDLINE EDITING). by default they're inserted into the command line macro and immediately executed โญ.

so while SciTECO handles keys with arbitrary Unicode representations, all immediate editing commands and regular SciTECO commands operate on a language based solely on ASCII codes, which is a subset of Unicode. and since the SciTECO parser is Unicode-aware, this does not exclude using Unicode glyphs wherever a single character is expected โ€” i.e. ^^x and Uq work with arbitrary Unicode glyphs ๐ŸŒˆ. all SciTECO macros must be in valid UTF-8, no exceptions.


๐ŸŽ€ Key Macros ๐ŸŽ€

by default, function keys except Escape, Backspace and Return are just ignored by SciTECO, lowkey rude but ok. with certain interfaces (curses) the Escape key might only be handled after a short delay ๐Ÿ™ˆ โ€” this is because it might be used by the terminal to transmit Escape Sequences. SciTECO minimizes this delay, so using the escape key should not be a problem even on ncurses/UNIX. if the default delay is too small, you can tweak it with the ESCDELAY environment variable, and if necessary a key macro can be defined as an escape surrogate as described in this section (fnkeys.tes defines the delete key as an escape surrogate for instance ๐Ÿ“).

to make use of function keys, or to remap all other keys, special Q-Register strings can be defined that get inserted into the command stream before immediate editing command handling. here's the full list of key macro registers SciTECO supports:

  • ^KDOWN, ^KUP โ€” inserted when the down/up cursor keys are pressed.
  • ^KLEFT, ^KSLEFT โ€” inserted when the left or shift-left cursor keys are pressed.
  • ^KRIGHT, ^KSRIGHT โ€” inserted when the right or shift-right cursor keys are pressed.
  • ^KHOME, ^KSHOME โ€” inserted when the Home or shift-Home keys are pressed.
  • ^KFx โ€” inserted when the Fx-key is pressed (x is a number between 0 and 63).
  • ^KDC, ^KSDC โ€” inserted when the Delete or shift-Delete key is pressed.
  • ^KIC, ^KSIC โ€” inserted when the Insert or shift-Insert key is pressed.
  • ^KPPAGE, ^KNPAGE โ€” inserted when the Page-Up or Page-Down key is pressed.
  • ^KPRINT, ^KSPRINT โ€” inserted when the Print or shift-Print key is pressed.
  • ^KA1, ^KA3, ^KB2, ^KC1, ^KC3 โ€” inserted when the numeric key pad's upper left key (7), upper right key (9), central key (5), lower left key (1), or lower right key (3) is pressed and num-lock is disabled. the key-pad's cursor keys are handled like the regular cursor keys ๐Ÿ’….
  • ^KEND, ^KSEND โ€” inserted when the End or shift-End key is pressed.
  • ^KHELP, ^KSHELP โ€” inserted when the Help or shift-Help key is pressed.
  • ^KCLOSE โ€” inserted when the Close key has been pressed. more importantly, this key is emulated in some GUIs (notably GTK+) when the user tries to close SciTECO's window or when the SIGTERM signal is received ๐Ÿซถ. this lets you customize SciTECO's behaviour when program termination is requested (e.g. only quit if there are no unsaved buffers). the close key is also special because it has a default action if the โ€œ^KCLOSEโ€ macro is undefined: it unconditionally quits SciTECO ๐Ÿ’€. that default action is not performed when โ€œ^KCLOSEโ€ has merely been masked out in the current parser state (see below).
  • ^KMOUSE โ€” mouse event occurred ๐Ÿ–ฑ๏ธ. this will not be delivered on Curses unless bit 7 (64) is set in the ED flags. you can use EJ with negative keys to retrieve the event type, mouse coordinates and other information about the last mouse event. Dot is not automatically scrolled into the view when processing mouse events, so you can customize scrolling and even have dot leaving the visible area โ€” very main character energy tbh. you can manually scroll dot into the view by calling SCI_SCROLLCARET โœจ.
  • ^Kx โ€” any other key with printable representation and all control codes are looked up with a โ€œ^Kโ€ prefix. x can usually only be a single Unicode glyph. if undefined, x is inserted unmodified ๐ŸŒธ.

โ€œ^Kโ€ corresponds to Ctrl+K (ASCII code 11) in the above list, but might be typed with a caret due to string building characters in long Q-Register names. the names are all derived from key definitions of the curses library โ€” not all of them may be supported on any particular user interface, iykyk ๐Ÿ˜ญ.

the result of key macro expansion differs from consecutive key presses in that they're considered a unity ๐Ÿ‘‘. if insertion of a single character fails (raises an error), the entire macro expansion is automatically rubbed out. periodt.

by default key macros are effective everywhere โ€” pressing a key has the same effect as processing the characters of the corresponding key macro as immediate editing commands (or self-inserting characters). however, key macros that rewrite the current command line will only work correctly from specific SciTECO parser states ๐Ÿ˜ฌ. another common use of key macros would be defining aliases of SciTECO commands for non-latin keys on Curses. so SciTECO lets you mask key macros in specific parser states by evaluating the Q-Register's numeric part, which lets you control where a key macro is effective ๐Ÿ’–. the numeric part represents a bitmask of states where key macros are disabled (so the default value 0 enables that key macro everywhere). SciTECO defines these state flags:

  • 1 โ€” bit 0 represents the โ€œstartโ€ state where SciTECO accepts the beginning of a command. this is the state you'll want command line editing macros enabled in โญ.
  • 2 โ€” bit 1 represents any string argument.
  • 4 โ€” bit 2 represents any case insensitive syntactic character. this is the state you might want to use for translating non-latin characters to their latin equivalent ๐ŸŒˆ.

all other bits/flags represent any other parser state. consequently, setting the register to the inverse of a bitmask of state flags enables the corresponding macro only for the specified states ๐ŸŽ€. for instance, to enable the โ€œ^KRIGHTโ€ key macro only in the โ€œstartโ€ state, you could set:

1^_U[^KRIGHT]

a set of useful key macros for function keys is provided in the standard library fnkeys.tes ๐Ÿฆ‹. it demonstrates how key macros may be used to define alternate Escape keys (so the delay issue is not experienced), or do insertion and command-line editing using function keys. slay.


๐Ÿ’… COMMANDLINE EDITING ๐Ÿ’…

after all key presses have been translated to characters, SciTECO interprets some of them in a special way to perform command line editing and a few other actions that cannot depend on regular command execution ๐Ÿ‘‘. these special characters are called Immediate Editing Commands and are outlined in the following subsection. all characters not handled as immediate editing commands are self-inserting, i.e. they insert themself into the command stream and may be processed as regular commands or part of them โœจ.

โœจ Immediate Editing Commands โœจ

okay bestie, here's the rundown of the Immediate Editing Commands ๐ŸŒธ Some of them are everywhere and aren't used as regular commands (because typing them would be a whole struggle). Some are context-sensitive, though, and are only available in or depend on the current language context (at the end of the command line) that SciTECO always knows about. Because of this superior parsing and command line editing, editing is much less dangerous and much more interactive than in classic TECO implementations. Most of these commands are control codes, so their control code mnemonics are given too. ๐Ÿ’…

  • Toggle modifier โ€” Code: 7 โ€ข Mnemonics: ^G โ€ข Context: Everywhere.
    • Toggles the immediate editing command modifier and displays its new state. If it's enabled, the rubout commands will perform analogous re-insertions of previously rubbed out characters. So ^G (CTRL+G) effectively switches between undo and redo modes. The modifier also influences the behaviour of the TAB key. ๐Ÿซถ
  • Case insensitive command character โ€” Code: โ€” โ€ข Mnemonics: Any letter โ€ข Context: Beginning of case-insensitive commands (automatic case folding enabled).
    • At the beginning of case-insensitive commands, the case of letters is inverted. One or two letter commands will thus typically be inserted in upper case. This only happens if bit 3 of the ED flags is set, e.g. by executing:
0,8ED
  • Insert end of line sequence โ€” Code: 10 โ€ข Mnemonics: ^J, Return, Enter โ€ข Context: Everywhere (no automatic EOL translation).
    • If automatic end of line sequence translation is disabled, the return key will insert the current buffer's end of line sequence (line feed; carriage return, line feed; or carriage return) according to the SCI_GETEOLMODE Scintilla message. In auto-EOL-translation mode, the return key will always insert a line feed. โœจ
  • Rub out character โ€” Code: 8 โ€ข Mnemonics: ^H, Backspace โ€ข Context: Everywhere (modifier disabled).
    • Rubs out the command line's last character. ๐Ÿ’…
  • ^H, Backspace โ€” key code 8, doing Re-insert character.
    • Everywhere + modifier enabled: inserts the next character from the rubbed-out part of the command line. ๐Ÿ’–
    • Non-empty file name arguments + modifier disabled: rubs out the directory separator at the end of the filename and the last filename component up to but not including the preceding directory separator. ๐ŸŽ€
  • ^W โ€” key code 23, doing Rub out word/command.
    • Non-empty string arguments + modifier disabled: rubs out to the beginning of the last word according to Scintillaโ€™s definition of a word as set by SCI_SETWORDCHARS, analogous to Y command. โœจ
    • Miscelleaneous + modifier disabled: rubs out until the beginning of the last command, which is not a no-op (whitespace). The @ and : modifiers are considered part of the command and are also rubbed out. ๐Ÿ’…
  • ^W โ€” key code 23, now doing Re-insert word/command:
    • File name arguments + modifier enabled: re-inserts the next file name component up to and including the next directory separator from the rubbed-out command line. ๐Ÿฆ‹
    • String arguments + modifier enabled: re-inserts the next word from the rubbed-out command line according to Scintillaโ€™s definition of a word as set by SCI_SETWORDCHARS. ๐ŸŒธ
    • Miscelleaneous + modifier enabled: re-inserts the next command from the rubbed-out command line including all subsequent no-ops (whitespace). The @ and : modifiers are considered part of the command and are also re-inserted. ๐Ÿ‘‘
  • ^U โ€” key code 21, doing Rub out string.
    • String arguments + modifier disabled: rubs out the entire current string argument. ๐Ÿ“
  • ^U โ€” key code 21, doing Re-insert string.
    • String arguments + modifier enabled: re-inserts the entire current string argument from the previously rubbed-out part of the command line, stopping at the stringโ€™s terminating character. ๐Ÿงš
  • ^I, Tab โ€” key code 9, doing Auto complete Q-Register name.
    • Q-Register specifications: in all Q-Register specifications โ€” either after a command with a Q-Register argument like M or as part of a string building construct like ^EQ (of course

So picking up right where we left off with that register auto-complete ๐Ÿ’… โ€” string building constructs inside Q-Register specifications totally count too, and it's gonna auto complete the local or global register name beginning at the start of the specification. Cute, right?

  • With one- or two-letter specifications (#xy), only one- or two-letter register names are even considered for auto-completion. Short king energy only ๐Ÿ‘‘
  • With long specifications ([name]), fully completed names get terminated with a closing bracket, which ends the specification. Clean. โœจ

  • Auto complete filename โ€” key 9, key name ^I, Tab
    • String arguments (modifier enabled) and operating system command arguments: auto completes the filename beginning after the last space (or at the beginning of the string argument). Fully completed filenames are terminated with a space. And this autocompletion works in every string argument, as long as the ^G modifier is enabled. fr fr, every single one ๐Ÿซถ
    • File name arguments: auto completes the filename beginning at the start of the argument. Fully completed filenames terminate the string argument โ€” except if the { terminator is used. Sneaky little exception, but we move ๐Ÿ’€
  • Auto complete directory โ€” key 9, key name ^I, Tab โ€” for Directory arguments, it auto completes the directory beginning at the start of the argument. That's it, that's the vibe ๐ŸŽ€
  • Auto complete symbol โ€” key 9, key name ^I, Tab โ€” for Scintilla symbol arguments, i.e. in ES commands, it completes beginning with the symbol, and fully completed symbols get terminated with a comma. Iconic behaviour honestly โญ
  • Auto complete Goto label โ€” key 9, key name ^I, Tab โ€” for Goto command arguments, in Goto label arguments (O command), it completes beginning with the current label, and fully completed labels get terminated with a comma. Lowkey the most useful one ngl ๐Ÿฆ‹
  • Auto complete help topic โ€” key 9, key name ^I, Tab โ€” for Help topic arguments (? command), it completes beginning at the start of the command. Fully completed topics terminate the string argument, which effectively opens the corresponding womanpage โ€” except if the { terminator is used. Yes bestie, it literally opens the docs for you ๐Ÿ˜ญ๐Ÿ’–
  • Indent to next tab stop โ€” key 9, key name ^I, Tab โ€” for Text insertion arguments, it expands to spaces so that followingโ€ฆ

โ€ฆthe text gets inserted at the next tab stop into the buffer ๐Ÿ’–. This takes Scintilla's indention policy into account and results in the same indention as the ^I command โ€” same vibe, same spacing, no cap. โœจ


  • Suspend process โ€” code 26, key ^Z, availability: Everywhere. Suspends the process using SIGTSTP. Ngl, this one is only an immediate editing command on platforms that actually support this signal (usually Unices ๐Ÿ™‚). The process can also be suspended from another process, for instance by pressing Ctrl+Z in the console โ€” and that path also works if SciTECO is busy ๐Ÿ”ฅ. So with GUI user interfaces (GTK+), this command will only work as an immediate editing command in the GUI, or as a signal dispatched from an associated console or from another process. iykyk ๐Ÿ’…
  • Redraw โ€” code 12, key ^L, availability: Everywhere. Enforces a complete redraw of the entire window ๐ŸŒˆ. Super useful when the display gets corrupted โ€” especially when you're using the Curses UI. Little rescue button, fr fr. ๐Ÿซถ
  • Interrupt โ€” code 3, key ^C, availability: SciTECO is busy. Lowkey not a real immediate editing command ๐Ÿ’€. It will interrupt the current operation (character processing), yielding a SciTECO error. On some GUIs it depends on asynchronous delivery of the SIGINT signal, and it's useful for interrupting infinite loops ๐Ÿ‘‘. Since not all user interfaces support interruptions via ^C, it may be necessary to deliver the signal by pressing ^C on the attached console or by explicitly sending it. And heads up: if SciTECO is not busy, ^C is self-inserting and might be typed as part of regular commands โ€” though the ^C command itself is disallowed in interactive mode. Sneaky little guy ๐Ÿ™ˆ

๐ŸŽ€ Undo and Redo ๐ŸŽ€

Okay so here's the thing, bestie โ€” the immediate editing commands that rub out and re-insert characters effectively constitute SciTECO's undo and redo support ๐Ÿ’…. And, exactly like all the features implemented by the immediate editing commands, undo and redo is only possible when you're using SciTECO interactively. Interactive only, periodt โœจ.

When a character gets rubbed out, SciTECO reverses the side effects it had when it was typed ๐Ÿฆ‹. But โ€” and this is the cute part โ€” the rubbed out characters are not discarded immediately; they're kept in a rubbed out part of the command line. The user interface displays this area as characters at or after the command line cursor, and it tries to highlight them (e.g. by underlining and greying them out) ๐ŸŒธ. So, since characters that resulted in errors (not accepted into the command-line macro) are automatically rubbed out, they can still be seen in the command line's rubbed out area ๐Ÿ‘€.

The rubbed out command line is not a part of the command-line macro, though. Just so we're clear ๐Ÿ’–.

Okay so changes can be redone by typing the characters at the command line cursor or using one of the re-insertion commands โ€” undo and redo literally looks like moving the command line cursor back and forth, bestie. The re-insertion commands are the same as the rubout commands but need the immediate editing modifier to be enabled. The ^G (CTRL+G) command toggles this modifier and thus has the primary effect of switching between undo and redo modes. SciTECO discards the rubbed out command-line once you type or insert a character that is not a prefix of the rubbed out command line. This will also automatically disable the ^G modifier. The ^G modifier is disabled by default, so the corresponding commands work similar to their Unix shell counterparts. Fr fr.

Ngl, SciTECO's undo stack requires an increasing amount of memory and other resources proportional to the length of the command line, so it is occasionally useful to reclaim these resources โ€” especially after operations that consumed a lot of memory. In some cases, commands like tight loops might even make the system swap until SciTECO hits its configurable memory limit. It is therefore possible to terminate command lines using the $$ (double escape) command โ€” or in other words by returning from the command line macro. Since this is a regular command respecting SciTECO's syntax, it is much less likely to accidentally terminate a command line than in classic TECOs where $$ is a special immediate editing key sequence. Command line termination will reclaim all undo-related resources without undoing any side effects, thus โ€œpersistingโ€ or โ€œcommittingโ€ them. Since undoing those side effects (of the last command line) will no longer be possible, command line termination will also reset the command line macro. Global and local Q-Registers are not affected by command line termination. ๐Ÿซถ

โœจ Auto Completion โœจ

The immediate editing commands, that perform auto-completions, do so in a manner similar to Posix shells. Upon first invocation they try to fully or partially complete the file name (or token). If the token can be fully completed, the current command or Q-Register specification will also usually be terminated automatically. If no completion can be performed, the invocation will display a list of file names (or tokens) that begin with the token to complete in SciTECO's popup area. If the popup area is not large enough to display all possible completions, this is highlighted by the user interface using scroll bars. If the immediate editing command is invoked again, the next page of file names or tokens is displayed in the popup area. I.e. it is possible to cycle through long lists of possible auto-completions. Iconic behavior, honestly. ๐Ÿ’…

You can also scroll through the popup area with the mouse wheel. Furthermore, you can click on entries in the popup area with the mouse in order to fully complete them. Often this will also automatically terminate the current command or Q-Register specification, just like an unambiguous completion via immediate editing commands. On Curses, mouse events are not processed unless bit 7 (64) is set in the ED flags.

When completing file names, hidden files are not considered for completion unless a prefix of the hidden file's name has already been typed. On Unix, SciTECO considers files and directories beginning with "." as hidden. On Windows, the hidden file attribute is evaluated. On other platforms, SciTECO might not identify hidden files correctly. ๐Ÿซฃ

Both forward and backslash directory separators are supported as arguments to SciTECO commands on Windows: the separator style used for auto-completions is determined by the last separator in the supplied file name and defaults to backslash. Therefore forward-slash auto-completion is possible on Windows, e.g. by using a forward-slash in the file name or by prefixing file names with ./. This is useful for writing cross-platform SciTECO macros (see FILE NAMES AND DIRECTORIES).

File name completions are case-sensitive or insensitive depending on operating system defaults. On some operating systems SciTECO can determine the case-sensitivity of individual directories as well.

Note that completions take place after string building and tilde-expansion is also performed by file name completions, so for instance both ~/foo and ^EQ[$HOME]/foo will complete a file in the user's home directory. Auto-completion also takes care of quoting string termination and string building characters, which might be relevant especially when autocompleting Q-Register names. The way that works is lowkey kind of genius. ๐Ÿงš

๐ŸŒˆ USER INTERFACE ๐ŸŒˆ

SciTECO can be built with support for different textual and graphical user interfaces. In SciTECO's batch mode, there is little difference between the user interfaces (as no graphical window will be visible). Naturally the interfaces have different graphical capabilities but SciTECO tries to provide a consistent look and feel across all user interfaces and reasonable defaults to make writing user-interface agnostic macros and profiles easier. The user interface will always be segmented into the following areas from top of the program window to bottom:

  • The info area โ€” identifying the currently edited buffer or Q-Register. This area is currently sometimes omitted. If technically possible, SciTECO will include the same information in the window's title.
  • The Scintilla area โ€” displaying the current document's contents. This corresponds to a Scintilla view (see section BUFFER RING) and can be customized extensively using Scintilla messages (see the ES command).
  • The message area โ€” which will show the last SciTECO message that occurred. This area will show errors, warnings, โ€œuser messagesโ€ and other notes and tries to highlight them appropriately.
  • The auto-completion popup area โ€” which is only shown when presenting the user with a choice of auto-completions. This area will overlap the Scintilla and message areas.
  • The command line area โ€” showing the currently effective and rubbed-out command line as it is edited. This is a single line by default, but can be configured with 5EJ. Since it is also a Scintilla view, it can be further customized by running 0,2048ED and invoking Scintilla messages using ES.

๐ŸŽจ Colors and Theming ๐ŸŽจ

SciTECO supports customizing its look predominantly by setting up the current Scintilla view using Scintilla messages (see the ES command and Scintilla documentation). Most visual properties of the Scintilla view can be set via its styles. This is also how syntax highlighting (lexing) is set up. Obsessed with the flexibility, ngl. ๐Ÿ’–

The STYLE_DEFAULT (32) style defines the default foreground, background color, font etc. and is initialized to white on black with some monospaced font by SciTECO. The STYLE_DEFAULT is also accessed by SciTECO to style the info area, message area (if it is empty or when showing โ€œuser messagesโ€) and command line area. The info and message areas are styled reverse to the setting of this style to provide good contrast, i.e. with foreground and background colors swapped. The colors used to highlight errors, warnings and other messages in the message area are currently hardcoded and cannot be customized. The command line area on the other hand will be styled with the original colors of STYLE_DEFAULT and should look similar to the current Scintilla view.

The STYLE_CALLTIP (38) style is also accessed by SciTECO to style the popup area and is initialized to black on white by SciTECO.

On curses user interfaces, only a selection of 16 terminal colors can be used, although it is possible to request changing the default color mapping (see EJ command).

Scintilla styles will usually be set up in the profile macro or ED hook (for syntax highlighting). SciTECO ships with a standard library with color schemes and lexer configurations for a wide range of languages. Itโ€™s giving โ€œready-made slayโ€. ๐ŸŽ€

๐Ÿ’… Gtk CSS Styling ๐Ÿ’…

While the tools mentioned above are sufficient for Curses UIs, the Gtk+ 3 UI has many more styling possibilities. The basic color scheme will be automatically effective for the buffer view since this is handled by Scintilla. In order to apply the color scheme to the other UI components, a CSS file must be provided that overrides certain styling settings of the Gtk theme.

Therefore SciTECO automatically exports the following Gtk CSS variables that can be referred to by user-provided CSS files:

  • @sciteco_default_fg_color โ€” the foreground color of Scintilla's STYLE_DEFAULT.
  • @sciteco_default_bg_color โ€” the background color of Scintilla's STYLE_DEFAULT.
  • @sciteco_calltip_fg_color โ€” the foreground color of Scintilla's STYLE_CALLTIP.
  • @sciteco_calltip_bg_color โ€” the background color of Scintilla's STYLE_CALLTIP.

Furthermore, SciTECO defines named widgets for its main UI components as well as several CSS classes. Very main character energy, if you ask me. โœจ

The CSS file is loaded from $SCITECOCONFIG/.teco_css if it is existing. Else, SciTECO loads the fallback CSS at /usr/share/sciteco/fallback.css, which can also be used as a template when writing .teco_css. The fallback CSS can also be consulted for additional documentation on SciTECO's named widgets and special CSS classes. The CSS file can be written such that it works for any SciTECO color scheme and may also be used to tweak other aspects of SciTECO's user interface. Please refer to the Gtk documentation for more details on CSS theming. ๐Ÿ’œ

โšก ARITHMETICS AND EXPRESSIONS โšก

Okay bestie, this is where SciTECO gets its little stack-powered brain going. ๐Ÿ’… Classic TECO had this whole scheme where commands accept at most two prefix arguments and return at most one value for the next command. SciTECO said โ€œnot me being limited like thatโ€ and abstracted it into a much more elaborate scheme where commands accept n arguments and return n arguments. It does this with an integer value stack โ€” the stack is literally for passing arguments and for arithmetics. So yes, SciTECO is a stack-based language. ๐Ÿซถ

But donโ€™t panic: unary prefix and binary infix operators are supported, including operator preference. And because the same stack is used for arithmetics and command arguments, arithmetics and arbitrary code can be freely mixed like in expression-centered languages and some classic TECOs. In fact, in SciTECO digits are basically stack-operating commands. For the sake of macro portability all integers are 64-bit signed integers regardless of the hostโ€™s architecture. The integer storage size may be changed at SciTECO build time however. In this specific build, integers are 64-bit. โœจ

Some commands expect or return booleans, most often signifying success or failure. Booleans are also integers, but โ€” and this is the chaotic part โ€” unlike in ordinary (sane) languages where 0 represent false and other values represent true, in SciTECO negative values (smaller than zero) represent success and non-negative values (larger than or equal to zero) represent failure. So SciTECO booleans may be negated by performing a binary (bit by bit) negation, for instance using the ^_ command. Not me side-eyeing the success-is-negative situation ๐Ÿ’€ but okay, we move.

๐Ÿงฎ Operators

The following binary operators are supported with descending precedence, whereas borders separate operators of the same precedence:

  • top tier โ€” base ^* power: Raise base to power.
  • next tier, all same precedence:
    • a ^/ b โ€” Remainder of a divided by b. It is actually a modulo operation conforming to the host C compilerโ€™s modulo semantics.
    • a / b โ€” Divide a by b. Naturally it is a division without remainder.
    • a * b โ€” Multiply a by b.
  • next tier, same precedence:
    • a - b โ€” Subtract b from a.
    • a + b โ€” Add b to a.
  • next tier:
    • a & b โ€” Binary AND.
  • next tier:
    • a ^# b โ€” Binary exclusive OR (XOR).
  • lowest tier:
    • a # b โ€” Binary OR.

All binary operators are left-associative, i.e. associate from left to right, in SciTECO. Round brackets may be used for grouping expressions to override operator precedence and associativity. For instance, since ^/, / and * all have the same precedence, the expression 1 ^/ 2 / 3 * 4 is equivalent to (((1 ^/ 2) / 3) * 4). ๐ŸŽ€

The opening bracket also represents an argument barrier, i.e. the first command after the opening bracket does not see and cannot pop any arguments from the stack. This may be useful for mixing commands with arithmetic expressions. An expression enclosed in brackets returns all of the values that have been pushed onto the stack. SciTECO currently performs minimal checking on the validity of braces (i.e. the closing brace โ€œcommandโ€) which are handled more or less like regular commands with regards to flow control. Care should thus be taken when jumping out of braces or leaving open braces at the end of macros as this might leave the parser in an unexpected state. Conversely, the return command $$ has special support for dealing with braces. As the current behaviour has probably little benefits, the rules governing braces might be made stricter in a future release of SciTECO. ๐Ÿ™ˆ

Another construct that may be used as an argument barrier to explicitly separate arguments is the comma (,). It is obligatory when trying to push a sequence of number constants like in 1,2 but is optional in many contexts where it is mandatory in classic TECO, like in .ZD. The recommendation is to use it as much as possible in code where clarity matters. ๐Ÿ’–

The arithmetic evaluation order established by the operator precedence or braces must not be confused with the execution order of SciTECO commands which is always strictly from left to right (unless flow control commands are used). Literally: math groups, but command execution stays in its left-to-right lane. ๐Ÿฆ‹

The only unary operator currently supported is -. The minus-operator is special and has unique semantics. It sets the so called prefix sign which is 1 by default to -1. This prefix sign may be evaluated by commands โ€” most often it is the default value if the argument stack is empty so that expressions like -C are roughly equivalent to -1C. However in front of opening brackets, like in -(1+2), it is roughly equivalent to -1*(1+2) so that values calculated in brackets can be easily negated. In front of digits the prefix sign specifies whether the digit is added or subtracted from the value on the stack so that in front of numbers the result is a negative number. ๐ŸŒธ

๐ŸŽ€ BUFFER RING ๐ŸŽ€

Okay bestie, so SciTECO organizes the files you're editing into something called the buffer ring โ€” and yes, it's literally a circular list of buffers. A buffer is a named or unnamed Scintilla document, and honestly it's giving SciTECO's second important primary data type. There is at most one unnamed buffer in the ring, identified by the empty name. Named buffers are buffers with an associated file name. That file might or might not already exist in the file system โ€” no cap. The file name uses the host system's directory separator, but for the sake of macro portability the directory separators are normalized to / when accessing the current buffer's file name with the * Q-Register. File names are always tried to be normalized to absolute paths to make them independent of SciTECO's current working directory. New buffers are always added at the end of the buffer ring. The Id of a buffer corresponds to its position in the ring โ€” first one has Id 1, second one Id 2, etc. Buffers may be marked dirty by destructive operations, which is lowkey iconic of them.

Every buffer has its own Scintilla view, which means it behaves like a standalone Scintilla instance. This means all Scintilla messages you send to the current buffer (using the ES command) affect only this buffer. So if you change some setting (like syntax highlighting), switch the buffer and eventually switch back, all settings will still be in effect. It's giving persistence ๐Ÿ’…. If a configuration should be applied to all buffers, ED hooks should be used (see below). Note that Q-Registers behave differently โ€” they can also be edited like regular buffers but share one Scintilla instance for performance reasons.

SciTECO is a character-oriented editor, so every character in a buffer/document may be addressed by a position integer. The first character is addressed by position 0. Every document has a current position called dot (after the . command that returns it). A document may contain any sequence of bytes but positions refer to characters that might not correspond to individual bytes depending on the document's encoding (see the EE command). The ^E command can be used to translate between byte and character/glyph positions. Consequently when querying the code at a character position or inserting characters by code, the code may be a Unicode codepoint instead of a byte-sized integer. Slay, Unicode, slay โœจ.

Currently, SciTECO supports buffers in UTF-8 and single-byte ANSI encodings, which can also be used for editing raw binary files. UTF-8 is the default codepage for new buffers and Q-Registers unless the 2nd ED flag bit is set. You can also specify --8bit to optimize SciTECO for 8-bit cleanliness. While navigation in documents with single-byte encodings takes place in constant time, SciTECO uses heuristics in UTF-8 documents for translating between byte and character offsets โ€” which are slower, especially when โ€œjumpingโ€ into very large lines. Like, very large lines? It's giving performance anxiety ๐Ÿ˜ญ.

To simplify working with files using different end of line sequences (combinations of carriage return and line feed), SciTECO implements an automatic EOL translation feature. When loading files with the EB and EQ commands โ€” or when reading from an external process with the EC and EG commands โ€” SciTECO will normalize all end of line sequences to line feeds. It will also detect, correct and warn about inconsistent EOL sequences in the source file or process output. EOL normalization is thus a lossy process. The file's original EOL mode as guessed by SciTECO is still saved as the corresponding Scintilla document's EOL mode (see SCI_SETEOLMODE and the EL command). If the EOL mode could not be guessed, the document will retain a platform-default EOL mode (e.g. carriage return, line feed on Windows and line feed on UNIX). The EOL mode is used when saving files with the EW and E% commands or when writing to an external process with the EC and EG commands in order to reconstruct the original EOL characters. Translation on write-out will also work when the source document has inconsistent or mixed line breaks. Therefore macros can assume each line to be terminated by a single line feed character while working with files that have different EOL styles. The feature is enabled by default but is controlled by bit 4 of the ED flag setting. It can be turned off by executing:

16,0ED

This may be beneficial when working with very large files โ€” as the EOL translation imposes a performance penalty โ€” or non-text (binary) files. No automatic guessing of documents' EOL mode is performed when disabling this feature, so all documents will have platform-default EOL modes set.

For more details, please refer to this manual's command reference.


๐Ÿช„ Buffer Editing Hooks ๐Ÿช„

When opening or editing a file with the EB command or when closing a file with the EF command, you often want to configure the editor for a particular language. For instance, when opening C++ files you might want to enable C++ lexing and syntax highlighting automatically. SciTECO thus provides user-configurable hooks into buffer editing operations. Hooks are by default disabled. To enable them, set bit 5 in the ED flags:

0,32ED

SciTECO will now execute the macro in global Q-Register ED whenever a relevant operation is performed. This macro must be provided if ED hooks are enabled โ€” fr fr, don't leave it hanging.

The ED macro will receive an argument that specifies the type of operation that has just been performed or is just about to be performed. The ED macro is executed in a more or less isolated way by SciTECO, i.e. it will not see any other argument that is on the expression stack when the hook is executed, and all values it may leave on the expression stack are discarded. This way, ED hooks should not interfere with the stack-semantics of commands triggering them. Bestie boundaries, periodt.

Possible arguments to the ED macro begin with 0 and are defined consecutively so the macro can branch to the operation using a computed goto. The different values are defined as follows:

  • 0 โ€” A file has been added to the buffer ring. It may or may not already exist in the file system. This file is SciTECO's current document when this hook executes. Scintilla lexing may be configured in this hook โ€” it usually only has to be done once.
  • 1 โ€” A buffer has been edited (made the current file). This hook is not executed when a file is freshly added to the buffer ring, since this can be simulated easily by branching within the ED macro. In this hook you may want to define language-specific auxiliary macros, for instance.
  • 2 โ€” A buffer is about to be closed (removed from the buffer ring). The buffer that is about to be closed is still the current document when this hook runs.
  • 3 โ€” SciTECO is about to quit, i.e. exit normally. This is SciTECO's equivalent of atexit(3) handlers. The hook is not run when some command fails, but only when SciTECO exits normally. This is the case when control in a macro specified via --eval reaches the end, or otherwise returns (using ^C or by returning from the top-level macro via $$). Similarly, the hook is executed when a munged file calls ^C or EX has been called before the top-level macro returns. It is also called after the interactive mode has shut down by calling EX$$. The quit hook will always run in batch mode (after any user interface has shut down). Errors in the hook's execution will not prevent SciTECO from exiting, but an error trace will be printed and SciTECO exit code will be a failure code. It is not possible to cancel program termination via quit hooks. The quit hook may be used to transparently save a buffer session, for instance. Honestly? Kind of a big deal ๐Ÿ‘‘.

The side-effects of the hook executions are reversed when rubbing out the command that resulted in its execution. Unless otherwise noted, errors during hook execution will propagate and let the command triggering the hook execution fail.

The SciTECO standard library contains a framework for configuring Scintilla lexing and other useful hooks (see lexer.tes).

โœจ COMMAND SYNTAX โœจ

okay so SciTECOโ€™s command syntax is super flexible and diverse, but it still breaks down into a few base command types. Think of these as the main-character command shapes, bestie. ๐Ÿ’…

  • C / EF โ€” A simple command is one or more printable or control characters whose case is insignificant. Only at the beginning of a command, carets followed by one character are equivalent to the corresponding control character. Since it does not make any sense whatsoever to support a caret-form of non-operational (ignored) control character commands (i.e. form feed, carriage return, line feed, vertical tab), their caret forms (e.g. ^J) are reserved for future use as operational commands. The command is executed as soon as it has been completely specified.
  • Qq โ€” A command identifier may be followed by a Q-Register specification q. It specifies a Q-Register to be accessed by the command (e.g. to query, set, increase).
  • Istring$ / FSstring1$string2$ โ€” A command identifier (and Q-Register specification) may be followed by one or more string arguments. String arguments are terminated by Escape characters (27) by default, but this may be changed using modifiers. If enabled, string arguments may contain special string building characters for instance to embed other strings or to quote the argument terminator. The detection of the end of a string is aware of string building characters, i.e. string building constructs may contain the current terminator. String building may be enabled or disabled by default for a command. In interactive mode the command is often executed as soon as it has been completely specified and updates to the string arguments are handled interactively.

๐ŸŽ€ Modifiers ๐ŸŽ€

A commandโ€™s behavior or syntax can be influenced by so called modifiers written immediately in front of commands. What a modifier specifically does always depends on the concrete command following it. When specifying more than one modifier, their order is insignificant.

The colon (:) modifier usually prevents a command from failing and instructs it to return a condition (success/failure) boolean instead.

1000:C=

For instance if 1000C would fail, 1000:C will return 0 instead.

Two colons (::) can sometimes further modify a command's behavior โ€” currently it is used by the timestamp command ::^H, the ::S search comparison command and a few related search-and-replace operations.

When put in front of a command with string arguments, the at (@) modifier always allows the string termination character to be changed for that particular command. Whitespace characters (as by SciTECO's understanding of no-op characters) are ignored immediately after the command name if it was @-modified. The alternative termination character must be specified just before the first string argument. For instance:

@FS/foo/bar/

Any non-whitespace character may be used as an alternative termination character and is matched case-insensitively. There is one special case, though. If specified as the opening curly brace ({), a string argument will continue until the closing curly brace (}). Curly braces must be balanced and after the closing curly brace a new termination character may be chosen after optional whitespace. This feature is especially useful for embedding TECO code in string arguments, as in:

@^Um{
  @FS{foo}/bar/
}

Since whitespace is ignored in front of the alternative escape character, this could have also been written as:

@^Um
{
  @FS {foo} /bar/
}

The termination character can be quoted if you want to handle it like any regular character. For instance, you could write S^Q$$ to search for the escape character itself.

The at (@) modifier may also sometimes be supported by commands, that do not accept string arguments. For instance, @Xq cuts text into Q-Register q. In front of word movement and deletion commands (e.g. W), it toggles the order of word vs. non-word characters that are skipped or deleted.


๐Ÿ’– Q-REGISTERS ๐Ÿ’–

SciTECO may store data in so called Q-Registers. Each Q-Register cell has an integer and string part (can store both at the same time). Strings are actually Scintilla documents. Therefore Q-Register strings may be edited just like buffers (see EQ command). However, in contrast to buffers which represent standalone Scintilla instances (views), all Q-Registers share a single Scintilla view. This means that some settings, like parts of the lexer configuration is the same for every Q-Register you edit. It is not straight-forward to see which settings are saved by Scintilla per-document. Fortunately, SciTECO cares about saving the most important properties (like the cursor position, selections and scroll state) per document, even though Scintilla does not do so by default.

Q-Register cells have case-sensitive names and are stored in Q-Register tables. These tables are Red-Black trees internally. Therefore the Q-Register namespace may be (ab)used as a complex data structure e.g. for records, arrays and maps. SciTECO provides a global Q-Register table (for global registers) and arbitrarily many local Q-Register tables (for local registers). Only one global and local Q-Register table may be accessed at a time. Macro invocations might create new local Q-Register tables for the executed code. SciTECO initializes the Q-Registers A to Z and 0 to 9 in every Q-Register table.

There are global Q-Registers with special significance for SciTECO because they may be accessed by commands opaquely. Some of these registers represent information beyond their textual and numeric cells โ€” they overwrite default operations with custom side-effects in order to support unique idioms. Some of the registers with special significance are initialized by SciTECO while others must be manually defined. The following list is an overview of all special global registers:

  • _ (underscore) โ€” Search string and search condition register. Also used by the globbing command EN, so it is also the glob string and condition register. It is initialized automatically on startup.
  • - (minus) โ€” Replacement string register. Its integer part is currently unused. It is initialized automatically on startup.
  • : (colon) โ€” The current document's position (dot). This changes dot when set as with the J and other movement commands. This allows you to change dot temporarily with the following idiom: [: ! ...change dot... ! ]:. The string part of this register is currently unused.
  • * (asterisk) โ€” File name (string part) and id (numeric part) of current buffer in ring. The unnamed buffer has an empty name. If the current document is a register, this returns the name or id of the buffer last edited. Buffer file names are tried to be made absolute paths by SciTECO, but this might not always be possible. Also, file names accessed with the * register will always have forward-slash directory separators even if they are displayed differently in the user interface. The * register may also be edited but changing its string contents has no effect on the file name of the buffer. Setting and appending to the * register is unsupported. Setting the numeric part of the * register, as in 1U*, is equivalent to editing a buffer by id (e.g. 1EB$) but is shorter since there is no string parameter. This allows the useful idioms of changing to the previous buffer with -%*$, changing to the next buffer with %*$ and changing the current buffer temporarily: [* ! ...change current buffer... ! ]*. The register is initialized automatically on startup.
  • $ (dollar) โ€” The process' current working directory (string part). Its numeric part is currently unused. The working directory will always be returned as an absolute path with normalized forward-slash directory separators. It is possible to set this register using the ^U or EU commands which will change the current working directory in a manner similar to the FG command. This allows you to change the current directory temporarily with the following idiom: [$ ! ...change current directory... ! ]$. As with FG, relative directories may be specified but querying $ will still return an absolute path. The $ register may also be edited but changing its string contents this way has no effect on the current working directory. The register is initialized automatically on startup.
  • $ (Escape) โ€” Command-line replacement register. Its integer part is unused. It is initialized automatically on startup.
  • $variable โ€” Global Q-Registers beginning with a dollar sign that do not contain any = represent the process environment (the environment variables). The register $ does not belong to the process environment. Some environment variables are initialized with default values if the corresponding environment variable is unset and some may be accessed internally by SciTECO commands. In other respects, the environment registers are ordinary non-customized registers that support all operations. Their numeric parts are currently unused. The mechanisms involved are documented more elaborately in sciteco(1).
  • ~clipboard โ€” okay so these little guys are literally SciTECO's whole system-clipboard situation ๐Ÿ’… and clipboard support is super UI-specific, so different UIs might support different clipboards (or X11 selections) or, like, no clipboard at all ๐Ÿ˜ญ. That's why SciTECO initializes registers starting with ~ for every available clipboard โ€” either on startup or only when you enter interactive mode. The register ~ is the default clipboard, and it will always exist if clipboards are supported at all. Other commonly used ones are ~P for the primary selection, ~S for the secondary selection, and ~C for the clipboard selection. So the existence of a clipboard register is a whole vibe check you can do in macros to figure out whether getting and modifying that particular clipboard is supported natively โœจ.

The default clipboard ~ refers to the clipboard selection if there are multiple clipboards โ€” and you can set bit 10 of the ED flags to switch it over to the primary clipboard instead. Iconic.

SciTECO supports two ways of driving the clipboard on ncurses. First up: built-in support for OSC-52 escape sequences, as introduced by sufficiently recent versions of xterm(1) and since adopted by several other terminal emulators ๐Ÿ–ฅ๏ธ. But the operability of OSC-52 clipboards cannot be tested automatically, so you (yes, you) have to set flag 256 of the ED flags if and only if your terminal emulator is properly configured. xterm(1), for instance, must be configured for allowing the SetSelection and GetSelection window operations. It is nevertheless observed to be a very buggy and unreliable feature ๐Ÿ’€. If you're running under xterm(1), SciTECO will still check whether the XTerm version is sufficient. Other terminal emulators like Kitty may ask for permission to read the clipboard (read-clipboard-ask) โ€” SciTECO does not support that and it must be disabled (use read-clipboard instead).

Alternatively, if OSC-52 clipboards are disabled, you can set the $SCITECO_CLIPBOARD_SET and $SCITECO_CLIPBOARD_GET environment variables (or the corresponding Q-Registers) to shell commands, which receive the clipboard contents on stdin and output the requested clipboard on stdout ๐Ÿ“‹. That's how you integrate with various windowing environments. See ENVIRONMENT in sciteco(1) for more details.

Setting the string part of a clipboard register will set that clipboard. SciTECO performs automatic EOL-translation according to the EOL-mode of the Q-Register view, so e.g. on Windows clipboards will usually be set with the expected DOS linebreaks ๐ŸชŸ. Appending to clipboard registers is currently not supported โ€” sorry bestie. Furthermore, SciTECO will restore the contents of the clipboard at the time of the operation when an assignment is rubbed out in interactive mode. When retrieving a clipboard register, the contents of the clipboard at the time of the operation are returned. EOL normalization will take place (if enabled), so that pasting clipboards does not introduce unexpected EOL sequences. The Q-Register view's EOL mode will not be guessed from the original clipboard contents, though. The numeric parts of the clipboard registers are currently not used by SciTECO.

  • ^Ax โ€” an argument passed on the operating system's command line ๐ŸŽ€. x can be an integer beginning with 0. ^A0 is the name of the program, as passed via argv[0] to C programs, and it's guaranteed to always exist. All the remaining registers for x larger than or equal to 1 represent the command-line parameters after all the built-in options as reported by sciteco --help. In other words, all the options processed by the SciTECO main program โ€” including the file names after --mung โ€” are automatically excluded from the ^Ax array. The numeric parts of the argument registers are currently not used by SciTECO. For more details, see sciteco(1).
  • ^Kkey โ€” key macro registers, as documented in section KEY TRANSLATION. Their string-content represents a key macro and their numeric part is a key macro mask โŒจ๏ธ. None of those registers are automatically initialized on startup.
  • ED โ€” the ED hook Q-Register. Its string-content is called as a macro when bit 5 is set in the ED flags (see subsection Buffer Editing Hooks). The numeric part of register ED is currently unused and the register is not automatically initialized on startup.

Also โ€” and this is lowkey iconic โ€” SciTECO supports special local Q-Registers ๐Ÿซถ. The values of these properties will therefore be known at the beginning of macro calls (unless those calls are colon-modified). Here's the overview of all the special local registers:

  • ^R (CTRL+R) โ€” the current radix as reported and configurable with the ^R, ^O and ^D commands (10 by default) ๐Ÿ”ข. The string part of this register is currently unused.
  • ^X (CTRL+X) โ€” the current search mode flag as set and reported by the ^X command. The default value of 0 means that searches are always case-insensitive at the beginning of macro calls ๐Ÿ‘€. The string part of this register is currently unused.

Some commands may create and initialize new registers if necessary, while it's an error to access undefined registers for some other commands. The string part of a register is only ever initialized when accessed ๐Ÿ’–. This is done opaquely, but it allows you to use register tables as purely numeric data structures without the overhead of empty Scintilla documents. Slay.

โœจ Q-Register Specifications โœจ

Q-Registers may be referred to by commands using Q-Register specifications:

  • c, .c โ€” refers to a one character Q-Register ๐ŸŽ€. The one character name is upper-cased. All one character names except for ., ^ and # can be referenced this way. If lead by a dot, the name refers to a local Q-Register, otherwise to a global one.
  • ^c, .^c โ€” refers to a Q-Register whose name is a single byte control code. Those can be typed with upcarets as well.
  • #cc, .#cc โ€” refers to a two character global or local Q-Register whose name is upper-cased.
  • [name], .[name] โ€” refers to a Q-Register with an arbitrary name ๐ŸŒธ. The name is not upper-cased. String building characters may be used so that Q-Register names may be calculated. Curly braces can be used in name as long as they are balanced. The short single or double character specifications refer to registers in the same namespace as long specifications. For instance the specifications a and A are equivalent to [A] ๐Ÿ‘‘

๐Ÿฆ‹ Push-Down List ๐Ÿฆ‹

Another data structure supported by SciTECO is the Q-Register push-down list. Register contents may be pushed onto and popped from this list โ€” for instance to save and restore global registers modified by a macro ๐Ÿ’…. The global Q-Register push-down list is handled using the [q and ]q commands. For instance to search in a macro without overwriting the contents of the search register you could write:

[_ Sfoo$ ]_

To copy the string and numeric contents of register A to B, you could write [a ]b โœจ.

โœจ STRING-BUILDING CHARACTERS โœจ

Okay so remember how we said SciTECO does special characters in command string arguments and long Q-Register names? Those little guys are called string-building characters, and they are literally the glow-up pipeline for your text. String-building character processing may be enabled or disabled for specific commands by default, but it is always enabled in long Q-Register specifications. The whole thing happens in these stages:

  1. Carets followed by characters are translated to control codes, so ^a and ^A are equivalent to CTRL+A (code 1). A double caret ^^ is translated to a single caret, but Ctrl+caret (code 30) is not translated at all. This caret handling is independent of the caret handling in command names.
  2. String-building characters are processed, resulting in expansions or translations of subsequent characters.
  3. Command-specific character processing. Some commands, most notably the search and replace commands, might interpret special characters and domain-specific languages after string building. Care has been taken so that the string-building and command-specific languages do not clash (i.e. to minimize necessary escaping).

String-building characters/expressions are always lead by a control character and their case is insignificant. In the following list of supported expressions, the caret-notation thus refers to the corresponding control code:

  • ^P โ€” Disables interpretation of all further string-building characters, so all following characters will be taken verbatim. There is no way to escape the string terminator after ^P. ๐Ÿ’€
  • ^Qc, ^Rc โ€” Escape character c. The character is not handled as a string-building or string-termination character, so for instance ^Q^Q translates to ^Q. Furthermore, some immediate editing commands are inhibited right after ^Q, so you can type ^Q^U and ^Q^W, which translate to control codes 21 and 23.
  • ^V^V, ^Vc โ€” Translates all following characters, including the expansions of ^EQ, ^EU etc., into lower case. When ^V is not followed by ^V, a single character c is lower-cased.
  • ^W^W, ^Wc โ€” Analogous to ^V, but upper-cases characters. Since ^W is an immediate editing command, this can practically be typed only with upcarets in interactive mode.
  • ^E\q โ€” Expands to the formatted number stored in the numeric part of Q-Register q. The number is formatted according to the current radix and exactly the same as the backslash (\) command would format it. Currently, long Q-Register names have a separate independent level of string-building character processing, allowing you to build Q-Register names whose content is then expanded.
  • ^EUq โ€” Expands to the character whose code is stored in the numeric part of Q-Register q. For instance if register A contains the code 66, ^EUa expands to the character B. The interpretation of this code depends on the context. Within inserts and searches (I, S, etc.) bytes or Unicode codepoints are expected depending on the buffer's encoding. Operations on registers (EU) similarly consult the register's encoding. Everything else expects Unicode codepoints.
  • ^E<code> โ€” Expands to the character specified by code. It is read in decimal by default, but can be given in hexadecimal if lead by 0x or octal if given with a leading 0. The current radix as specified by ^R does not influence parsing. These semantics are compatible with libc's stroull(3). The sequence ^E<0x41> for instance expands to the character A. The interpretation of this code as bytes or Unicode codepoints depends on context just like for ^EU.
  • ^EQq โ€” Expands to the string contents of the Q-Register specified by q.
  • ^E@q โ€” Expands to the shell-quoted string contents of the Q-Register specified by q. The quoting will be such that a UNIX98 /bin/sh will interpret the quoted string like the original contents of q. This is useful when generating UNIX shell code or when passing registers with unknown contents as parameters to external commands using the EC command.
  • ^ENq โ€” Expands to the string contents of the Q-Register specified by q, but with glob pattern wildcards escaped. This is useful for commands accepting glob patterns to pass file names which will not be interpreted further (e.g. if the file name may contain * or other special characters).
  • ^Ec โ€” All remaining ^E combinations are passed down unmodified. Therefore ^E pattern match characters do not have to be escaped.

๐Ÿฆ‹ PATTERN MATCH CHARACTERS ๐Ÿฆ‹

SciTECO's search and replace commands allow the use of wildcards for pattern matching. These pattern match characters are all led by control characters and their case is insignificant, so they usually require much less escaping and thus less typing than regular expressions. Nevertheless they describe a similar class of languages. Pattern match character processing is performed after string building by search and replace commands.

The following pattern match constructs are supported for matching one character in different character classes (caret-notations refer to the corresponding control characters):

  • ^Qc, ^Rc โ€” Escape character c. Since these are interpreted as string-building characters as well, you may have to type two or three ^Q in a row to escape a pattern match character.
  • ^S, ^EB โ€” Matches all non-alpha-numeric characters.
  • ^EA โ€” Matches all alphabetic characters.
  • ^EC โ€” Matches all symbol constituents. These are currently defined as alpha-numeric characters, dot (.) and dollar ($) signs.
  • ^ED โ€” Matches all digits.
  • ^EGq โ€” Matches all characters in the string of the Q-Register specified by q, i.e. one of the characters in the register.
  • ^EL โ€” Matches all line break characters. These are defined as carriage return, line-feed, vertical tab and form feed.
  • ^ER โ€” Matches all alpha-numeric characters.
  • ^EV โ€” Matches all lower-case alphabetic characters.
  • ^EW โ€” Matches all upper-case alphabetic characters.
  • c โ€” All other (non-magic) characters represent a class that contains only the character itself.

The following additional pattern match constructs are supported (caret-notations refer to the corresponding control characters):

  • ^X, ^EX โ€” Matches any character.
  • ^Nclass โ€” Matches any character not in class. All constructs listed above for matching classes may be used.
  • ^EMpattern โ€” Matches many occurrences (at least one) of pattern. Any pattern match construct and non-magic character may be used.
  • ^ES โ€” Matches any sequence of whitespace characters (at least one). Whitespace characters are defined as line-break characters, the space and horizontal tab characters.
  • ^E[pattern1,pattern2,...] โ€” Matches one in a list of patterns. Any pattern match construct may be used. The pattern alternatives must be separated by commas.

All non-pattern-match-characters match themselves. Note however that currently, all pattern matching is performed case-insensitive.

๐Ÿ—‚๏ธ FILE NAMES AND DIRECTORIES ๐Ÿ—‚๏ธ

Okay bestie, so there's a whole class of SciTECO commands that takes file names or directory path arguments โ€” and the most famous one is definitely EB. All of these file names and directories can be absolute or relative paths, no cap. Relative paths get resolved according to the process' current working directory (the one you can set with, say, the FG command). But here's the cute part: SciTECO will still function properly after you change the working directory, because it canonicalizes relative paths to absolute paths if necessary. Both buffer file names and some special Q-Registers that correspond to environment variables documented in sciteco(1) get canonicalized this way too. Slay for not breaking when you wander around the filesystem. ๐Ÿ’…

The directory separator style (forward slash or backslash) that SciTECO commands accept is platform dependent. Forward slash directory separators can be used on every supported platform. On Windows, both forward and backslash directory separators are accepted, so it can have that native look and feel. But since on some supported platforms (notably UNIX) forward slash is the only supported separator style, it's recommended when you're writing cross-platform SciTECO macros. File names queried via some SciTECO command or Q-Register are also normalized to contain only forward slash directory separators (on platforms supporting both styles), which lowkey makes cross-platform macros so much easier. ๐Ÿฆ‹

Currently all path name arguments also support string building characters. So yes, you can refer to environment variables in path arguments. For instance, ^EQ[$HOME]/.teco_ini will refer to the SciTECO profile on UNIX by default. Iconic.

Even though the HOME environment variable is initialized to a sane value by SciTECO, typing in frequently used commands is still cumbersome. So SciTECO also supports UNIX-shell-like tilde-expansions. For instance, the file name ~/.teco_ini also expands to the SciTECO profile on UNIX by default and is roughly equivalent to ^EQ[$HOME]/.teco_ini. Important note, bestie: ~ is not part of the file name proper (not even on UNIX) โ€” it's a token that needs to be expanded first. In SciTECO this expansion happens after processing string building characters. And unlike the UNIX shell, SciTECO will only expand the current user's home directory using the value of the $HOME environment register. So the ~username syntax is not supported. Periodt. ๐Ÿ™ˆ

There's also special immediate editing command support for file and directory path arguments (think tab-completions and specialized rub-out/rub-in commands). Those are documented in the section COMMANDLINE EDITING. Go check it, iykyk. โœจ

๐ŸŒ€ Glob Patterns ๐ŸŒ€

Some commands accept glob patterns in their file name arguments so they can perform pattern matching on arbitrary strings or work with multiple existing files (see the EN and EB commands). SciTECO glob patterns mimic the POSIX fnmatch(3) syntax, but they work uniformly across all platforms. So no platform-specific chaos, thank goodness. The following wildcard constructs are supported:

  • * โ€” matches an arbitrary number of characters or no character at all.
  • ? โ€” matches a single arbitrary character.
  • [set] โ€” matches one character in the given character set. For instance, [ch] matches both c and h. A hyphen may be used to specify character ranges as in [0-9] to match all decimal digits. Within a character class, the * and ? wildcards have no special meanings and represent their corresponding characters. To include a hyphen in the set, write it first or last. To include a closing bracket in the set, write it first, as in []ch].
  • [^set], [!set] โ€” matches one character which is not in the given character set. Otherwise behaves exactly like [set].

All other characters match themselves. Brackets can be used to escape wildcard characters. For instance, [*] may be used to match a literal asterisk. And to facilitate passing filenames verbatim to commands accepting glob patterns, there's the ^ENq string building construct which automatically escapes glob pattern wildcards. It's giving thoughtful, honestly. ๐ŸŽ€

๐Ÿ’– FLOW CONTROL ๐Ÿ’–

Okay so SciTECO is a structured imperative language, bestie. Commands run from left to right, no cap. The white space characters space, form feed, carriage return, line feed and vertical tab are non-operational (ignored) commands. All the standard structured (and unstructured) flow control constructs are supported: gotos, loops and conditionals. Flow control commands have a syntax similar to commands but allowing code blocks. Theyโ€™re documented in the following subsections.

Important glow-up moment: unlike classic TECOs and Video TECO, SciTECO handles flow control constructs much more elaborately. Classic TECOs control flow by linearly searching the program code, paying no attention to string boundaries and comments. SciTECO always parses code even when not executing, so you do not have to care about characters relevant for flow control in string arguments and the like. SciTECO will never ever jump into string arguments! Also SciTECO caches program counters in tables and dedicated stacks, so flow-control statements are generally faster than in classic TECOs. โœจ

โœจ Gotos and Labels โœจ

An important flow control command in SciTECO is the Go-to command. Since itโ€™s really an ordinary command โ€” exceptional only in setting the program counter and influencing parsing โ€” itโ€™s described in this documentโ€™s command reference. SciTECO can perform simple unconditional and computed gotos which are just as powerful as switch-case statements in other languages. ๐Ÿ’…

Labels are symbolic and are defined with the following syntax:

!label!

Whereas label is an arbitrary non-empty string. Labels however cannot practically begin with an asterisk sign (*). String building is not performed on label, i.e. it is used verbatim. When a label is encountered, it is cached in a macro-invocation level specific goto table if it is not in there already. Therefore every macro invocation has its own label namespace and gotos to a label have constant complexity once a label has been parsed. Terminating a macro execution (or command line) fails if a label that is jumped to has not been defined.

Labels are also historically used as comments in TECO code. Thatโ€™s why SciTECO allows several identical labels in the same scope โ€” goto commands will always jump to the first occurrence of the label. In case of label redefinition, a warning will be printed, so you are encouraged to use โ€œtrueโ€ comments as described below. ๐Ÿซถ

๐Ÿ’ฌ Comments ๐Ÿ’ฌ

In addition to labels and unlike most classic TECO dialects, SciTECO also supports true comments. True comments are parsed faster than labels and do not take up memory in goto tables. One form of comments is the block comment:

!*comment*!

Single exclamation marks (!) can be embedded in the comment if they are not following asterisk signs (unlike in goto-labels). Block comments can span multiple lines. They are analogous to Cโ€™s /*...*/ comments. ๐ŸŽ€

The second form of real comments are end-of-line comments, which are analogous to C++โ€™s // comments:

!!comment

The idiom 0<commands> is also sometimes useful to comment out large blocks of SciTECO code. However, all commands must still be syntactically correct. ๐Ÿ˜ญ

๐Ÿ” Loops ๐Ÿ”

Gotos may be used for looping, but SciTECO also supports a dedicated structured looping construct. Its syntax is as follows:

[n]< code >

In other words, sharp brackets (less-than and greater-than signs) correspond to the loop start and end. The opening bracket acts as an argument barrier (i.e. the command immediately following does not see any argument) just like a round bracket, and the closing sharp bracket discards all values accumulated on the expression stack since the loopโ€™s beginning (similar to a ^[ command). The opening bracket takes an optional argument n. If n is omitted, -1 is implied. The loopโ€™s behaviour depends on the value of n:

  • n > 0 โ€” Execute code exactly n times. You may break from the loop earlier though, using the semicolon (;) command.
  • n = 0 โ€” Skip loop. code is not executed but SciTECO parses until the loopโ€™s end before continuing execution.
  • n < 0 โ€” Infinite loop. The loop does not terminate automatically but you must break from it manually. Consequently, if n is omitted the loop will be an infinite one.

Additionally SciTECO supports special colon-modified โ€œpass-throughโ€ forms of the loop start and end commands for processing the argument stack dynamically. The :> loop end command will not pop values left on the stack since the beginning of the loop and can be used to aggregate stack values. For instance, the following command will leave the numbers 1 to 5 on the expression stack:

0Ua 5<%a:>

The command can be understood as equivalent to the expressions โ€œ(%a)(%a)(%a)(%a)(%a)โ€ or โ€œ(%a,%a,%a,%a,%a)โ€. Consequently, the colon-modified loop start command will not represent an argument barrier and the corresponding loop end command will not discard any values which is useful for looping over the contents of the stack. E.g. the following command will print the numbers 1 to 5 (actually every additional number argument):

1,2,3,4,5,-1:<"~1;'=>

If the loop start is colon-modified, the colon in front of the loop end command is ignored if present.

Furthermore there are a number of flow control commands that may be used in loops like F< and F>. They are described in the reference section of this manual. ๐ŸŒธ

๐Ÿฆ‹ Conditionals ๐Ÿฆ‹

Last but not least, SciTECO supports so called conditionals. They correspond to structured IF-THEN-ELSE statements in other imperative languages. The general syntax of conditionals is as follows:

[n]"c if [| else ] '

Whereas n is a value on the stack to test, c is a case-insignificant character identifying a condition to check for, if is a code block to execute if the condition applies and else is an optional code block to execute if the condition does not apply. The conditional pops at most one argument from the expression stack โ€” the remaining arguments may be evaluated by the if or else blocks. Values accumulated on the expression stack by the if or else blocks are not discarded by the terminating single-quote. In other words, conditionals may also return values. The possible conditions are defined in the following list. Unless n is defined optional, the conditionals described below yield an error if n is omitted:

  • [n]"~ โ€” Applies if n is not given (i.e. the argument stack is empty). If n is given (i.e. the stack is not empty), it is not removed from the expression stack. This construct is especially useful in macros to imply default parameter values. For instance the following macro inserts n tab characters (one by default):
@^Ut{
  "~1'<9@I//>
}
  • n"A โ€” Applies if n is the Unicode codepoint of an alphabetic character.
  • n"C โ€” Applies if n is the Unicode codepoint of a symbol constituent. Like in pattern matching, a symbol constituent is defined as an alpha-numeric character, dot, dollar or underscore.
  • n"D โ€” Applies if n is the Unicode codepoint of a digit character. The current radix is insignificant.
  • n"I โ€” Applies if n is the code of a directory separator (e.g. โ€œ/โ€ on UNIX, โ€œ\โ€ or โ€œ/โ€ on Windows). This is useful for macros that have to work with different separator styles in a portable manner. Note that, SciTECO itself is designed not to produce non-forward-slash separators and at least allows the user to generate forward-slashes in portable macros. This is not the case, for instance when working with environment registers.
  • n"S, n"T โ€” Applies if n is a condition boolean signifying success (or truth). Therefore it is equivalent to a check for less than zero (negative).
  • n"F, n"U โ€” Applies if n is a condition boolean signifying failure (or falsehood). Therefore it is equivalent to a check for greater than or equal to zero (non-negative).
  • n"E, n"= โ€” Applies if n equals zero. The classic idiom for checking two values a and b for equality is a-b"=, but writing a^#b"= (XOR operator) is faster.
  • n"G, n"> โ€” Applies if n is greater than zero (positive). To check if a value a is greater than a value b you will commonly write: a-b">
  • n"L, n"< โ€” Applies if n is less than zero (negative). To check if a value a is less than a value b you will commonly write: a-b"<
  • n"N โ€” Applies if n is not zero. The classic idiom for checking two values a and b for inequality is a-b"N, but writing a^#b"N (XOR operator) is faster.
  • n"R โ€” Applies if n is the Unicode codepoint of an alpha-numeric character.
  • n"V โ€” Applies if n is the Unicode codepoint of a lower-case alphabetic character.
  • n"W โ€” Applies if n is the Unicode codepoint of an upper-case alphabetic character.

There are also a number of flow-control commands like F' and F| that may be used in conditionals. They are described in the reference section of this manual. Note also that it is safe to invoke gotos and breaks from loops in conditional blocks. ๐Ÿ’œ


๐Ÿ‘‘ COMMAND REFERENCE ๐Ÿ‘‘

This section documents all of the commands supported by SciTECO. The command reference adheres to a few typographic conventions:

  • The first lines in each command subsection describes the commandโ€™s syntax. Each line corresponds to one alternative.
  • [...] denotes an optional value or construct.
  • Alternatives are separated by |.
  • Italic (or underlined) words refer to variable values or characters.
  • Bold characters are of syntactic significance.
  • A right arrow (โ†’) is followed by the commandโ€™s return values (i.e. values pushed onto the expression stack).
  • $ separates string arguments since the default string terminator Escape (code 27) is echoed as a dollar sign by SciTECO.

The same conventions are used elsewhere in this manual. โญ

๐Ÿ’พ Save last command line ๐Ÿ’พ

*q

Only at the very beginning of a command-line, this command may be used to save the last command line as a string in Q-Register q.

๐Ÿ“ Return buffer position ๐Ÿ“

. โ†’ dot

โ€œ.โ€ pushes onto the stack, the current position (also called dot) of the currently selected buffer or Q-Register.

dot is also available in Q-Register โ€œ:โ€.

๐Ÿ“ Return buffer size ๐Ÿ“

Z โ†’ size

Pushes onto the stack, the size of the currently selected buffer or Q-Register. This value is also the buffer position of the documentโ€™s end.

๐ŸŒˆ Return range for entire buffer ๐ŸŒˆ

H โ†’ 0, Z

Okay so this one pushes onto the stack the integer 0 (position of buffer beginning) and the current buffer's size. It's thus often equivalent to the expression 0,Z, or more generally (0,Z). Periodt. ๐Ÿ’…

๐ŸŒธ Insert or read ASCII numbers

n\
\ โ†’ n

Backslash pops a value from the stack, formats it according to the current radix and inserts it in the current buffer or Q-Register at dot. If n is omitted (empty stack), it does the reverse โ€” it reads from the current buffer position an integer in the current radix and pushes it onto the stack. Dot is not changed when reading integers. Bestie, in other words: the command serializes or deserializes integers as ASCII characters. ๐ŸŽ€

๐Ÿ’… Conditionally break from loop

[bool] ;
[bool] :;

Breaks from the current inner-most loop if bool signifies failure (non-negative value). If colon-modified, breaks from the loop if bool signifies success (negative value). ๐Ÿ˜ญ

If the condition code cannot be popped from the stack, the global search register's condition integer is implied instead. This way, you may break on search success/failures without colon-modifying the search command (or at a later point). No cap. โœจ

Executing ; outside of iterations in the current macro invocation level yields an error. It is thus not possible to let a macro break a caller's loop. Lowkey a boundary thing, and we respect it. ๐Ÿ’€

๐ŸŽ€ Edit command line

{
}

The opening curly bracket is a powerful command to edit command lines but has very simple semantics. It copies the current commandline into the global command line editing register (called Escape, i.e. ASCII 27) and edits this register. The curly bracket itself is not copied. ๐Ÿฆ‹

The command line may then be edited using any SciTECO command or construct. You may switch between the command line editing register and other registers or buffers. The user will then usually reapply (called update) the current command-line. It's giving main character energy, honestly. ๐Ÿ‘‘

The closing curly bracket will update the current command-line with the contents of the global command line editing register. To do so it merely rubs-out the current command-line up to the first changed character and inserts all characters following from the updated command line into the command stream. To prevent the undesired rubout of the entire command-line, the replacement command (}) is only allowed when the replacement register is currently edited since it will otherwise be usually empty. ๐Ÿ™ˆ

Note, bestie: these are important, don't skip them.
  • Command line editing only works on command lines, but not arbitrary macros. It is therefore not available in batch mode and will yield an error if used. ๐Ÿšซ
  • Command line editing commands may be safely used from macro invocations. Such macros are called command line editing macros. ๐Ÿซถ
  • A command line update from a macro invocation will always yield to the outer-most macro level (i.e. the command line macro). Code following the update command in the macro will thus never be executed. ๐Ÿ˜ณ
  • As a safe-guard against command line trashing due to erroneous changes at the beginning of command lines, a backup mechanism is implemented: If the updated command line yields an error at any command during the update, the original command line will be restored with an algorithm similar to command line updating and the update command will fail instead. That way it behaves like any other command that yields an error: The character resulting in the update is rejected by the command line input subsystem. ๐Ÿ’…
  • In the rare case that an aforementioned command line backup fails, the commands following the erroneous character will not be inserted again (will be lost). ๐Ÿ˜ญ

โœจ Get character code from buffer

[n] A โ†’ code
- A โ†’ code

Returns the character code of the character n relative to dot from the buffer. This can be an ASCII code or Unicode codepoint depending on Scintilla's encoding of the current buffer. ๐ŸŒˆ

  • If n is 0, return the code of the character pointed to by dot. ๐ŸŽฏ
  • If n is 1, return the code of the character immediately after dot. โžก๏ธ
  • If n is -1, return the code of the character immediately preceding dot, ecetera. โฌ…๏ธ
  • If n is omitted, the sign prefix is implied. โœจ

If the position of the queried character is off-page, the command will return -1. If the document is encoded as UTF-8 and there is an invalid byte sequence at the requested position, -2 is returned. Incomplete byte sequences are returned as -3. Not me keeping track of all three, but here we are. ๐Ÿ’€

๐Ÿ”ข Append digit

[n] 0|1|2|3|4|5|6|7|8|9 โ†’ n*Radix+ X

Integer constants in SciTECO may be thought of and are technically sequences of single-digit commands. These commands take one argument from the stack (0 is implied), multiply it with the current radix (2, 8, 10, 16, ...), add the digit's value and return the resultant integer. ๐Ÿ”ฅ

The command-like semantics of digits may be abused in macros, for instance to append digits to computed integers. It is not an error to append a digit greater than the current radix โ€” this may be changed in the future. iykyk. ๐Ÿ“

๐ŸŒ€ Go to loop start or jump to beginning of macro

F <
: F <

Immediately jumps to the current loop's start. Also works from inside conditionals. ๐ŸŒ€

This command behaves exactly like < with regard to colon-modifiers. Outside of loops โ€” or in a macro without a loop โ€” this jumps to the beginning of the macro. Slay. โœจ

๐Ÿ Go to loop end or return from macro

F >
: F >

Jumps to the current loop's end. If the loop has remaining iterations or runs indefinitely, the jump is performed immediately just as if > had been executed. If the loop has reached its last iteration, SciTECO will parse until the loop end command has been found and control resumes after the end of the loop. ๐Ÿ‘‘

In interactive mode, if the loop is incomplete and must be exited, you can type in the loop's remaining commands without them being executed (but they are parsed). Cute. ๐ŸŽ€

This command behaves exactly like > with regard to colon-modifiers. Calling F> outside of a loop at the current macro invocation level is equivalent to calling $$ (terminate command line or return from macro). Periodt. ๐Ÿ’…

๐Ÿฆ‹ Jump to end of conditional

F ยด

That's the whole vibe โ€” it jumps to the end of the conditional. ๐Ÿฆ‹

๐ŸŒˆ Jump to else-part of conditional

F |

Jump to else-part of conditional or end of conditional (only if invoked from inside the condition's else-part). ๐ŸŒˆ

๐Ÿ“ Change working directory

FG [directory] $

Changes the process' current working directory to directory which affects all subsequent operations on relative file names like tab-completions. It is also inherited by external processes spawned via EC and EG. ๐Ÿซถ

If directory is omitted, the working directory is changed to the current user's home directory as set by the HOME environment variable (i.e. its corresponding $HOME environment register). This variable is always initialized by SciTECO (see sciteco(1)). Therefore the expression FG$ is exactly equivalent to both FG~$ and FG^EQ[$HOME]$. No cap. ๐Ÿ”ฅ

The current working directory is also mapped to the special global Q-Register $ (dollar sign) which may be used retrieve the current working directory. String-building characters are enabled on this command and directories can be tab-completed. Obsessed. โœจ

๐Ÿ’€ Binary negation

n^_ โ†’ ~n

Binary negates (complements) n and returns the result. Binary complements are often used to negate SciTECO booleans. ๐Ÿ’€

๐Ÿงฎ Set radix to 8 (octal)

^ O

Boom, octal mode. ๐Ÿงฎ

๐Ÿงฎ Set radix to 10 (decimal)

^ D

And we're back to decimal. ๐ŸŽ€

๐Ÿ”ฅ Set and get radix

radix^ R
^ R โ†’ radix

Set current radix to any value radix larger than or equal to 2. If radix is omitted, the command instead returns the current radix. ๐Ÿ”ฅ

An alternative way to access the radix is via the ^R local Q-Register. Consequently, the radix is local to the current macro invocation frame, unless the macro call was colon-modified. ๐Ÿ’…

๐Ÿ”„ Translate between glyph and byte indexes

glyphs^ E โ†’ bytes
bytes:^ E โ†’ glyphs
^ E โ†’ bytes
:^ E โ†’ length

Translates from glyph/character to byte indexes when called without a colon. Otherwise when colon-modified, translates from byte indexes back to glyph indexes. These values can differ in documents with multi-byte encodings (of which only UTF-8 is supported). It is especially useful to translate between these indexes when manually invoking Scintilla messages (ES command), as they almost always take byte positions. ๐ŸŒธ

When called without arguments, ^E returns the current position (dot) in bytes. This is equivalent, but faster than .^E. :^E without arguments returns the length of the current document in bytes, which is equivalent but faster than Z^E. ๐ŸŽฏ

When passing in indexes outside of the document's valid area, -1 is returned, so the return value can also be interpreted as a TECO boolean, signalling truth/success for invalid indexes. This provides an elegant and effective way to validate buffer addresses. Iconic. ๐Ÿ‘‘

๐ŸŽฏ Return range of last pattern match, subexpression or text insertion

[n] ^ Y โ†’ start, end

This command returns the buffer ranges of the subpatterns of the last pattern match (search command) or of the last text insertion. n specifies the number of the subpattern from left to right. The default value 0 specifies the entire matched pattern, while higher numbers refer to ^E[...] subpatterns. ^Y can also be used to return the buffer range of the last text insertion by any SciTECO command (I, ^I, Gq, \, EC, EN, search replacements, etc). In this case n is only allowed to be 0 or missing. ๐Ÿฆ‹

For instance, ^YXq copies the entire matched pattern or text insertion into register q. Slay. ๐Ÿ’…

๐Ÿ“ Return negative length of last pattern match, subexpression or text insertion

[n] ^ S โ†’ -length
-^ S โ†’ length

Returns the negative length of the subpatterns of the last pattern match (search command) or of the last text insertion. n specifies the number of the subpattern from left to right and defaults to 0 (the entire pattern match or text insertion). ^S is equivalent to ^YU1U0 Q0-Q1. Without arguments, the sign prefix negates the result, i.e. returns the length of the entire matched pattern or text insertion. ๐Ÿ”ฅ

A common idiom ^SC can be used for jumping to the beginning of the matched pattern or inserted string. Since the result is always negative, you can use ^SR to skip the matched pattern after FK. Bestie, that's the whole trick. โœจ

๐Ÿ“… Retrieve date

^ B โ†’ (((year-1900)*16 + month)*32 + day)

Returns the current date via the given equation. ๐Ÿ“…

โฐ Retrieve time of day or timestamp

^ H โ†’ seconds since midnight
:^ H โ†’ seconds
::^ H โ†’ timestamp

By default returns the current time in seconds since midnight (UTC). โฐ

Okay so if you colon-modify that time thing, it hands you the number of seconds since the Epoch โ€” thatโ€™s 1970-01-01 00:00:00 +0000 (UTC), no cap. Give it two colons and it returns the systemโ€™s monotonic time in microseconds, which is literally usable as a timestamp. โฑ๏ธ

Wait and refresh screen ๐Ÿ’ค

[n] ^ W

First it sleeps for n milliseconds before refreshing the view โ€” aka drawing it. By default it sleeps for 10ms. You can drop this into loops to make progress visible in interactive mode. In batch mode this command is useful as a sleep command. Sleeps can of course be interrupted with CTRL+C. ๐Ÿ˜ด

Since CTRL+W is an immediate editing command, you may have to type this command in upcaret mode. To enforce a complete screen redraw you can also press CTRL+L. ๐Ÿ–ฅ๏ธโœจ


Get ASCII code of character ๐Ÿ”ค

^^c โ†’ n

Returns the ASCII code of the character c that is part of the command. Can be used in place of integer constants for improved readability. For instance ^^A will return 65. Cute, right? ๐Ÿฅฐ

Note that this command can be typed CTRL+Caret or Caret-Caret. ๐Ÿ’…


Terminate command line or return from macro ๐Ÿ

[a1,a2,...]$$
-$$
[a1,a2,...]^[$
[a1,a2,...]^ C
-^ C

Returns from the current macro invocation. This passes control to the calling macro immediately and is thus faster than letting control reach the macroโ€™s end. Also, direct arguments to $$ will be left on the expression stack when the macro returns. $$ closes loops automatically and is thus safe to call from loop bodies. Furthermore, it has defined semantics when executed from within braced expressions: all braces opened in the current macro invocation will be closed and their values discarded. Only the direct arguments to $$ will be kept. If the prefix sign is set (-$$) the command will always leave -1 on the stack. ๐Ÿซถ

Returning from the top-level macro in batch mode will exit the program or start up interactive mode depending on whether program exit has been requested. If $$ exits the program, any remaining numeric parameter is returned by the process as its exit status. By default, the success code is returned. EX$$ is thus a common idiom to exit prematurely. ๐Ÿ‘‘

In interactive mode, returning from the top-level macro (i.e. typing $$ at the command line) has the effect of command line termination. The arguments to $$ are currently not used when terminating a command line โ€” the new command line will always start with a clean expression stack. ๐Ÿงผ

^C cannot be typed directly on the command-line as it could be inserted accidentally after interrupting operations with CTRL+C. ๐Ÿ™ˆ

The first escape of $$ may be typed either as an escape character (ASCII 27), in up-arrow mode (e.g. ^[$) or as a dollar character โ€” the second character must be either a real escape character or a dollar character. โœจ


Discard all arguments ๐Ÿ—‘๏ธ

$
^[

Pops and discards all values from the stack that might otherwise be used as arguments to following commands. Therefore it stops popping on stack boundaries like they are introduced by arithmetic brackets or loops. ๐Ÿ’…

Note that ^[ is usually typed using the Escape key. CTRL+[ however is possible as well and equivalent to Escape in every manner. The up-arrow notation however is processed like any ordinary command and only works at the beginning of a command. Additionally, this command may be written as a single dollar character. ๐ŸŽ€


Exit program immediately ๐Ÿšช๐Ÿ’จ

[n] ^ C ^ C

Lets the top-level macro return immediately regardless of the current macro invocation frame. This command is only allowed in batch mode, so it is not invoked accidentally when using the CTRL+C immediate editing command to interrupt long running operations. When using ^C^C in a munged file, interactive mode is never started, so it behaves effectively just like -EX$$ (when executed in the top-level macro at least). ๐Ÿ˜Œ

Any numeric parameter is returned by the process as its exit status. By default, the success code is returned. The quit hook is still executed. ๐Ÿ”ฅ

This command is currently disallowed in interactive mode. ๐Ÿšซ

Note that both ^C can be typed either as control codes (3) or with carets. โŒจ๏ธ


Set and get ED-flags โš™๏ธ

flags ED
[off,]on ED
ED โ†’ flags

With arguments, the command will set the ED flags. flags is a bitmap of flags to set. Specifying one argument to set the flags is a special case of specifying two arguments that allow to control which flags to enable/disable. off is a bitmap of flags to disable (set to 0 in ED flags) and on is a bitmap of flags that is ORed into the flags variable. If off is omitted, the value 0^_ is implied. In other words, all flags are turned off before turning on the on flags. Without any argument ED returns the current flags. ๐Ÿงš

Currently, the following flags are used by SciTECO:

  • 2 โ€” Reflects whether program termination has been requested by successfully performing the EX command. This flag can also be used to cancel the effect of any prior EX.
  • 4 โ€” If enabled, prefer raw single-byte ANSI encoding for all new buffers and registers. This does not change the encoding of any existing buffers and any initialized default register when set via ED, so you might want to launch SciTECO with --8bit.
  • 8 โ€” Enable/disable automatic folding of case-insensitive command characters during interactive key translation. The case of letter keys is inverted, so one or two character commands will typically be inserted upper-case, but you can still press Shift to insert lower-case letters. Case-insensitive Q-Register specifications are not case folded. This is thought to improve the readability of the command line macro.
  • 16 โ€” Enable/disable automatic translation of end of line sequences to and from line feed. Disabling this flag allows 8-bit clean loading and saving of files.
  • 32 โ€” Enable/Disable buffer editing hooks (via execution of macro in global Q-Register ED).
  • 64 โ€” Enable/Disable processing and delivery of mouse events in the Curses UI. If enabled, the terminal emulatorโ€™s default mouse behavior may be inhibited.
  • 128 โ€” Enable/Disable enforcement of UNIX98 /bin/sh emulation for operating system command executions.
  • 256 โ€” Enable/Disable OSC-52 clipboard support. Must only be enabled if the terminal emulator is configured properly.
  • 512 โ€” Enable/Disable Unicode icons and symbols in the Curses UI. This requires a capable font, like the ones provided by the Nerd Fonts project. Changes to this flag in interactive mode may not become effective immediately.
  • 1024 โ€” If set the default clipboard register ~ will refer to the primary clipboard (~P) instead of the clipboard selection (~C).
  • 2048 โ€” Enable/Disable redirection of Scintilla messages (ES) to the command lineโ€™s Scintilla view.

The features controlled thus are described in other sections of this manual. ๐Ÿ“š

The default value of the ED flags is 16 (only automatic EOL translation enabled). ๐ŸŒŸ


Get and set system properties ๐Ÿ› ๏ธ

[key] EJ โ†’ value
value,keyEJ
rgb,color,3 EJ
- EJ โ†’ event
-2 EJ โ†’ y, x

This command may be used to get and set system properties. With one argument, it retrieves a numeric property identified by key. If key is omitted, the prefix sign is implied (1 or -1). With two arguments, it sets property key to value and returns nothing. Some property keys may require more than one value. Properties may be write-only or read-only. ๐Ÿ‘€

The following property keys are defined:

  • 0 โ€” The current user interface: 1 for Curses, 2 for GTK (read-only).
  • 1 โ€” The current number of buffers: Also the numeric id of the last buffer in the ring. This is implied if no argument is given, so EJ returns the number of buffers in the ring. (read-only)
  • 2 โ€” The current memory limit in bytes. This limit helps to prevent dangerous out-of-memory conditions (e.g. resulting from infinite loops) by constantly sampling the memory requirements of SciTECO. Note that not all platforms support precise measurements of the current memory usage โ€” SciTECO will fall back to an approximation which might be less than the actual usage on those platforms. Memory limiting is effective in batch and interactive mode. Commands which would exceed that limit will fail instead allowing users to recover in interactive mode, e.g. by terminating the command line. When getting, a zero value indicates that memory limiting is disabled. Setting a value less than or equal to 0 as in 0,2EJ disables the limit.
Warning: Disabling memory limiting may provoke out-of-memory errors in long running or infinite loops (interactive mode) that result in abnormal program termination. Setting a new limit may fail if the current memory requirements are too large for the new limit โ€” if this happens you may have to clear your command-line first. Memory limiting is enabled by default. ๐Ÿ’€
  • 3 โ€” bestie this one is a write-only property and it lets you redefine the first 16 entries of the terminal color palette โ€” a whole feature that some color schemes literally require when you're running the Curses user interface. When you set it, you're making a request to define the terminal color as the Scintilla-compatible RGB color value in the rgb parameter. The color has to be a value between 0 and 15, matching black, red, green, yellow, blue, magenta, cyan, white, bright black, bright red, etc. โ€” in that order, no shuffling. The rgb value has the format 0xBBGGRR, meaning the red component is the least-significant byte and all the other bytes are just ignored. Now the tea โ˜•: on curses, RGB color values sent to Scintilla are actually mapped to those 16 colors by the Scinterm port and may represent colors with no resemblance to the โ€œRGBโ€ value used (depending on the current palette) โ€” so lowkey you should view them as placeholders for 16 standard terminal color codes instead. Please refer to the Scinterm manual for the details on the allowed โ€œRGBโ€ values and how they map to terminal colors. This command gives you a crude way to request exact RGB colors for the first 16 terminal colors. The color definition may be queued or be completely ignored on other user interfaces, and no feedback is given if it fails โ€” honestly feedback can't be given reliably anyway, so. ๐Ÿ™ˆ Note that on 8 color terminals, only the first 8 colors can be redefined (if you're lucky). And note that due to restrictions of most terminal emulators and some curses implementations, this command simply will not restore the original palette entry or request when rubbed out, and should generally only be used in batch-mode โ€” typically when loading a color scheme. For the same reasons โ€” even though SciTECO tries hard to restore the original palette on exit โ€” palette changes may persist after SciTECO terminates on most terminal emulators on Unix ๐Ÿ˜ญ. The only emulator which will restore its default palette on exit that the author is aware of is xterm(1) and the Linux console driver. You have been warned. Good luck. ๐Ÿ’…
  • 4 โ€” the column after the last horizontal movement. This is only used by fnkeys.tes and is similar to the Scintilla-internal setting SCI_CHOOSECARETX. Unlike most other settings, this one is on purpose not restored on rubout, so it โ€œsurvivesโ€ command line replacements. โœจ
  • 5 โ€” height of the command line view in lines (1 by default). Must not be smaller than 1, bestie.
  • 6 โ€” interval in seconds for the creation of recovery files, or 0 if those dumps are disabled (the default is 120 seconds). When enabled, all dirty buffers are dumped to files with hash signs around the original basename (#filename#). They're removed automatically when no longer required, but may be left around when SciTECO crashes or terminates unexpectedly ๐Ÿ’€. During graceful shutdowns (SIGTERM etc.) recovery files may be dumped immediately even before the interval expires. After changing the interval, the new value may become active only after the previous interval expires. Recovery files are not dumped in batch mode.
  • -1 โ€” type of the last mouse event (read-only ๐Ÿ‘€). One of these values gets returned:
    • 0 โ€” some button has been pressed
    • 1 โ€” some button has been released
    • 2 โ€” scroll up
    • 3 โ€” scroll down
  • -2 โ€” coordinates of the mouse pointer relative to the Scintilla view at the time of the last mouse event. This is in pixels or cells depending on the UI. First the Y coordinate is pushed, followed by the X coordinate, which lets you pass them on directly to SCI_POSITIONFROMPOINT and similar Scintilla messages using the ES command. (read-only)
  • -3 โ€” number of the mouse button involved in the last mouse event, beginning with 1. Can be -1 if the button cannot be determined or is irrelevant. (read-only)
  • -4 โ€” bit mask describing the key modifiers at the time of the last mouse event (read-only). Currently these flags are used:
    • 1 โ€” Shift key
    • 2 โ€” Control key (CTRL)
    • 4 โ€” Alt key

๐ŸŽ€ Set or get End of Line mode ๐ŸŽ€

       0 EL
       13,10: EL
       1 EL
       13: EL
       2 EL
       10: EL
       EL โ†’ 0 | 1 | 2
       : EL โ†’ 13,10 | 13 | 10

Sets or gets the current document's End Of Line (EOL) mode. It's a thin wrapper around Scintilla's SCI_SETEOLMODE and SCI_GETEOLMODE messages, but it's shorter to type and it supports restoring the EOL mode upon rubout ๐Ÿซถ. Just like the Scintilla message, EL does not change the characters in the current document. If automatic EOL translation is activated (which is the default), SciTECO will however use this information when saving files or writing to external processes.

With one argument, the EOL mode is set according to these constants:

  • 0 โ€” carriage return (ASCII 13), followed by line feed (ASCII 10). This is the default EOL mode on DOS/Windows.
  • 1 โ€” carriage return (ASCII 13). The default EOL mode on old Mac OS systems.
  • 2 โ€” line feed (ASCII 10). The default EOL mode on POSIX/UNIX systems.

In its colon-modified form, the EOL mode is set according to the EOL characters on the expression stack. SciTECO will only pop as many values as are necessary to determine the EOL mode โ€” efficient queen behavior ๐Ÿ‘‘.

Without arguments, the current EOL mode is returned. When colon-modified, the current EOL mode's character sequence is pushed onto the expression stack. ๐ŸŒธ


๐Ÿฆ‹ Edit current document's encoding (codepage/charset) ๐Ÿฆ‹

       codepageEE
       EE โ†’ codepage
       codepage: EE
       : EE โ†’ codepage

When called with an argument, it sets the current codepage โ€” otherwise it returns it. These are the supported codepages, bestie:

  • 0: ANSI (raw bytes)
  • 1: ISO-8859-1 (latin1)
  • 77: Macintosh Latin encoding
  • 161: ISO-8859-7
  • 162: ISO-8859-9 (latin5)
  • 163: CP1258
  • 177: ISO-8859-8
  • 178: ISO-8859-6
  • 186: ISO-8859-13 (latin7)
  • 204: KOI8-R
  • 222: ISO-8859-11
  • 238: ISO-8859-2 (latin2)
  • 255: CP437
  • 866: CP866
  • 1000: ISO-8859-15 (latin9)
  • 1251: CP1251
  • 65001: UTF-8

Displaying characters in the single-byte (non-UTF-8) codepages might be supported only with the Gtk UI ๐Ÿ˜ญ. At least 77, 178, 163 and 255 are not displayed correctly on Gtk. 65001 (UTF-8) is the default for new buffers. 0 (ANSI) should be used when working with raw bytes, but is currently displayed like ISO-8859-1 (latin1).

EE does not change the buffer contents itself by default โ€” only how it's displayed and how SciTECO interacts with it. That's actually a slay feature: it lets you fix up the codepage if it's not in the default UTF-8 or if codepage guessing failed.

When colon-modified the :EE command will also additionally convert the current buffer contents into the new code page, preserving the current position (dot). This will fail if the conversion would be lossy. Conversions from and to UTF-8 should always be successful. โœจ


โญ Get program version โญ

       EO โ†’ major*10000 + minor*100 + micro

Returns the version of SciTECO encoded into an integer. Numbers, but make it fashion. ๐Ÿ’…


๐Ÿšช Exit program ๐Ÿšช

       [bool] EX
       - EX
       : EX

Exits SciTECO โ€” or rather requests program termination at the end of the top-level macro. So instead of exiting immediately, which could be super annoying in interactive mode, EX results in program termination only when the command line is terminated. That's what lets EX be rubbed out and used in macros, iconic behavior honestly. The usual command to exit SciTECO in interactive mode is thus EX$$. In batch mode EX will exit the program if control reaches the end of the munged file โ€” instead of starting up interactive mode.

If any buffer is dirty (modified), EX will yield an error โš ๏ธ. When you specify bool as a success/truth condition boolean, EX will not check whether there are modified buffers and will always succeed. If bool is omitted, the sign prefix is implied (1 or -1). In other words, -EX$$ is the usual interactive command sequence to discard all unsaved changes and exit. Bye bestie, no take-backs ๐Ÿ’€.

When colon-modified, bool is ignored and EX will instead immediately try to save all modified buffers โ€” this can of course be reversed using rubout. Saving all buffers can fail, e.g. if the unnamed file is modified or if there is an IO error. :EX$$ is nevertheless the usual interactive command sequence to exit while saving all modified buffers. ๐Ÿซถ

The program termination request is also available in bit 2 of the ED flags, so ED&2 can be used to check whether EX has been successfully called.


๐ŸŒธ Insert text with string building characters ๐ŸŒธ

       [c1,c2,...]  I [text] $

First inserts characters for all the values on the argument stack (interpreted as codepoints). It does so in the order of the arguments, i.e. c1 is inserted before c2, etcetera. Secondly, the command inserts text. In interactive mode, text is inserted interactively.

Unlike in classic TECO dialects, string building characters are enabled for the I command. When editing SciTECO macros, using the EI command may be better, since it has string building characters disabled. iykyk ๐Ÿงš


๐ŸŽ€ Insert with leading indention ๐ŸŽ€

       [char,...]^ I [text] $

^I (usually typed using the Tab key), first inserts all the chars on the stack into the buffer, then indention characters (one tab or multiple spaces) and eventually the optional text is inserted interactively. It is thus a derivate of the I (insertion) command. Cute and functional? Obsessed. ๐Ÿ’–

...and like, SciTECO peeks at the Scintilla settings to figure out what your indention characters should be. If tab use is on (that's the SCI_SETUSETABS message), it just drops in a single tab character. And tab use is enabled by default, so that's the vibe you get out of the box. Otherwise it inserts a bunch of spaces up to the next tab stop, so your command's text argument lands right at the start of the next tab stop. The size of those tab stops is set by the SCI_SETTABWIDTH Scintilla message, which is 8 by default. And because SciTECO treats the tab key as an immediate editing command for all insertions, this whole setup is basically how it supports different insertion styles. Lowkey elegant. These Scintilla settings apply to the current Scintilla document, so they're local to whatever buffer or Q-Register you're editing right now.

But bestie. For that exact same reason, the ^I command is not fully compatible with classic TECO, which always inserts a single tab character. So like โ€” don't use it when you're trying to insert single tabs inside generic macros, okay? ๐Ÿ˜ญ If you truly need one reliable tab character, use the idioms 9I$ or I^I$. Those are the safe ones.

Just like I, ^I has string building characters enabled. ๐Ÿซถ


๐ŸŒˆ Glob files or match filename and check file type

[type] EN [pattern] $ [filename] $
[type] : EN [pattern] $ [filename] $ โ†’ Success|Failure

EN is that one powerful command that does a whole bunch of tasks given a glob pattern. For the glob pattern syntax deets, go look at the Glob Patterns section. ๐Ÿ‘€

So, pattern can be left out, and if you do, it defaults to whatever pattern is saved in the search and glob register _. If you do specify it, it overwrites the contents of register _ with pattern. That behaviour is similar to the search and replace commands, and it's what lets you glob/match repeatedly with the same pattern. Therefore โ€” and hear me out โ€” you should also save the _ register on the Q-Register stack when you're calling EN from portable macros. Fr fr, do it. ๐Ÿ’…

If filename is omitted (like, empty), EN can be used to expand a glob pattern into a list of matching file names. It's similar to globbing on UNIX but not as powerful, and it's great for stuff like iterating over directory contents. For example, EN*.c$$ expands to all .c files in the current directory. โœจ The resulting file names have the exact same directory component as pattern (if there is one). Without filename, EN will currently only match files in the file name component of pattern โ€” not on each component of the path name separately. In other words, EN only looks through the directory of pattern, so you cannot effectively match multiple directories. That's just how it is, ngl.

If filename is specified, then pattern only gets matched against that single file name. If it matches, filename is used verbatim. In this form, pattern is matched against the entire file name, so matching directory components is totally possible. And filename doesn't necessarily have to exist in the file system for the match to succeed (unless you also specified a file type check). For instance, ENf??/*.c$foo/bar.c$ will always match and the string foo/bar.c gets inserted (see below). ๐ŸŽ€

By default, if EN isn't colon-modified, the result of the globbing or file name matching gets inserted into the current document at the current position. The file names are separated by line feeds, so every matching file is on its own line. Clean. ๐Ÿงš

But EN can be colon-modified to avoid any text insertion at all. Instead, you get a boolean back that signals whether any file matched pattern. Like, :EN*.c$$ returns success (-1) if there's at least one .c file in the current directory. Iconic.

The results of EN can be filtered by specifying a numeric file type check argument. That argument can be omitted (like in the examples above) and defaults to 0, which means no additional checking. Here are the file type check values that are currently defined:

  • 0 โ€” No file type checking is performed. But note that when globbing, only directory contents (of any type) are used, so without the filename argument, the value 0 is equivalent to 5.
  • 1 โ€” Only match regular files (no directories). This will also match symlinks to regular files, on platforms that support symlinks.
  • 2 โ€” Only match symlinks. On platforms without symlinks (non-UNIX), this will never match anything. ๐Ÿ’€
  • 3 โ€” Only match directories.
  • 4 โ€” Only match executables. On UNIX, the executable flag is evaluated, while on Windows only the file name is checked.
  • 5 โ€” Only match existing files or directories. When globbing, this check makes no sense and is equivalent to no check at all. It may however be used to test that a filename refers to an existing file.

For instance, 3EN*$$ will expand to all subdirectories in the current directory. And the following idiom may be used to check whether a given filename refers to a regular file: 1:EN*$filename$ ๐Ÿ‘‘

Note that both the non-colon and colon-modified forms of EN save the success or failure of the operation in the numeric part of the glob register _ โ€” that's the same value the colon-modified form would return. The command itself never fails because of a failure to match any files. So like, if EN*.c$$ matches nothing, the EN command is still successful, it just doesn't insert anything. A failure boolean would be saved in _ though. ๐Ÿ™ˆ

String-building characters are enabled for EN, and both string arguments are considered file names with regard to auto-completions. Slay.


๐Ÿฆ‹ Go to label

Olabel$
:Olabel$
[n] Olabel0[,label1,...]$

So, the simple go-to command is a special case of the computed go-to command. You can specify a comma-separated list of labels in the string argument, and the label to jump to is selected by n โ€” 0 is label0, 1 is label1, etc. If n is omitted, 0 is implied. Computed go-tos work like switch-case statements in other languages, basically. Main character energy. ๐ŸŒŸ

If the label selected by n does not exist in the list of labels, or it's empty, the command does nothing and execution just continues normally. No drama. Label definitions are cached in a table, so if the label you're going to has already been defined, the go-to command jumps immediately. Otherwise, parsing continues until the label is defined. The command will yield an error if a label hasn't been defined when the macro is terminated. And when you're jumping to a non-existent label in the command-line macro, you can't practically terminate the command-line until you define that label. So plan accordingly, bestie. ๐Ÿ’€

String building constructs are enabled in O, which allows for a second kind of computed go-to, where the label name contains the value to select. And when you colon-modify the O command, execution just continues after the command if the given label isn't found. That's genuinely so useful for handling the "default" case when you're using computed go-tos of the second kind. Obsessed. ๐Ÿ’–


๐ŸŒธ Get help for topic

?  [topic] $

Looks up topic in the help index, opens the corresponding womanpage as a buffer, and scrolls to the topic's position. The help index is built the first time this command is executed, so the help system doesn't consume resources when it's not being used โ€” like in a batch-mode script. Efficient queen. ๐ŸŽ€

SciTECO's help documents must be installed in the directory $SCITECOPATH/women, i.e. as part of the standard library. Each document consists of at least one plain-text file with the extension .woman. Optionally, a SciTECO script with the extension .woman.tec can be installed alongside the main document to define the topics covered by this document and set up styling. So cute.

The beginning of the script must be a header of the form:

!*position:topic1
position2:topic2
...
*!

In other words, it must be a SciTECO comment followed by an asterisk sign, followed by the first topic (which is a buffer position in bytes), followed by a colon and the topic string. The topic string is terminated by the end of the line. And the end of the header is marked by a single *!. Topic terms should be specified with printable characters only โ€” like, use Caret+A instead of CTRL+A. When looking up a help term, control characters are canonicalized to their printable form, so the term ^A is found both by Caret+A and CTRL+A. Also, while topic terms are not case folded, lookup is case insensitive. ๐Ÿ˜Œ

The rest of the script isn't read by SciTECO internally, but it should contain styling for the main document. It's usually read by the standard library's lexer configuration system when showing a womanpage. If the .woman.tec macro is missing, SciTECO will define a single topic for the document based on the .woman file's name.

The combination of plain-text document and script is called a "womanpage" because these files are usually generated using groff(1) with the grosciteco formatter and the sciteco.tmac GNU troff macros. And when you're using womanpages generated by grosciteco, help topics can be defined using the SCITECO_TOPIC Troff macro. This flexible system lets SciTECO access internal and third-party help files written in plain-text or with an arbitrary GNU troff macro package. And since all GNU troff documents are processed at build-time, GNU troff is not required at runtime. ๐Ÿงš

The ? command does not have string building enabled.


๐Ÿ’œ Go to position in buffer

[position] J
[position] : J โ†’ Success|Failure

Sets dot to position. If position is omitted, 0 is implied and J will go to the beginning of the buffer. Home sweet home. ๐Ÿ 

If position is outside the range of the buffer, the command yields an error. But if it's colon-modified, the command instead returns a condition boolean signalling whether the position could be changed or not. Fancy.


โญ Move dot <n> characters

[n] C
- C
[n] : C โ†’ Success|Failure

Adds n to dot. 1 or -1 is implied if n is omitted. Fails if n would move dot off-page. The colon modifier results in a success-boolean being returned instead. ๐Ÿ’…


โญ Move dot <n> characters backwards

[n] R
- R
[n] : R โ†’ Success|Failure

Subtracts n from dot. It's equivalent to -nC. Same energy, other direction. ๐ŸŒˆ


โญ Move dot <n> lines forwards

[n] L
- L
[n] : L โ†’ Success|Failure

Moves dot to the beginning of the line specified relatively to the current line. So a value of 0 for n goes to the beginning of the current line, 1 goes to the next line, -1 to the previous line, etc. If n is omitted, 1 or -1 is implied depending on the sign prefix.

If n would move dot off-page, the command yields an error. The colon-modifier results in a condition boolean being returned instead.


โญ Move dot <n> lines backwards

[n] B
- B
[n] : B โ†’ Success|Failure

Moves dot to the beginning of the line n lines before the current one. It's equivalent to -nL. ๐Ÿฆ‹


โญ Move dot <n> words forwards

[n] W
- W
[n] : W โ†’ Success|Failure
[n] @ W
[n] :@ W โ†’ Success|Failure

If n is positive, move dot n words forwards by first skipping word characters, followed by non-word characters. If n is negative, move dot <-n> words backwards by first skipping non-word characters, followed by word characters. This leaves dot at the beginning of words as defined by the Scintilla message SCI_SETWORDCHARS. If n is zero, dot is not moved. If n is omitted, 1 or -1 is implied depending on the sign prefix.

The command is at-modified (@), the order of word vs. non-word character skipping is swapped, which leaves dot at the end of words. It is especially useful for jumping to the end of the current word.

If the requested word would lie beyond the range of the buffer, the command yields an error. If colon-modified it instead returns a condition code.

๐Ÿ’ซ Move dot n words backwards

[n] P
- P
[n] : P โ†’ Success|Failure
[n] @ P
[n] :@ P โ†’ Success|Failure

Move dot to the beginning of preceding words if n is positive. It is completely equivalent to -nW.

๐Ÿซง Delete words forwards

[n] V
- V
[n] : V โ†’ Success|Failure
[n] @ V
[n] :@ V โ†’ Success|Failure

If n is positive, deletes the next n words until the beginning of the n'th word after the current one. It is deleting exactly until the position that the equivalent W command would move to.

@V is especially useful to remove the remainder of the current word.

๐ŸŒธ Delete word backwards

[n] Y
- Y
[n] : Y โ†’ Success|Failure
[n] @ Y
[n] :@ Y โ†’ Success|Failure

If n is positive, deletes the preceding n words until the beginning of the n'th word before the current one. It is deleting exactly until the position that the equivalent P command would move to. Y is completely equivalent to -nV.

๐ŸŽ€ Kill lines

[n] K
- K
from,to K
[n] : K โ†’ Success|Failure
from,to: K โ†’ Success|Failure

Deletes characters up to the beginning of the line n lines after or before the current one. If n is 0, K will delete up to the beginning of the current line. If n is omitted, the sign prefix will be implied. So to delete the entire line regardless of the position in it, one can use 0KK.

If the deletion is beyond the buffer's range, the command will yield an error unless it has been colon-modified so it returns a condition code.

If two arguments from and to are available, the command is synonymous to from , to D.

๐Ÿฆ‹ Delete characters

[n] D
- D
from,to D
[n] : D โ†’ Success|Failure
from,to: D โ†’ Success|Failure

If n is positive, the next n characters (up to and character .+ n ) are deleted. If n is negative, the previous n characters are deleted. If n is omitted, the sign prefix will be implied.

If two arguments can be popped from the stack, the command will delete the characters with absolute position from up to to from the current buffer.

If the character range to delete is beyond the buffer's range, the command will yield an error unless it has been colon-modified so it returns a condition code instead.

๐ŸŒˆ Convert between lines and glyph lengths or positions

[n] ^ Q โ†’ glyphs
[position] :^ Q โ†’ line

Converts between line and glyph arguments. It returns the number of glyphs between dot and the n-th next line (or previous line if n is negative). Consequently ^QC is equivalent to L, but less efficient.

If colon-modified, an absolute buffer position is converted to the line that contains this position, beginning with 1. Without arguments, :^Q returns the current line.

๐Ÿ’พ Save Q-Register

[q

Save Q-Register q contents on the global Q-Register push-down stack.

๐Ÿงš Restore Q-Register

]q
:]q โ†’ Success|Failure

Restore Q-Register q by replacing its contents with the contents of the register saved on top of the Q-Register push-down stack. The stack entry is popped.

When colon-modified, ] returns a success boolean (-1) if there was a register to pop. If the stack was empty, a failure boolean (0) is returned instead of throwing an error.

In interactive mode, the original contents of q are not immediately reclaimed but are kept in memory to support rubbing out the command. Memory is reclaimed on command-line termination.

๐Ÿ‘‘ Edit or load Q-Register

EQq$
EQq [file] $

When specified with an empty file string argument, EQ makes q the currently edited Q-Register. Otherwise, when file is specified, it is the name of a file to read into Q-Register q. When loading a file, the currently edited buffer/register is not changed and the edit position of register q is reset to 0.

Undefined Q-Registers will be defined. The command fails if file could not be read.

๐Ÿ“ Save Q-Register string to file

E %q<file>$

Saves the string contents of Q-Register q to file. The file must always be specified, as Q-Registers have no notion of associated file names.

In interactive mode, the E% command may be rubbed out, restoring the previous state of file. This follows the same rules as with the EW command.

File names may also be tab-completed and string building characters are enabled by default.

๐Ÿ”ฅ Query Q-Register existence, its integer or string characters

Qq โ†’ n
-Qq โ†’ -n
<position>Qq โ†’ code
:Qq โ†’ -1 | size

Without any arguments, get and return the integer-part of Q-Register q.

With one argument, return the character code at position from the string-part of Q-Register q. Positions are handled like buffer positions โ€” they begin at 0 up to the length of the string minus 1. -1 is returned for invalid positions. If q is encoded as UTF-8 and there is an invalid byte sequence at the requested position, -2 is returned. Incomplete UTF-8 byte sequences are returned as -3. Both non-colon-modified forms of Q require register q to be defined and fail otherwise.

When colon-modified, Q does not pop any arguments from the expression stack and returns the size of the string in Q-Register q if register q exists (i.e. is defined). Naturally, for empty strings, 0 is returned. When colon-modified and Q-Register q is undefined, -1 is returned instead. Therefore checking the return value :Q for values smaller 0 allows checking the existence of a register. Note that if q exists, its string part is not initialized, so :Q may be used to handle purely numeric data structures without creating Scintilla documents by accident. These semantics allow the useful idiom :Qq"> for checking whether a Q-Register exists and has a non-empty string. Note also that the return value of :Q may be interpreted as a condition boolean that represents the non-existence of q. If q is undefined, it returns success, else a failure boolean.

๐Ÿ’… Set or append to Q-Register string without string building

[c1,c2,...]^Uq [string] $
[c1,c2,...]:^Uq [string] $

If not colon-modified, it first fills the Q-Register q with all the values on the expression stack (interpreted as codepoints). It does so in the order of the arguments, i.e. c1 will be the first character in q, c2 the second, etc. Eventually the string argument is appended to the register. Any existing string value in q is overwritten by this operation.

In the colon-modified form ^U does not overwrite existing contents of q but only appends to it.

If q is undefined, it will be defined.

String-building characters are disabled for ^U commands. Therefore they are especially well-suited for defining SciTECO macros, since string building characters in the desired Q-Register contents do not have to be escaped. The EU command may be used where string building is desired.

๐ŸŽ€ Set or append to Q-Register string with string building characters

[c1,c2,...]EUq [string] $
[c1,c2,...]:EUq [string] $

This command sets or appends to the contents of Q-Register q. It is identical to the ^U command, except that this form of the command has string building characters enabled.

๐ŸŒŸ Insert or print Q-Register string

Gq
:Gq

Inserts the string of Q-Register q into the buffer at its current position. If colon-modified prints the string as a message (i.e. to the terminal and/or in the message area) instead of modifying the current buffer.

Specifying an undefined q yields an error.

๐Ÿงธ Set Q-Register integer

nUq
-Uq
[n] :Uq โ†’ Success|Failure

Sets the integer-part of Q-Register q to n. -U is equivalent to -1U, otherwise the command fails if n is missing.

If the command is colon-modified, it returns a success boolean if n or - is given. Otherwise it returns a failure boolean and does not modify q.

The register is defined if it does not exist.

๐Ÿ’œ Increase or decrease Q-Register integer

[n] %q โ†’ q+n
-%q โ†’ q-1

Add n to the integer part of register q, returning its new value. If n is omitted, the sign prefix is implied. q will be defined if it does not exist.

๐Ÿš€ Execute macro

Mq
:Mq

Execute macro stored in string of Q-Register q. The command itself does not push or pop any arguments from the stack but the macro executed might well do so. The new macro invocation level will contain its own go-to label table and local Q-Register table. Except when the command is colon-modified โ€” in this case, local Q-Registers referenced in the macro refer to the parent macro-level's local Q-Register table (or whatever level defined one last).

Errors during the macro execution will propagate to the M command. In other words if a command in the macro fails, the M command will fail and this failure propagates until the top-level macro (e.g. the command-line macro).

Note that the string of q will be copied upon macro execution, so subsequent changes to Q-Register q from inside the macro do not modify the executed code.

While M does not check the register's configured encoding (as reported by EE), its contents must be and are checked to be in valid UTF-8.

๐Ÿฆ‹ Execute from indirect command file

EIfile$
:EIfile$

Read the file with name file into memory and execute its contents as a macro. It is otherwise similar to the M command.

If file could not be read, the command yields an error.

As all SciTECO code, the contents of file must be in valid UTF-8 even if operating in the โ€œdefault ANSIโ€ mode as configured by ED.

๐ŸŒธ Copy into or append or cut to Q-Register

[lines] Xq
-Xq
from,toXq
[lines] :Xq
-:Xq
from,to:Xq
[lines] @Xq
-@Xq
from,to@Xq
[lines] :@Xq
-:@Xq
from,to:@Xq

Okay so this one copies the next or previous lines from the buffer into the Q-Register qโ€™s string. If lines is omitted, the sign prefix is implied. If two arguments are specified, the characters beginning at position from up to the character at position to are copied. The semantics of the arguments is analogous to the K commandโ€™s arguments.

If the command is colon-modified (:), the characters will be appended to the end of register q instead. If the command is at-modified (@), the text will be removed from the buffer after copying or appending to the Q-Register, thus performing a cut operation. The order of modifiers is as always insignificant.

Register q will be created if it is undefined.


๐Ÿ“‚ Open or edit file ๐Ÿ“‚

[n] EB [file] $
[n] EB $

Bestie, EB is your open/edit baddie. It opens or edits the file with name file. If file is not in the buffer ring, it is opened, added to the ring and set as the currently edited buffer. If it already exists in the ring, it is merely made the current file. file may be omitted, in which case the default unnamed buffer is created/edited. If an argument is specified as 0, EB will additionally display the buffer ring contents in the windowโ€™s popup area. Naturally this only has any effect in interactive mode. Note that you can also click on these entries โ€” if mouse support is enabled โ€” to immediately switch to any file in the buffer ring just like with any other popup. iykyk โœจ

file may also be a glob pattern, in which case all regular files matching the pattern are opened/edited. Globbing is performed exactly the same as the EN command does. Also refer to the section called Glob Patterns for more details.

File names of buffers in the ring are normalized by making them absolute. Any comparison on file names is performed using guessed or actual absolute file paths, so that one file may be referred to in many different ways (paths).

file does not have to exist on disk. In this case, an empty buffer is created and its name is guessed from file. When the newly created buffer is first saved, the file is created on disk and the bufferโ€™s name will be updated to the absolute path of the file on disk.

File names may also be tab-completed and string building characters are enabled by default. ๐Ÿซถ

If n is greater than zero, the string argument must be empty. Instead n selects a buffer from the ring to edit. A value of 1 denotes the first buffer, 2 the second, ecetera. ๐Ÿ’…


๐Ÿ’พ Save buffer or Q-Register ๐Ÿ’พ

EW $
[n] EW [file] $

Saves the chosen buffer with id n to disk. By default, the current buffer is saved. If the buffer was dirty, it will be clean afterwards. If the string argument file is not empty, the buffer is saved with the specified file name and is renamed in the ring.

If the current document is a Q-Register and n is not given, the string contents of the current Q-Register are saved to file (cf. E%q command).. Q-Registers have no notion of associated file names, so file must be always specified in this case.

In interactive mode, EW is executed immediately and may be rubbed out. In order to support that, SciTECO creates so called save point files. It does not merely overwrite existing files when saving but moves them to save point files instead. Save point files are called .teco-n-filename~, where filename is the name of the saved file and n is a number that is increased with every save operation. Save point files are always created in the same directory as the original file to ensure that no copying of the file on disk is necessary but only a rename of the file. When rubbing out the EW command, SciTECO restores the latest save point file by moving (renaming) it back to its original path -- also not requiring any on-disk copying.

โš ๏ธ SciTECO is impossible to crash, but just in case it still does it may leave behind these save point files which must be manually deleted by the user. Otherwise save point files are deleted on command line termination. ๐Ÿ˜ญ

File names may also be tab-completed and string building characters are enabled by default. ๐ŸŽ€


๐Ÿ“– Read and insert file into current buffer ๐Ÿ“–

ER <file>$

Reads and inserts the given file into the current buffer or Q-Register at dot. Dot is left immediately after the given file. slay. โœจ


๐Ÿ—‘๏ธ Remove buffer from ring ๐Ÿ—‘๏ธ

[n] EF
- EF
[n] : EF

Removes buffer from buffer ring, effectively closing it. The optional argument n specifies the id of the buffer to close -- by default the current buffer will be closed. If the selected buffer is dirty (modified), EF will yield an error. If n is negative (success boolean), buffer <-n> will be closed even if it is dirty. -EF will force-close the current buffer. No cap, dirty buffers are not here to play unless you force it. ๐Ÿ’€

When colon-modified, the selected buffer is saved before closing. The file is always written, unlike :EX which saves only dirty buffers. This can fail of course, e.g. when called on the unnamed buffer.

It is noteworthy that EF will be executed immediately in interactive mode but can be rubbed out at a later time to reopen the file. Closed files are kept in memory until the command line is terminated. ๐Ÿซถ

Close and edit hooks are only executed when closing the current buffer.


๐Ÿ” Set or get search mode flag ๐Ÿ”

mode^ X
-^ X
^ X โ†’ mode

The search mode is interpreted as a TECO boolean. A true value (smaller than zero) configures case-sensitive searches, while a false value (larger than or equal to zero) configures case-insensitive searches. -^X is equivalent to -1^X and also enables case-sensitive searches. Searches are case-insensitive by default. the more you know, bestie. ๐ŸŒˆ

An alternative way to access the search mode is via the ^X local Q-Register. Consequently, the search mode is local to the current macro invocation frame, unless the macro call was colon-modified. โœจ


๐Ÿ”Ž Search for pattern ๐Ÿ”Ž

[n] S [pattern] $
- S [pattern] $
from,toS [pattern] $
[n] : S [pattern] $ โ†’ Success|Failure
-: S [pattern] $ โ†’ Success|Failure
from,to: S [pattern] $ โ†’ Success|Failure
[n] :: S [pattern] $ โ†’ Success|Failure
-:: S [pattern] $ โ†’ Success|Failure
from,to:: S [pattern] $ โ†’ Success|Failure

Search for pattern in the current buffer/Q-Register. Search order and range depends on the arguments given. By default without any arguments, S will search forward from dot till file end. The optional single argument specifies the occurrence to search (1 is the first occurrence, 2 the second, etc.). Negative values for n perform backward searches. If missing, the sign prefix is implied for n. Therefore -S will search for the first occurrence of pattern before dot.

If two arguments are specified on the command, search will be bounded in the character range from up to to, and only the first occurrence will be searched. from might be larger than to in which case a backward search is performed in the selected range.

After performing the search, the search pattern is saved in the global search Q-Register _. A success/failure condition boolean is saved in that registerโ€™s integer part. pattern may be omitted in which case the pattern of the last search or search and replace command will be implied by using the contents of register _ (this could of course also be manually set).

After a successful search, the pointer is positioned after the found text in the buffer. An unsuccessful search will display an error message but not actually yield an error. The message displaying is suppressed when executed from loops and register _ is the implied argument for break-commands so that a search-break idiom can be implemented as follows:

<Sfoo$; ...>

Alternatively, S may be colon-modified in which case it returns a condition boolean that may be directly evaluated by a conditional or break-command.

When modified with two colons, the search will be anchored in addition to returning a condition boolean, i.e. it can be used to perform a string comparison. ::S without arguments compares the pattern against the current buffer position. With a single positive integer n, ::S matches n repititions of the given pattern. With a negative integer n, ::S will match the n-th last occurrence of the pattern from the beginning of the buffer (which is not really useful). With two integer arguments, ::S compares the pattern against the corresponding part of the buffer. iconic behavior, honestly. ๐Ÿ’…

In interactive mode, searching will be performed immediately (โ€œsearch as you typeโ€) highlighting matched text on the fly. Changing the pattern results in the search being reperformed from the beginning. ๐Ÿ”ฅ


๐Ÿงš Search over buffer-boundaries ๐Ÿงš

[n] N [pattern] $
- N [pattern] $
from,toN [pattern] $
[n] : N [pattern] $ โ†’ Success|Failure
-: N [pattern] $ โ†’ Success|Failure
from,to: N [pattern] $ โ†’ Success|Failure

Search for pattern over buffer boundaries. This command is similar to the regular search command (S) but will continue to search for occurrences of pattern when the end or beginning of the current buffer is reached. Occurrences of pattern spanning over buffer boundaries will not be found. When searching forward N will start in the current buffer at dot, continue with the next buffer in the ring searching the entire buffer until it reaches the end of the buffer ring, continue with the first buffer in the ring until reaching the current file again where it searched from the beginning of the buffer up to its current dot. Searching backwards does the reverse.

N also differs from S in the interpretation of two arguments. Using two arguments the search will be bounded between the buffer with number from, up to the buffer with number to. When specifying buffer ranges, the entire buffers are searched from beginning to end. from may be greater than to in which case, searching starts at the end of buffer from and continues backwards until the beginning of buffer to has been reached. Furthermore as with all buffer numbers, the buffer ring is considered a circular structure and it is possible to search over buffer ring boundaries by specifying buffer numbers greater than the number of buffers in the ring. circular ring energy, we love to see it. ๐ŸŒ€


โœ‚๏ธ Delete up to occurrence of pattern โœ‚๏ธ

FK [pattern] $
[n] FK [pattern] $
- FK [pattern] $
from,toFK [pattern] $
: FK [pattern] $ โ†’ Success|Failure
[n] : FK [pattern] $ โ†’ Success|Failure
-: FK [pattern] $ โ†’ Success|Failure
from,to: FK [pattern] $ โ†’ Success|Failure

FK searches for pattern just like the regular search command (S) but when found, deletes all text from dot up to but not including the found text instance. When searching backwards the characters beginning after the occurrence of pattern up to dot are deleted. cutting it up, periodt. โœ‚๏ธ

In interactive mode, deletion is not performed as-you-type but only on command termination. ๐Ÿซถ

๐Ÿ—‘๏ธ Delete occurrence of pattern

[n] FD [pattern] $
- FD [pattern] $
from,toFD [pattern] $
[n] : FD [pattern] $ โ†’ Success|Failure
-: FD [pattern] $ โ†’ Success|Failure
from,to: FD [pattern] $ โ†’ Success|Failure
[n] :: FD [pattern] $ โ†’ Success|Failure
-:: FD [pattern] $ โ†’ Success|Failure
from,to:: FD [pattern] $ โ†’ Success|Failure

Okay so this one searches for pattern exactly like the regular search command (S) does, but the moment it finds a match it deletes the entire occurrence. Search-and-destroy behavior, literally.


๐Ÿ” Search and replace

[n] FS [pattern] $ [string] $
- FS [pattern] $ [string] $
from,toFS [pattern] $ [string] $
[n] : FS [pattern] $ [string] $ โ†’ Success|Failure
-: FS [pattern] $ [string] $ โ†’ Success|Failure
from,to: FS [pattern] $ [string] $ โ†’ Success|Failure
[n] :: FS [pattern] $ [string] $ โ†’ Success|Failure
-:: FS [pattern] $ [string] $ โ†’ Success|Failure
from,to:: FS [pattern] $ [string] $ โ†’ Success|Failure

It searches for pattern just like the regular search command (S) does, but if it finds it, it replaces the match with string. If string is empty, the occurrence will always be deleted, so FS[pattern]$$ is similar to FD[pattern]$. The global replace register is not touched by the FS command.

In interactive mode, the replacement will be performed immediately and interactively. Very much โ€œdo it liveโ€ energy. ๐Ÿ’…


๐Ÿ’พ Search and replace with default

[n] FR [pattern] $ [string] $
- FR [pattern] $ [string] $
from,toFR [pattern] $ [string] $
[n] : FR [pattern] $ [string] $ โ†’ Success|Failure
-: FR [pattern] $ [string] $ โ†’ Success|Failure
from,to: FR [pattern] $ [string] $ โ†’ Success|Failure
[n] :: FR [pattern] $ [string] $ โ†’ Success|Failure
-:: FR [pattern] $ [string] $ โ†’ Success|Failure
from,to:: FR [pattern] $ [string] $ โ†’ Success|Failure

The FR command is similar to the FS command. It searches for pattern just like the regular search command (S) and replaces the occurrence with string similar to what FS does. It differs from FS because the replacement string is saved in the global replacement register -. If string is empty, the string in the global replacement register is implied instead.


๐ŸŒˆ Search and replace with default over buffer-boundaries

[n] FN [pattern] $ [string] $
- FN [pattern] $ [string] $
from,toFN [pattern] $ [string] $
[n] : FN [pattern] $ [string] $ โ†’ Success|Failure
-: FN [pattern] $ [string] $ โ†’ Success|Failure
from,to: FN [pattern] $ [string] $ โ†’ Success|Failure
[n] :: FN [pattern] $ [string] $ โ†’ Success|Failure
-:: FN [pattern] $ [string] $ โ†’ Success|Failure
from,to:: FN [pattern] $ [string] $ โ†’ Success|Failure

The FN command is similar to the FR command but will continue to search for occurrences of pattern when the end or beginning of the current buffer is reached. It searches for pattern just like the search over buffer-boundaries command (N) and replaces the occurrence with string similar to what FR does. If string is empty, the string in the global replacement register is implied instead.

FN also differs from FR in the interpretation of two arguments. Using two arguments, the search will be bounded between the buffer with number from, up to the buffer with number to.


๐Ÿ–ฅ๏ธ Execute operating system command and filter buffer contents

ECcommand$
linesECcommand$
-ECcommand$
from,toECcommand$
:ECcommand$ โ†’ Success|Failure
lines:ECcommand$ โ†’ Success|Failure
-:ECcommand$ โ†’ Success|Failure
from,to:ECcommand$ โ†’ Success|Failure

The EC command allows you to interface with the operating system shell and external programs. The external program is spawned as a background process, and its standard input stream is fed with data from the current document โ€” i.e. text is piped into the external program. When automatic EOL translation is enabled, this will translate all end of line sequences according to the source document's EOL mode (see the EL command). For instance, when piping from a document with DOS line breaks, the receiving program will only be sent DOS line breaks. The process' standard output stream is also redirected and inserted into the current document. End of line sequences are normalized accordingly, but the EOL mode guessed from the program's output is not set on the document. The process' standard error stream is discarded. If data is piped into the external program, its output replaces that data in the buffer. Dot is always left at the end of the insertion.

If invoked without parameters, no data is piped into the process (and no characters are removed), and its output is inserted at the current buffer position. This is equivalent to invoking .,.EC. If invoked with one parameter, the next or previous number of lines are piped from the buffer into the program, and its output replaces these lines. This effectively runs command as a filter over lines. -EC may be written as a short-cut for -1EC. When invoked with two parameters, the characters beginning at position from up to the character at position to are piped into the program and replaced with its output. This effectively runs command as a filter over a buffer range.

Errors are thrown not only for invalid buffer ranges but also for errors during process execution. If the external command has an unsuccessful exit code, the EC command will also fail. If the EC command is colon-modified, it will instead return a TECO boolean signifying success or failure. In case of an unsuccessful exit code, a colon-modified EC will return the absolute value of the process exit code (which is also a TECO failure boolean) and 0 for all other failures. This feature may be used to take action depending on a specific process exit code.

command execution is by default platform-dependent. On DOS-like systems like Windows, command is passed to the command interpreter specified in the $COMSPEC environment variable with the /q and /c command-line arguments. On UNIX-like systems, command is passed to the interpreter specified by the $SHELL environment variable with the -c command-line argument. Therefore the default shell can be configured using the corresponding environment registers. The operating system restrictions on the maximum length of command-line arguments apply to command, and quoting of parameters within command is somewhat platform dependent. On all other platforms, SciTECO will uniformly parse command just as an UNIX98 /bin/sh would, but without performing any expansions. The program specified in command is searched for in standard locations (according to the $PATH environment variable). This mode of operation can also be enforced on all platforms by enabling bit 7 in the ED flag, e.g. by executing 0,128ED, and is recommended when writing cross-platform macros using the EC command.

When using an UNIX-compatible shell or the UNIX98 shell emulation, you might want to use the ^E@ string-building character to pass Q-Register contents reliably as single arguments to the spawned process.

The spawned process inherits both SciTECO's current working directory and its environment variables. More precisely, SciTECO uses its environment registers to construct the spawned process' environment. Therefore it is also straight forward to change the working directory or some environment variable temporarily for a spawned process.

Note that when run interactively and subsequently rubbed out, SciTECO can easily undo all changes to the editor state. It cannot however undo any other side-effects that the execution of command might have had on your system. ๐Ÿ˜ญ
Note also that the EC command blocks indefinitely until the command completes, which may result in editor hangs. You may however interrupt the spawned process by sending the SIGINT signal to SciTECO, e.g. by pressing CTRL+C. The first time, this will try to kill the spawned process gracefully. The second time you press CTRL+C, it will hard kill the process. ๐Ÿ’€

In interactive mode, SciTECO performs TAB-completion of filenames in the command string parameter but does not attempt any escaping of shell-relevant characters like whitespaces.


๐Ÿ“ฅ Set Q-Register to output of operating system command

EGq command$
linesEGq command$
-EGq command$
from,toEGq command$
:EGq command$ โ†’ Success|Failure
lines:EGq command$ โ†’ Success|Failure
-:EGq command$ โ†’ Success|Failure
from,to:EGq command$ โ†’ Success|Failure

Runs an operating system command and sets Q-Register q to the data read from its standard output stream. Data may be fed to command from the current buffer/document. The interpretation of the parameters and command as well as the colon-modification is analogous to the EC command.

The EG command only differs from EC in not deleting any characters from the current buffer, not changing the current buffer position, and writing process output to the Q-Register q. In other words, the current buffer is not modified by EG. Also, since EG replaces the string value of q, the register's EOL mode is set to the mode guessed from the external program's output.

The register q is defined if it does not already exist.


<n>=
<n>==
<n>===
<n>:=
<n>:==
<n>:===

Shows integer n as a message in the message line and/or on the console. One = formats the integer as a signed decimal number, == formats as an unsigned octal number, and === as an unsigned hexadecimal number. It is logged with the user-message severity. The command fails if n is not given.

A noteworthy quirk is that == and === will print 2 or 3 numbers in succession when executed from interactive mode at the end of the command line in order to guarantee immediate feedback. โœจ

If you want to print multiple values from the stack, you have to put the = into a pass-through loop or separate the commands with whitespace (e.g. ^Y= =).

If colon-modified, the number is printed without a trailing linefeed.


[type] ^ A <string>^ A
[type] @^ A /string/
[type] :^ A <string>^ A

Prints string as a message with severity type, i.e. in the message line in interactive mode and if possible on the terminal as well. The following message levels are supported:

  • 0: User-level message: they are written without any prefixes directly to stdout. This is the default if type is omitted.
  • 1: Info-level message
  • 2: Warnings
  • 3: Errors

^A differs from all other commands in the way string is terminated. It is terminated by ^A (CTRL+A, ASCII 1) by default. While the initial ^A can be written with upcarets, the terminating ^A must always be ASCII 1. You can however overwrite the string terminator as usual by @-modifying the command. ๐ŸŽ€

Also, string-building characters are enabled for this command. ^A outputs strings in the default codepage, but when you colon-modify the command, raw ANSI encoding is enforced. ๐Ÿ’…

๐Ÿ“ค Type out buffer contents as messages

[lines] T
- T
from,toT

Type out the next or previous number of lines from the buffer as a message โ€” i.e. in the message line in interactive mode, and if possible on the terminal (stdout) as well. If lines is omitted, the sign prefix is implied. If two arguments are specified, the characters beginning at position from up to the character at position to are copied. The semantics of the arguments is analogous to the K command's arguments. ๐Ÿซถ

๐Ÿ”ข Type out the numeric arguments as a message or get character from user

<c1,c2,...>^ T
<c1,c2,...>:^ T
^ T โ†’ codepoint
:^ T โ†’ byte

Types out characters for all the values on the argument stack (interpreted as codepoints) as messages โ€” i.e. in the message line in interactive mode and if possible on the terminal (stdout) as well. It does so in the order of the arguments, i.e. c1 is inserted before c2, etcetera. By default the codepoints are expected to be in the default codepage, but you can force raw ANSI encoding (for arbitrary bytes) by colon-modifying the command. โœจ

When called without any argument, ^T reads a key from the user (or from stdin) and returns the corresponding codepoint. If the default encoding is UTF-8, this will not work for function keys. If the default encoding is raw ANSI or if the command is colon-modified, ^T returns raw bytes. When run in batch mode, this will return whatever byte is delivered by the attached terminal. In case stdin is closed, -1 is returned. In interactive mode, pressing CTRL+D or CTRL+C will also return -1. ๐Ÿ’€

๐Ÿ›ฐ๏ธ Send Scintilla message

[lParam,][wParam,] [message] ES $ โ†’ result
[lParam,] [wParam] ES [message] $$ โ†’ result
[lParam] ES [message] [,wParam]$$ โ†’ result
[wParam] ES [message] $ [lParam] $ โ†’ result
[lParam] ES [message] $ [wParam] ^@ [lParam] $ โ†’ result

Send Scintilla message with code specified by message, wParam and lParam. message and wParam may be symbolic names when specified as part of the first string argument. If not, they are popped from the stack. lParam may be specified as a constant string whose pointer is passed to Scintilla if specified as the second string argument. It is automatically null-terminated. If the second string argument is empty, lParam is popped from the stack instead. If the second string argument contains a null-byte (^@), both wParam and lParam are passed as null-terminated string pointers to Scintilla. If the second string ends in a null-byte, lParam is still popped from the stack. Parameters popped from the stack may be omitted, in which case 0 is implied. The message's return value is always pushed onto the stack (0 if the message has no documented return values). ๐ŸŒˆ

All messages defined by Scintilla (as C macros in Scintilla.h) can be used by passing their name as a string to ES (e.g. ESSCI_LINESONSCREEN...). The โ€œSCI_โ€ prefix may be omitted and message symbols are case-insensitive. Only the Lexilla style names (SCE_...) may be used symbolically with the ES command as wParam in the first string argument. In interactive mode, symbols may be auto-completed by pressing Tab. String-building characters are by default interpreted in the string arguments. ๐ŸŽ€

As a special exception, you can and must specify a Lexilla lexer name as a string argument for the SCI_SETILEXER message, i.e. in order to load a Lexilla lexer (this works similar to the old SCI_SETLEXERLANGUAGE message). If the lexer name contains a null-byte, the second string argument is split into two: up until the null-byte, the path of an external lexer library (shared library or DLL) is expected, that implements the Lexilla protocol. The โ€œ.soโ€ or โ€œ.dllโ€ extension is optional. The concrete lexer name is the remainder of the string after the null-byte. This allows you to use lexers from external lexer libraries like Scintillua. When detecting Scintillua, SciTECO will automatically pass down the SCITECO_SCINTILLUA_LEXERS environment variable as the โ€œscintillua.lexersโ€ library property for specifying the location of Scintillua's Lua lexer files. ๐Ÿงš

In order to facilitate the use of Scintillua lexers, the semantics of SCI_NAMEOFSTYLE have also been changed. Instead of returning the name for a given style id, it now returns the style id when given the name of a style in the second string argument of ES, i.e. it allows you to look up style ids by name. ๐Ÿ’…

By default Scintilla messages are sent to the current buffer's view or the Q-register view โ€” there is only one view for all Q-registers. If bit 11 is set in the ED flags, the messages will be sent to the command-line view instead, which allows you to set up SciTECO syntax highlighting and other styles. ๐Ÿ‘‘

Warning: Almost all Scintilla messages may be dispatched using this command. If called wrongly, you can easily crash the editor. Therefore it is not recommended to invoke ES interactively. SciTECO does not keep track of the editor state changes performed by these commands and cannot undo them. You should never use it to change the editor state (position changes, deletions, etc.) or otherwise rub out will result in an inconsistent editor state. There are however exceptions:
  • In the editor profile and batch mode in general, the ES command may be used freely.
  • In the ED hook macro (register โ€œEDโ€), when a file is added to the ring, most destructive operations can be performed since rubbing out the EB command responsible for the hook execution also removes the buffer from the ring again.
  • As part of function key macros that immediately terminate the command line.

๐Ÿ•ฐ๏ธ COMPATIBILITY ๐Ÿ•ฐ๏ธ

SciTECO strives to be compatible with โ€œstandardโ€ DEC TECO-11 wherever this does not hinder SciTECO's nature as an interactive modern editor. In questions concerning multiple buffers and interactivity SciTECO draws inspiration from Video TECO. Most Video TECO and many โ€œstandardโ€ TECO macros should be portable with little or no changes. SciTECO however consciously deviates from both dialects to preserve features considered intrinsic and defining to the project. ๐ŸŒธ

๐Ÿ”Ž SEE ALSO ๐Ÿ”Ž

  • Program invocation and options: sciteco(1)
  • Scintilla messages and other documentation: Scintilla
  • Scinterm website, documenting the mapping of โ€œRGBโ€ values to terminal colors on curses user interfaces: Scinterm website
  • Scintillua manual, detailing usage of Lua-based Scintilla lexers: Scintillua manual
  • Suitable terminal fonts for icon support in Curses (see ED flags): Nerd Fonts
  • Gtk+ 3 documentation, containing details about its CSS support and syntax: Overview of CSS in GTK

๐Ÿ’– AUTHOR ๐Ÿ’–

This manpage and the SciTECO program was written by Robin Haberkorn. ๐Ÿ‘‘

And that's the whole sciteco(7) page, bestie โ€” SciTECO Version 2.5.2, dated 30 Apr 2026, signing off ๐Ÿ’–โœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from