<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rneovim.git/src/nvim/lua/executor.c, branch extregs</title>
<subtitle>Neovim fork with Rahm's personal hacks.</subtitle>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/'/>
<entry>
<title>[extregs] implement tab completion for ~ menu.</title>
<updated>2026-10-19T00:43:26+00:00</updated>
<author>
<name>Josh Rahm</name>
<email>joshuarahm@gmail.com</email>
</author>
<published>2026-10-19T00:43:26+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=41be894eb2e8d02c052ad4e85962550c54ae4589'/>
<id>41be894eb2e8d02c052ad4e85962550c54ae4589</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[extregs] implemented aliases.</title>
<updated>2026-10-18T06:33:03+00:00</updated>
<author>
<name>Josh Rahm</name>
<email>joshuarahm@gmail.com</email>
</author>
<published>2026-10-16T07:40:33+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=a33594631bcbef898ed97b5fd460ee28cde60f9d'/>
<id>a33594631bcbef898ed97b5fd460ee28cde60f9d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[extregs] switch to a hash map for an arbitrary number of extregs.</title>
<updated>2026-10-18T06:30:48+00:00</updated>
<author>
<name>Josh Rahm</name>
<email>joshuarahm@gmail.com</email>
</author>
<published>2026-10-14T22:34:51+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=6f7f01c20e21321c6bd00a891d7c6f94686154a9'/>
<id>6f7f01c20e21321c6bd00a891d7c6f94686154a9</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[feat] extregisters</title>
<updated>2026-10-18T06:28:27+00:00</updated>
<author>
<name>Josh Rahm</name>
<email>joshuarahm@gmail.com</email>
</author>
<published>2026-10-14T04:11:33+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=22d8bf3861234480aa6afed90a1faaaac3d49520'/>
<id>22d8bf3861234480aa6afed90a1faaaac3d49520</id>
<content type='text'>
Implements "extended registers"

Extended registers provide access to a separate namespace of registers
backed by custom lua callback functions.

A new special register ("~) is introduced, which prompts the user for
the name of an extregistr to yank or paste from.

This enables file-backed or cloud-synced or other arbitrary register
behavior.

One can now use:

`"~file_extreg&lt;cr&gt;yy`

to yank into the "file_extreg" register.

AI-assisted: Qwen3-Coder
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Implements "extended registers"

Extended registers provide access to a separate namespace of registers
backed by custom lua callback functions.

A new special register ("~) is introduced, which prompts the user for
the name of an extregistr to yank or paste from.

This enables file-backed or cloud-synced or other arbitrary register
behavior.

One can now use:

`"~file_extreg&lt;cr&gt;yy`

to yank into the "file_extreg" register.

AI-assisted: Qwen3-Coder
</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lua): regression with `print()` in headless mode</title>
<updated>2026-10-06T09:05:43+00:00</updated>
<author>
<name>bfredl</name>
<email>bjorn.linse@gmail.com</email>
</author>
<published>2026-10-03T11:20:33+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=adc0700dc4589e59de2c17a2f8cfc2ba2fb1181f'/>
<id>adc0700dc4589e59de2c17a2f8cfc2ba2fb1181f</id>
<content type='text'>
This is a bunch of hacks so we can override msg_puts_printf specifically
while still allowing redirecting and "normal" message flow to happen,
as this still has observable side-effects (even with no screen attached,
screenstring() is still valid..)

fixes #42218
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is a bunch of hacks so we can override msg_puts_printf specifically
while still allowing redirecting and "normal" message flow to happen,
as this still has observable side-effects (even with no screen attached,
screenstring() is still valid..)

fixes #42218
</pre>
</div>
</content>
</entry>
<entry>
<title>feat(lua): in script mode -l, use raw output for print()</title>
<updated>2026-10-02T09:43:56+00:00</updated>
<author>
<name>bfredl</name>
<email>bjorn.linse@gmail.com</email>
</author>
<published>2026-09-24T12:31:40+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=58ce7218ec9aa85cc090cee4654e4573f6dd8570'/>
<id>58ce7218ec9aa85cc090cee4654e4573f6dd8570</id>
<content type='text'>
consider the following test_script.lua :

    print 'hello\n' -- TWO new lines
    print 'this is \027[31mRED FOR AN AMAZING REASON\027[0m'
    print 'foo'
    print '' -- newline despite empty!
    print 'bar'

    -- a bit later:
    os.execute 'sleep 2' -- CPU goes BRR, cursor in column zero
    print 'more bar'

before this PR, `nvim -l test_script.lua` had some weird behaviors
compared to `lua test_script.lua` or the now removed `nvim -ll
test_script.lua`.

- one extra '\n' at the end of a print is ignored, one would need
  TWO '\n' for a single extra '\n'

- an empty print'' is supposed to print an empty line

- print'\027[31mRED' is being escaped so it does not work

- the cursor gets stuck at the end of a message, instead of after
  emitting the new line, this looks like the CPU lag has something
  to do with the _last_ printed message which is likely not the case.

I consider these behaviors to be unintentional (a consequence of
stragglig through the message.c meta-machine, which is optimized
for message handling in _an interative text editor_) and getting
closer to plain lua behavior would be better.

An alternative would be to restore the builtin print(), but our
implemenation still has some benefits, like try
`print(setmetatable({}, {__tostring=error})` in plain lua..
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
consider the following test_script.lua :

    print 'hello\n' -- TWO new lines
    print 'this is \027[31mRED FOR AN AMAZING REASON\027[0m'
    print 'foo'
    print '' -- newline despite empty!
    print 'bar'

    -- a bit later:
    os.execute 'sleep 2' -- CPU goes BRR, cursor in column zero
    print 'more bar'

before this PR, `nvim -l test_script.lua` had some weird behaviors
compared to `lua test_script.lua` or the now removed `nvim -ll
test_script.lua`.

- one extra '\n' at the end of a print is ignored, one would need
  TWO '\n' for a single extra '\n'

- an empty print'' is supposed to print an empty line

- print'\027[31mRED' is being escaped so it does not work

- the cursor gets stuck at the end of a message, instead of after
  emitting the new line, this looks like the CPU lag has something
  to do with the _last_ printed message which is likely not the case.

I consider these behaviors to be unintentional (a consequence of
stragglig through the message.c meta-machine, which is optimized
for message handling in _an interative text editor_) and getting
closer to plain lua behavior would be better.

An alternative would be to restore the builtin print(), but our
implemenation still has some benefits, like try
`print(setmetatable({}, {__tostring=error})` in plain lua..
</pre>
</div>
</content>
</entry>
<entry>
<title>fix(api): correct Lua command and completion types</title>
<updated>2026-09-28T13:43:14+00:00</updated>
<author>
<name>Lewis Russell</name>
<email>lewis6991@gmail.com</email>
</author>
<published>2026-09-28T13:19:42+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=b597af006fbb7c94c03ea9e7fa13cab7394b0501'/>
<id>b597af006fbb7c94c03ea9e7fa13cab7394b0501</id>
<content type='text'>
Problem: Command inputs and parsed modifiers have different optional
fields, and completion window IDs are annotated as floating-point
values.

Solution: Separate modifier input and return types, correct integer IDs,
and update the metadata generators and their output.

AI-assisted
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem: Command inputs and parsed modifiers have different optional
fields, and completion window IDs are annotated as floating-point
values.

Solution: Separate modifier input and return types, correct integer IDs,
and update the metadata generators and their output.

AI-assisted
</pre>
</div>
</content>
</entry>
<entry>
<title>fix(strings): non fatal errors for [NULL] safety in vim_snprintf</title>
<updated>2026-09-08T10:46:24+00:00</updated>
<author>
<name>bfredl</name>
<email>bjorn.linse@gmail.com</email>
</author>
<published>2026-09-07T11:39:56+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=97660307f5ac10d01febd7ffba63dfeb24d10351'/>
<id>97660307f5ac10d01febd7ffba63dfeb24d10351</id>
<content type='text'>
context: vim_snprintf provides a "portable" replacement for a system
vsnprintf(). However we rely on system vsnprintf() in places. This
is quite arbitrary. I want to use system vsnprintf() only, and
reduce the machinery in string.c for typval printf only, which will
delet a lot of duplicated code.

The biggest hurdle here is not "portably" (we only support sane c
runtimes) but the following discrepancy: standard libc printf()
considers NULL args to %s to be undefined behavior strictly
while vim_snprintf() _defacto_ allows this by replacement to "[NULL]"

IMO, this should be seen as "graceful" error handling (nicer than crashing
on the user), not a valid means to have the string "[NULL]" intentionally
be shoved in the users face. more robust code should explicitly
check for NULL and replace it with a _appropriate_ fallback for
the situation, depending on what a NULL string actually means in the
context (unnamed buffer? anonymous namespace? global augroup?)

soo, this PR provides the most _gently_ incremental nudge towards
considering this case again as an error one could possible imagine.
If sanitizers are complied in, this minor incursion gets printed
into the sanitizers' log as a "report-and-continue" error with a
traceback. This doesn't annoy the end user or "stop the world"
in the test suite, but the CI will see the reported error and
fail the build, just like other non-fatal CI errors.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
context: vim_snprintf provides a "portable" replacement for a system
vsnprintf(). However we rely on system vsnprintf() in places. This
is quite arbitrary. I want to use system vsnprintf() only, and
reduce the machinery in string.c for typval printf only, which will
delet a lot of duplicated code.

The biggest hurdle here is not "portably" (we only support sane c
runtimes) but the following discrepancy: standard libc printf()
considers NULL args to %s to be undefined behavior strictly
while vim_snprintf() _defacto_ allows this by replacement to "[NULL]"

IMO, this should be seen as "graceful" error handling (nicer than crashing
on the user), not a valid means to have the string "[NULL]" intentionally
be shoved in the users face. more robust code should explicitly
check for NULL and replace it with a _appropriate_ fallback for
the situation, depending on what a NULL string actually means in the
context (unnamed buffer? anonymous namespace? global augroup?)

soo, this PR provides the most _gently_ incremental nudge towards
considering this case again as an error one could possible imagine.
If sanitizers are complied in, this minor incursion gets printed
into the sanitizers' log as a "report-and-continue" error with a
traceback. This doesn't annoy the end user or "stop the world"
in the test suite, but the CI will see the reported error and
fail the build, just like other non-fatal CI errors.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lua): blast radius of broken `_G.debug` #41507</title>
<updated>2026-08-27T10:14:24+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2026-08-27T10:14:24+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=02b0c80422bf8b0ae7a3e839d162bb5e28b81e65'/>
<id>02b0c80422bf8b0ae7a3e839d162bb5e28b81e65</id>
<content type='text'>
Problem:
`nlua_pcall()` references `_G.debug.traceback`. If user code deletes it
or breaks it some other way, various Lua features are broken.

    _G.debug = nil
    vim.schedule(function() end)
    vim.wait(100)

    E5113: Lua chunk: attempt to index a nil value
    stack traceback:
            [C]: in function 'loop_poll'
            [string "vim/_core/editor"]:176: in function 'wait'
            crash.lua:3: in main chunk
    PANIC: unprotected error in call to Lua API (attempt to index a nil value)

Solution:
Check `_G.debug.traceback` before using it as errfunc. If it's broken,
omit the traceback and say so in the error message.

Note: We could cache `_G.debug` in LUA_REGISTRYINDEX on startup, but
that would prevent plugins from providing custom functionality there
(and we happen to do so in `tui_spec.lua` for example).</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
`nlua_pcall()` references `_G.debug.traceback`. If user code deletes it
or breaks it some other way, various Lua features are broken.

    _G.debug = nil
    vim.schedule(function() end)
    vim.wait(100)

    E5113: Lua chunk: attempt to index a nil value
    stack traceback:
            [C]: in function 'loop_poll'
            [string "vim/_core/editor"]:176: in function 'wait'
            crash.lua:3: in main chunk
    PANIC: unprotected error in call to Lua API (attempt to index a nil value)

Solution:
Check `_G.debug.traceback` before using it as errfunc. If it's broken,
omit the traceback and say so in the error message.

Note: We could cache `_G.debug` in LUA_REGISTRYINDEX on startup, but
that would prevent plugins from providing custom functionality there
(and we happen to do so in `tui_spec.lua` for example).</pre>
</div>
</content>
</entry>
<entry>
<title>fix(lifecycle): Lua state not freed if free_all_mem() is re-entered #41366</title>
<updated>2026-08-18T12:30:42+00:00</updated>
<author>
<name>Justin M. Keyes</name>
<email>justinkz@gmail.com</email>
</author>
<published>2026-08-18T12:30:42+00:00</published>
<link rel='alternate' type='text/html' href='http://git.josher.dev/rneovim.git/commit/?id=1eae512285e7131f4bf48416f9d4b8b1124e223a'/>
<id>1eae512285e7131f4bf48416f9d4b8b1124e223a</id>
<content type='text'>
Problem:
Leak reported by ASAN CI, always at Lua state init.

      ERROR: LeakSanitizer: detected memory leaks
          strbuf_init src/cjson/strbuf.c:62:22
          json_create_config src/cjson/lua_cjson.c:635:5
          lua_cjson_new src/cjson/lua_cjson.c:2060:5
          nlua_state_add_stdlib src/nvim/lua/stdlib.c:840:3
          nlua_state_init src/nvim/lua/executor.c:973:3
      ...
      SUMMARY: AddressSanitizer: 1055 byte(s) leaked in 2 allocation(s).

Analysis:
`getout()` may run during `free_all_mem()` (that's why it checks
`!entered_free_all_mem`). If that happens, the second `os_exit()`
returns early from `free_all_mem()` then `exit()` is called and Lua
state is never closed.

Solution:
Always call `nlua_free_all_mem()` in the early-return case.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Problem:
Leak reported by ASAN CI, always at Lua state init.

      ERROR: LeakSanitizer: detected memory leaks
          strbuf_init src/cjson/strbuf.c:62:22
          json_create_config src/cjson/lua_cjson.c:635:5
          lua_cjson_new src/cjson/lua_cjson.c:2060:5
          nlua_state_add_stdlib src/nvim/lua/stdlib.c:840:3
          nlua_state_init src/nvim/lua/executor.c:973:3
      ...
      SUMMARY: AddressSanitizer: 1055 byte(s) leaked in 2 allocation(s).

Analysis:
`getout()` may run during `free_all_mem()` (that's why it checks
`!entered_free_all_mem`). If that happens, the second `os_exit()`
returns early from `free_all_mem()` then `exit()` is called and Lua
state is never closed.

Solution:
Always call `nlua_free_all_mem()` in the early-return case.</pre>
</div>
</content>
</entry>
</feed>
