<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sciteco/src/qreg.c, branch lsp</title>
<subtitle>Scintilla-based Text Editor and COrrector</subtitle>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/'/>
<entry>
<title>get rid of teco_qreg_vtable_t::undo_set_integer()</title>
<updated>2026-07-25T00:37:17+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-07-25T00:37:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=a53fa85dabdfc2c47ec0c9e6626ddda2379a8e38'/>
<id>a53fa85dabdfc2c47ec0c9e6626ddda2379a8e38</id>
<content type='text'>
It was never required as a separate callback/method,
but was kept merely for consistency.
Since we now call teco_current_doc_set_dot() in
teco_qreg_dot_set_integer(), we'd have to split it up into
an "undo" method as well. I decided to get rid of the
superfluous Q-Reg method instead.

It's quite likely we could get rid of the remaining
undo_set_string(), undo_exchange_string() and undo_edit()
callbacks as well (TODO).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It was never required as a separate callback/method,
but was kept merely for consistency.
Since we now call teco_current_doc_set_dot() in
teco_qreg_dot_set_integer(), we'd have to split it up into
an "undo" method as well. I decided to get rid of the
superfluous Q-Reg method instead.

It's quite likely we could get rid of the remaining
undo_set_string(), undo_exchange_string() and undo_edit()
callbacks as well (TODO).
</pre>
</div>
</content>
</entry>
<entry>
<title>revised and improved the Unicode glyph-to-byte conversion heuristics</title>
<updated>2026-07-24T23:55:28+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-07-24T23:55:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=685507922b0b75da5935076395a5b1ec1ef58356'/>
<id>685507922b0b75da5935076395a5b1ec1ef58356</id>
<content type='text'>
Previously almost all glyph-to-byte offset conversions consulted
Scintilla's line index and counted characters on the resulting line.
For instance a simple expression like `.+1J` would scan the same line
twice completely, which would be very slow on pathologically long lines.
Even insertions did that due to having to update the ^Y ranges.
If you repeat such an operation over all characters as in `&lt;.+1:J;&gt;`
you would have complexity O(n^2) for n = line length.
Only commands with an explicit relative nature like `C` and `A` would
use teco_view_glyph2bytes_relative() which scans beginning at dot
as long as the relative movement is less than 1024 glyphs.

Wit the new heuristics almost all glyph-to-byte and byte-to-glyph
conversions can make use of that optimization.
This requires that dot must at all times be known in glyphs as well -
the byte position is managed by Scintilla (SCI_GETCURRENTPOS).
We therefore introduced teco_current_doc_set_dot() and
teco_current_doc_get_dot() to update dot in the current buffer or
Q-Register -- it cannot be stored along with the view since
Q-Registers share a single view.
A number of auxiliary functions have been introduced for
converting relative to a known (glyphs,bytes) offset pair
and for converting absolute and relative positions with regard
to the current doc and SCI_GETCURRENTPOS position.
Of course this is error-prone since the glyph and dot positions
are interdependant - they must always be kept in sync.

With these new optimizations even pathologically long lines can
(usually) be managed even in UTF-8 documents.
It does not address slow-downs in Scintilla's line layout, yet.
grosciteco.tes for instance runs twice as fast now.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously almost all glyph-to-byte offset conversions consulted
Scintilla's line index and counted characters on the resulting line.
For instance a simple expression like `.+1J` would scan the same line
twice completely, which would be very slow on pathologically long lines.
Even insertions did that due to having to update the ^Y ranges.
If you repeat such an operation over all characters as in `&lt;.+1:J;&gt;`
you would have complexity O(n^2) for n = line length.
Only commands with an explicit relative nature like `C` and `A` would
use teco_view_glyph2bytes_relative() which scans beginning at dot
as long as the relative movement is less than 1024 glyphs.

Wit the new heuristics almost all glyph-to-byte and byte-to-glyph
conversions can make use of that optimization.
This requires that dot must at all times be known in glyphs as well -
the byte position is managed by Scintilla (SCI_GETCURRENTPOS).
We therefore introduced teco_current_doc_set_dot() and
teco_current_doc_get_dot() to update dot in the current buffer or
Q-Register -- it cannot be stored along with the view since
Q-Registers share a single view.
A number of auxiliary functions have been introduced for
converting relative to a known (glyphs,bytes) offset pair
and for converting absolute and relative positions with regard
to the current doc and SCI_GETCURRENTPOS position.
Of course this is error-prone since the glyph and dot positions
are interdependant - they must always be kept in sync.

With these new optimizations even pathologically long lines can
(usually) be managed even in UTF-8 documents.
It does not address slow-downs in Scintilla's line layout, yet.
grosciteco.tes for instance runs twice as fast now.
</pre>
</div>
</content>
</entry>
<entry>
<title>fixed auto completion of two-character Q-register names</title>
<updated>2026-01-31T23:49:55+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-01-31T23:49:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=d0b9287ed3557efd11603afc30aa7781b03e262a'/>
<id>d0b9287ed3557efd11603afc30aa7781b03e262a</id>
<content type='text'>
* this was noticable only after the first character, i.e. after `#x`.
* Q-register tables are case sensitive, so we must not call
  teco_rb3str_auto_complete() with case_sensitive == FALSE.
  And it's also entirely unnecesary since the Q-register name
  for two-character Q-registers is already case-folded.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* this was noticable only after the first character, i.e. after `#x`.
* Q-register tables are case sensitive, so we must not call
  teco_rb3str_auto_complete() with case_sensitive == FALSE.
  And it's also entirely unnecesary since the Q-register name
  for two-character Q-registers is already case-folded.
</pre>
</div>
</content>
</entry>
<entry>
<title>updated copyright to 2026</title>
<updated>2026-01-01T06:59:49+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-01-01T06:59:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=c2feb2a6f71fc9adb20226fb3c2260c236e974e0'/>
<id>c2feb2a6f71fc9adb20226fb3c2260c236e974e0</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>teco_string_t is now passed by value like a scalar if the callee isn't expected to modify it</title>
<updated>2025-12-28T19:57:31+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2025-12-28T15:23:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=ea0a23645f03a42252ab1ce8df45ae4076ebae75'/>
<id>ea0a23645f03a42252ab1ce8df45ae4076ebae75</id>
<content type='text'>
* When passing a struct that should not be modified, I usually use a const pointer.
* Strings however are small 2-word objects and they are often now already passed via separate
  `gchar*` and gsize parameters. So it is consistent to pass teco_string_t by value as well.
  A teco_string_t will usually fit into registers just like a pointer.
* It's now obvious which function just _uses_ and which function _modifies_ a string.
  There is also no chance to pass a NULL pointer to those functions.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* When passing a struct that should not be modified, I usually use a const pointer.
* Strings however are small 2-word objects and they are often now already passed via separate
  `gchar*` and gsize parameters. So it is consistent to pass teco_string_t by value as well.
  A teco_string_t will usually fit into registers just like a pointer.
* It's now obvious which function just _uses_ and which function _modifies_ a string.
  There is also no chance to pass a NULL pointer to those functions.
</pre>
</div>
</content>
</entry>
<entry>
<title>TECO_DEFINE_STATE() no longer constructs callback names for mandatory callbacks, but tries to use static assertions</title>
<updated>2025-12-26T17:10:42+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2025-12-26T17:10:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=c2114fa0af73b42bc1ef302f7511ef87690cc0b1'/>
<id>c2114fa0af73b42bc1ef302f7511ef87690cc0b1</id>
<content type='text'>
* Requiring state callbacks by generating their names (e.g. NAME##_input) has several disadvantages:
  * The callback is not explicitly referenced when the state is defined.
    So an unintroduced reader will see some static function, which is nowhere referenced and still
    doesn't cause "unused" warnings.
  * You cannot choose the name of function that implements the callback freely.
  * In "substates" you need to generate a callback function if you want to provide a default.
    You also need to provide dummy wrapper functions whenever you want to reuse some existing
    function as the implementation.
* Instead, we are now using static assertions to check whether certain callbacks have been
  implemented.
  Unfortunately, this does not work on all compilers. In particular GCC won't consider
  references to state objects fully constant (even though they are) and does not allow
  them in _Static_assert (G_STATIC_ASSERT). This could only be made to work in newer GCC
  with -std=c2x or -std=gnu23 in combination with constexpr.
  It does work on Clang, though.
  So I introduced TECO_ASSERT_SAFE() which also passes if the expression is *not* constant.
  These static assertions are not crucial - they do not check anything that can differ between
  systems. So we can always rely on the checks performed by FreeBSD CI for instance.
  Also, you will of course quickly notice missing callbacks at runtime - with and without
  additional runtime assertions.
* All mandatory callbacks must still be explicitly initialized in the TECO_DEFINE_STATE calls.
* After getting rid of generated callback implementations, the TECO_DEFINE_STATE macros
  can finally be qualified with `static`.
* The TECO_DECLARE_STATE() macro has been removed. It no longer abstracts anything
  and cannot be used to declare static teco_state_t anyway.
  Also TECO_DEFINE_UNDO_CALL() also doesn't have a DECLARE counterpart.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Requiring state callbacks by generating their names (e.g. NAME##_input) has several disadvantages:
  * The callback is not explicitly referenced when the state is defined.
    So an unintroduced reader will see some static function, which is nowhere referenced and still
    doesn't cause "unused" warnings.
  * You cannot choose the name of function that implements the callback freely.
  * In "substates" you need to generate a callback function if you want to provide a default.
    You also need to provide dummy wrapper functions whenever you want to reuse some existing
    function as the implementation.
* Instead, we are now using static assertions to check whether certain callbacks have been
  implemented.
  Unfortunately, this does not work on all compilers. In particular GCC won't consider
  references to state objects fully constant (even though they are) and does not allow
  them in _Static_assert (G_STATIC_ASSERT). This could only be made to work in newer GCC
  with -std=c2x or -std=gnu23 in combination with constexpr.
  It does work on Clang, though.
  So I introduced TECO_ASSERT_SAFE() which also passes if the expression is *not* constant.
  These static assertions are not crucial - they do not check anything that can differ between
  systems. So we can always rely on the checks performed by FreeBSD CI for instance.
  Also, you will of course quickly notice missing callbacks at runtime - with and without
  additional runtime assertions.
* All mandatory callbacks must still be explicitly initialized in the TECO_DEFINE_STATE calls.
* After getting rid of generated callback implementations, the TECO_DEFINE_STATE macros
  can finally be qualified with `static`.
* The TECO_DECLARE_STATE() macro has been removed. It no longer abstracts anything
  and cannot be used to declare static teco_state_t anyway.
  Also TECO_DEFINE_UNDO_CALL() also doesn't have a DECLARE counterpart.
</pre>
</div>
</content>
</entry>
<entry>
<title>fixup 9425ad37ec95a40dc039169031259161c92cc217: fixed error handling in ED hooks</title>
<updated>2025-09-02T14:53:06+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>robin.haberkorn@googlemail.com</email>
</author>
<published>2025-09-02T14:53:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=5e97f97cb7ca9cf459b47d3409da85177e385af2'/>
<id>5e97f97cb7ca9cf459b47d3409da85177e385af2</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>the computed go-to command (O) is now 0-indexed and all invalid indexes and empty labels are ignored</title>
<updated>2025-08-30T17:51:39+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>robin.haberkorn@googlemail.com</email>
</author>
<published>2025-08-30T17:38:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=e82dc6639e829490cb11267fa4a49ef97c6459ae'/>
<id>e82dc6639e829490cb11267fa4a49ef97c6459ae</id>
<content type='text'>
* This has long been a TECO-11 incompatibility.
* The first label in a list has index 0, i.e. `1Ofoo,bar$` jumps to label `!bar!`.
  Consequently 0 is also implied, so `Olabel$` continues to do what you expect.
* `0Ofoo$` was previously also jumping to `!foo!` which was inconsistent:
  All invalid indexes should do nothing, i.e. execution continues after the go-to command.
* Fixed handling of empty labels as in `1Ofoo,,bar$` - execution should also continue
  after the command.
  This eases writing "default" clauses immediately after the go-to.
* The ED hook values now also begin at 0, so most existing ED hook macros should
  continue to work.
* Similarily, the mouse events returned by -EJ also begin at 0 now,
  so fnkeys.tes continues to work as expected.
* It's still very possible of course that this breaks existing code.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* This has long been a TECO-11 incompatibility.
* The first label in a list has index 0, i.e. `1Ofoo,bar$` jumps to label `!bar!`.
  Consequently 0 is also implied, so `Olabel$` continues to do what you expect.
* `0Ofoo$` was previously also jumping to `!foo!` which was inconsistent:
  All invalid indexes should do nothing, i.e. execution continues after the go-to command.
* Fixed handling of empty labels as in `1Ofoo,,bar$` - execution should also continue
  after the command.
  This eases writing "default" clauses immediately after the go-to.
* The ED hook values now also begin at 0, so most existing ED hook macros should
  continue to work.
* Similarily, the mouse events returned by -EJ also begin at 0 now,
  so fnkeys.tes continues to work as expected.
* It's still very possible of course that this breaks existing code.
</pre>
</div>
</content>
</entry>
<entry>
<title>special Q-registers `$` (working directory) and the clipboard registers now support the append operation (:Xq, :^Uq...)</title>
<updated>2025-07-19T19:34:57+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>robin.haberkorn@googlemail.com</email>
</author>
<published>2025-07-19T19:34:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=ac180a94ff749f5df7705279d3d08258417b9b34'/>
<id>ac180a94ff749f5df7705279d3d08258417b9b34</id>
<content type='text'>
Works via a default implementation in the "external" Q-register "class"
by first querying the string, appending and re-setting it.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Works via a default implementation in the "external" Q-register "class"
by first querying the string, appending and re-setting it.
</pre>
</div>
</content>
</entry>
<entry>
<title>make some array declarations real constants</title>
<updated>2025-07-17T22:12:45+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>robin.haberkorn@googlemail.com</email>
</author>
<published>2025-07-17T22:12:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=45b9dea901cec7045be1a98f61d48d41dc965a9f'/>
<id>45b9dea901cec7045be1a98f61d48d41dc965a9f</id>
<content type='text'>
* `static const char *p = "FOO"` is not a true constant since
  the variable p can still be changed.
  It has to be declared as `static const char *const p = "FOO"`,
  so that the pointer itself is constant.
* In case of string constants, it's easier however to use `static const char p[] = "FOO"`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* `static const char *p = "FOO"` is not a true constant since
  the variable p can still be changed.
  It has to be declared as `static const char *const p = "FOO"`,
  so that the pointer itself is constant.
* In case of string constants, it's easier however to use `static const char p[] = "FOO"`.
</pre>
</div>
</content>
</entry>
</feed>
