This is a feature found in vim and commonly used
by Linux kernel test robots to give context about
warnings and/or failures.
e.g. vim +/imem_size +623 drivers/net/ipa/ipa_mem.c
The order in which the commands appear in the args
determines in which order the "goto line:column"
and search will be executed.
Micro's logic for periodic backup creation is racy and may cause
spurious backups of unmodified buffers, at least for the following
reasons:
1. When a buffer is closed, its backup is removed by the main goroutine,
without any synchronization with the backup/save goroutine which
creates periodic backups in the background.
A part of the problem here is that the main goroutine removes the
backup before setting b.fini to true, not after it, so the
backup/save goroutine may start creating a new backup even after it
has been removed by the main goroutine. But even if we move the
b.RemoveBackup() call after setting b.fini, it will not solve the
problem, since the backup/save goroutine may have already started
creating a new periodic backup just before b.fini was set to true.
2. When a buffer is successfully saved and thus its backup is removed,
if there was a periodic backup for this buffer requested by the main
goroutine but not saved by the backup/save goroutine yet (i.e. this
request is still pending in backupRequestChan), micro doesn't cancel
this pending request, so a backup is unexpectedly saved a couple of
seconds after the file itself was saved.
Although usually this erroneous backup is removed later, when the
buffer is closed. But if micro terminates abnormally and the buffer
is not properly closed, this backup is not removed. Also if this
issue occurs in combination with the race issue #1 described above,
this backup may not be successfully removed either.
So, to fix these issues:
1. Do the backup removal in the backup/save goroutine (at requests from
the main goroutine), not directly in the main goroutine.
2. Make the communication between these goroutines fully synchronous:
2a. Instead of using the buffered channel backupRequestChan as a storage
for pending requests for periodic backups, let the backup/save
goroutine itself store this information, in the requestesBackups
map. Then, backupRequestChan can be made non-buffered.
2b. Make saveRequestChan a non-buffered channel as well. (There was no
point in making it buffered in the first place, actually.) Once both
channels are non-buffered, the backup/save goroutine receives both
backup and save requests from the main goroutine in exactly the same
order as the main goroutine sends them, so we can guarantee that
saving the buffer will cancel the previous pending backup request
for this buffer.
Micro "allows" plugins to register colorschemes via
config.AddRuntimeFile(). However, that has never really worked, since
InitColorscheme() is called earlier than plugins init() or even
preinit() callbacks are called.
To work around that, plugins that use it (e.g. nord-tc [1]) are using a
tricky hack: call config.AddRuntimeFile() not in init() or preinit() but
directly in Lua's global scope, so that it is called earlier, when the
plugin's Lua code is loaded. This hack is not guaranteed to work, and
works by chance. Furthermore, it only works when starting micro, and
doesn't work after the `reload` command. (The reason it doesn't work is
that PluginAddRuntimeFile() calls FindPlugin() which calls IsLoaded()
which returns false, since, well, the plugin is not loaded, it is only
being loaded. And the reason why it works when starting micro is that
in that case IsLoaded() confusingly returns true, since
GlobalSettings[p.Name] has not been set yet.)
So move InitColorscheme() call after calling plugins init/preinit/
postinit callbacks, to let plugins successfully register colorschemes
in any of those callbacks instead of using the aforementioned hack.
[1] https://github.com/KiranWells/micro-nord-tc-colors
Fix regression caused by the fix 0de16334d3 ("micro: Don't forward
nil events into the sub event handler"): even if the terminal was
started with `wait` set to false, it is not closed immediately after
it finished its job, instead it shows "Press enter to close".
The reason is that since the commit b68461cf72 ("Terminal plugin
callback support") the termpane code has been (slightly hackily) relying
on nil events as notifications to close the terminal after it finished
its job. So fix this by introducing a separate CloseTerms() function
for notifying termpanes about that, decoupled from HandleEvent() which
is for tcell events only.
Implement a radical approach to improving abilities of plugins to detect
and handle various changes of micro's state: add onAnyEvent callback
which is called, literally, after any event. A plugin can use this
callback to compare a state after the previous event and after the
current event, and thus is able to catch various events that cannot be
detected using other callbacks.
Some examples of such events:
- change of current working directory
- switching cursor focus between a bufpane and the command bar
- change of message text in the status bar
* rtfiles: Initialize all-/realFiles and Plugins in InitRuntimeFiles
* command: Reload plugins at ReloadCmd too
* command: Don't reload plugins in case of ReloadConfig()
* rtfiles: Split InitRuntimeFiles() into one func for assets and one for plugins
* rtfiles: Remove the unnecessary init function
With this modification the InitRuntimeFiles() and InitPlugins() (if needed)
must be called first, otherwise uninitialized runtime file variables are most
likely.
InfoBar should really receive the resize event, to know the window width
in order to do horizontal scrolling of the command line when it doesn't
fit in the screen. Although currently it doesn't scroll the command line
at all (see issue #2527) and just ignores the resize event, but we
should fix that anyway, so let's forward the resize event to it.
Exposing locking primitives to lua plugins is tricky and may lead to
deadlocks. Instead, if possible, it's better to ensure all the needed
synchonization in micro itself, without leaving this burden to lua code.
Since we've added micro.After() timer API and removed exposing Go timers
directly to lua, now we (probably?) have no cases of lua code possibly
running asynchronously without micro controlling when it is running. So
now we can remove lua.Lock.
This means breaking compatibility, but, until recently lua.Lock wasn't
workable at all (see #2945), which suggests that it has never been
really used by anyone. So it should be safe to remove it.
Directly using Go's time.AfterFunc() from lua is tricky. First, it
requires the lua timer callback to explicitly lock ulua.Lock to prevent
races. Second, it requires the lua timer callback to explicitly redraw
the screen if the callback changes the screen contents (see #2923).
So instead provide micro's own timer API which ensures both
synchronization and redrawing on its own, instead of leaving this burden
to lua code. In fact, its implementation runs the lua timer callback in
the main micro's goroutine (i.e. from micro's perspective it is
synchronous, not asynchronous), so both redrawing and synchronization
are ensured automatically.
Fixes#2923
Passing options via micro -option=value in the command line should only
temporarily override the option value for the current micro session,
not change it permanently in settings.json. But currently it wrongly
writes it to settings.json in the case when the value passed via command
line is the default value of this option, while the current permanent
setting in settings.json is a non-default value.
Fixes#3005
There is already a commented-out code in main() for enabling CPU
profiling of micro, which is often useful. Adjust it to allow enabling
it just by providing -profile flag on the command line, without
modifying and recompiling the code.