<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sciteco/src/ring.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>support lookups via language servers (LSP)</title>
<updated>2026-08-10T22:38:31+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-08-02T13:24:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=44f5bf677282308b959411c416da2b5b08db2062'/>
<id>44f5bf677282308b959411c416da2b5b08db2062</id>
<content type='text'>
* The main interface is the `FT` command.
  `FT` was an undocumented Video TECO command for etags/ctags lookups.
  I don't want to exactly copy its interface, though.
* `FT` allows looking up symbol names,
  definitions and references.
* ctags will be supported via ctags-lsp.
  LSP support is more powerful though and works without
  regenerating TAGS files all the time.
  The LSP will also allow you to customize auto-completions
  using SciTECO itself (i.e. by writing a language server
  in SciTECO).
* For multiple results, `FT$` can be used to cycle through
  results - this should mimic repeated `S$` or `N$`.
* `:FT...$` does a fuzzy search. IMHO it's not important
  to return a status integer instead. `FT` will only
  really be used in interactive mode.
* Document synchronization is supported via hooks from
  ring.c and via Scintilla notifications.
* Currently, the LSP communication is based on blocking
  GIOChannels. This means that a misbehaving hanging
  server could "lock up" the entire editor (FIXME).
  Only on ncurses you can always kill the subprocess by
  pressing CTRL+C.
  We need helper functions in spawn.c to read and write
  with interruptions.
* The textDocument/didChange notification transmits
  not only all edits, but all files' contents as well
  during initial synchronization.
  Therefore it is optimized to write and JSON-escape
  data without copying them around in memory and without
  destroying the buffer gap.
* Use $SCITECO_LSP to configure the language server.
  You can also use `tee` to capture stdin and stdout.
  Perhaps $SCITECO_LSP should be saved in .teco_session,
  so you can change it between projects?
* $SCITECO_LSP_ROOT is used to point to the project's
  root directory. session.tes will set it up automatically.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* The main interface is the `FT` command.
  `FT` was an undocumented Video TECO command for etags/ctags lookups.
  I don't want to exactly copy its interface, though.
* `FT` allows looking up symbol names,
  definitions and references.
* ctags will be supported via ctags-lsp.
  LSP support is more powerful though and works without
  regenerating TAGS files all the time.
  The LSP will also allow you to customize auto-completions
  using SciTECO itself (i.e. by writing a language server
  in SciTECO).
* For multiple results, `FT$` can be used to cycle through
  results - this should mimic repeated `S$` or `N$`.
* `:FT...$` does a fuzzy search. IMHO it's not important
  to return a status integer instead. `FT` will only
  really be used in interactive mode.
* Document synchronization is supported via hooks from
  ring.c and via Scintilla notifications.
* Currently, the LSP communication is based on blocking
  GIOChannels. This means that a misbehaving hanging
  server could "lock up" the entire editor (FIXME).
  Only on ncurses you can always kill the subprocess by
  pressing CTRL+C.
  We need helper functions in spawn.c to read and write
  with interruptions.
* The textDocument/didChange notification transmits
  not only all edits, but all files' contents as well
  during initial synchronization.
  Therefore it is optimized to write and JSON-escape
  data without copying them around in memory and without
  destroying the buffer gap.
* Use $SCITECO_LSP to configure the language server.
  You can also use `tee` to capture stdin and stdout.
  Perhaps $SCITECO_LSP should be saved in .teco_session,
  so you can change it between projects?
* $SCITECO_LSP_ROOT is used to point to the project's
  root directory. session.tes will set it up automatically.
</pre>
</div>
</content>
</entry>
<entry>
<title>hide #recovery# files from auto-completions, unless you already typed '#'</title>
<updated>2026-07-26T12:23:21+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-07-26T12:23:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=bbbe4cdbc9ba9d43582c9420303d2aab977673a4'/>
<id>bbbe4cdbc9ba9d43582c9420303d2aab977673a4</id>
<content type='text'>
* These files are created regularily and shouldn't be mangled with unless you're
  recovering from a crash.
  So it makes sense to hide them by default, just like the hidden .teco-* savepoint
  files.
* Recovery file name creation and checks are now centralized in file-utils.h.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* These files are created regularily and shouldn't be mangled with unless you're
  recovering from a crash.
  So it makes sense to hide them by default, just like the hidden .teco-* savepoint
  files.
* Recovery file name creation and checks are now centralized in file-utils.h.
</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>teco_globber_t is ported from GRegex to terex</title>
<updated>2026-06-28T00:35:17+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-06-28T00:35:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=0dfb113b47d958093e6ae086c9695e5be83b24b8'/>
<id>0dfb113b47d958093e6ae086c9695e5be83b24b8</id>
<content type='text'>
It's now a private struct, so we can include the regex_t wihout
having to draw in the terex headers everywhere.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It's now a private struct, so we can include the regex_t wihout
having to draw in the terex headers everywhere.
</pre>
</div>
</content>
</entry>
<entry>
<title>GTK: SIGTERM/SIGHUP always terminates the program and dumps recovery files</title>
<updated>2026-04-12T21:00:40+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-04-12T19:47:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=0a8770ac7d382df8976b2448fccc6cfe434cd4d1'/>
<id>0a8770ac7d382df8976b2448fccc6cfe434cd4d1</id>
<content type='text'>
* SIGTERM used to insert the ^KCLOSE key macro.
  However with the default ^KCLOSE macro, which inserts `EX`,
  this may fail to terminate the editor if buffers are modified.
  If the process is consequently killed by a non-ignorable signal,
  we may still loose data.
* SIGTERM is used to gracefully shut down, so we now always terminate.
  Since we have recovery files, they are now dumped before terminating.
  This makes sure that recovery files are more up-to-date during
  unexpected but gracefull terminations.
* The same functionality is planned on Curses, but requires more fundamental
  changes (TODO).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* SIGTERM used to insert the ^KCLOSE key macro.
  However with the default ^KCLOSE macro, which inserts `EX`,
  this may fail to terminate the editor if buffers are modified.
  If the process is consequently killed by a non-ignorable signal,
  we may still loose data.
* SIGTERM is used to gracefully shut down, so we now always terminate.
  Since we have recovery files, they are now dumped before terminating.
  This makes sure that recovery files are more up-to-date during
  unexpected but gracefull terminations.
* The same functionality is planned on Curses, but requires more fundamental
  changes (TODO).
</pre>
</div>
</content>
</entry>
<entry>
<title>decreased default recovery interval to 120s</title>
<updated>2026-03-09T20:12:32+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-03-09T20:12:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=66317e173c592817cfc7052b55a768e3ce7e4223'/>
<id>66317e173c592817cfc7052b55a768e3ce7e4223</id>
<content type='text'>
5 minutes was probably a bit too conservative.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
5 minutes was probably a bit too conservative.
</pre>
</div>
</content>
</entry>
<entry>
<title>`ER` updates ^S/^Y now as any other text insertion</title>
<updated>2026-01-24T16:19:48+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2026-01-24T16:19:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=59d3c24f198ca4628fb69c8da163f103bafebc43'/>
<id>59d3c24f198ca4628fb69c8da163f103bafebc43</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</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>avoid unnecessary cleanups of recovery files</title>
<updated>2025-12-28T23:42:41+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2025-12-28T23:31:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=713462dfdf3c46a998b43525cbbf5ae0ec8ea84b'/>
<id>713462dfdf3c46a998b43525cbbf5ae0ec8ea84b</id>
<content type='text'>
* After the last commit 0b593eb7d0e6907b19cdbb605caf1becae351004
  we tried to clean up (unlink) recovery files for all dirty buffers.
  This resulted in superfluous file deletions before any recovery
  file was dumped; after disabling file recovery and even in
  batch mode.
  It's not tolerable that SciTECO scripts try to unlink files
  as a side effect e.g. of EW.
  Also, sometimes you may have to clean up recovery dumps even
  in batch mode, e.g. in Quit hooks.
* Also, it was broken for dirty unnamed buffers, which would
  cause glib errors.
* That's why we had to add another buffer state for
  dirty files with outdated recovery dumps (TECO_BUFFER_DIRTY_OUTDATED_DUMP).
  Once a dump was written, a buffer never directly transitions
  into the TECO_BUFFER_DIRTY_NO_DUMP state again.
  We can now reliably unlink() only where we'd expect a
  recovery file to exist in the first place.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* After the last commit 0b593eb7d0e6907b19cdbb605caf1becae351004
  we tried to clean up (unlink) recovery files for all dirty buffers.
  This resulted in superfluous file deletions before any recovery
  file was dumped; after disabling file recovery and even in
  batch mode.
  It's not tolerable that SciTECO scripts try to unlink files
  as a side effect e.g. of EW.
  Also, sometimes you may have to clean up recovery dumps even
  in batch mode, e.g. in Quit hooks.
* Also, it was broken for dirty unnamed buffers, which would
  cause glib errors.
* That's why we had to add another buffer state for
  dirty files with outdated recovery dumps (TECO_BUFFER_DIRTY_OUTDATED_DUMP).
  Once a dump was written, a buffer never directly transitions
  into the TECO_BUFFER_DIRTY_NO_DUMP state again.
  We can now reliably unlink() only where we'd expect a
  recovery file to exist in the first place.
</pre>
</div>
</content>
</entry>
<entry>
<title>fixed left-over recovery files</title>
<updated>2025-12-28T20:22:46+00:00</updated>
<author>
<name>Robin Haberkorn</name>
<email>rhaberkorn@fmsbw.de</email>
</author>
<published>2025-12-28T20:22:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.fmsbw.de/sciteco/commit/?id=0b593eb7d0e6907b19cdbb605caf1becae351004'/>
<id>0b593eb7d0e6907b19cdbb605caf1becae351004</id>
<content type='text'>
* It was possible to provoke left-over recovery files even if the editor does *not* crash:
  1. If you dirtified the buffer (state = TECO_BUFFER_DIRTY), it would be dumped to a
     recovery file (TECO_BUFFER_DIRTY_DUMPED).
  2. If you dirtify the buffer again, the state will become TECO_BUFFER_DIRTY again,
     so it's up for dumping in the next cycle.
  3. If you now save and exit (e.g. `:EX`) the recovery file is not deleted since
     the state is not TECO_BUFFER_DIRTY_DUMPED.
* A buffer can have a recovery file both for TECO_BUFFER_DIRTY and TECO_BUFFER_DIRTY_DUMPED,
  so we must clean up afterwards in both states.
* Of course, it may __not__ yet have a recovery file in the TECO_BUFFER_DIRTY state.
  The g_unlink() might therefore be superfluous on those files.
  Moreover, if you disable recovery files, SciTECO will now still try to unlink the
  recovery file.
  These operations could only be avoided by adding yet another state, e.g.
  TECO_BUFFER_DIRTY_OUTDATED_DUMP, so that after the first dump you will never switch
  back into TECO_BUFFER_DIRTY.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* It was possible to provoke left-over recovery files even if the editor does *not* crash:
  1. If you dirtified the buffer (state = TECO_BUFFER_DIRTY), it would be dumped to a
     recovery file (TECO_BUFFER_DIRTY_DUMPED).
  2. If you dirtify the buffer again, the state will become TECO_BUFFER_DIRTY again,
     so it's up for dumping in the next cycle.
  3. If you now save and exit (e.g. `:EX`) the recovery file is not deleted since
     the state is not TECO_BUFFER_DIRTY_DUMPED.
* A buffer can have a recovery file both for TECO_BUFFER_DIRTY and TECO_BUFFER_DIRTY_DUMPED,
  so we must clean up afterwards in both states.
* Of course, it may __not__ yet have a recovery file in the TECO_BUFFER_DIRTY state.
  The g_unlink() might therefore be superfluous on those files.
  Moreover, if you disable recovery files, SciTECO will now still try to unlink the
  recovery file.
  These operations could only be avoided by adding yet another state, e.g.
  TECO_BUFFER_DIRTY_OUTDATED_DUMP, so that after the first dump you will never switch
  back into TECO_BUFFER_DIRTY.
</pre>
</div>
</content>
</entry>
</feed>
