Commit Graph

859 Commits

Author SHA1 Message Date
Dmytro Maluka
118f5a3e35 gofmt fix 2025-12-03 01:19:35 +01:00
Mikko
70dfc7fcb4 fix drawing of wide characters in InfoWindow (#3919) 2025-11-27 19:45:30 +01:00
Jöran Karl
a2620d1c02 Merge pull request #3914 from matthias314/m3/fix-issue-3700
quick fix for #3700
2025-11-27 19:24:52 +01:00
matthias314
560bfcf749 ensure regexp error messages are displayed in findCallback 2025-11-25 17:19:26 -05:00
matthias314
a577fc95ff handle regexps with missing \E (quick fix for #3700) 2025-11-25 17:19:26 -05:00
Jöran Karl
bc5e59c670 Merge pull request #3618 from Neko-Box-Coder/LockConfig
Removing the ability for plugins to modify settings.json and bindings.json. Adding an option to reject plugins to bind keys.
2025-11-18 21:28:19 +01:00
Neko Box Coder
4f1d2bb543 Adding lockbindings option for disallowing lua to modify bindings at all 2025-11-18 19:12:20 +00:00
Neko Box Coder
7a250b7df4 Changing behavior for SetGlobalOption*() for lua to not write to file 2025-11-18 19:12:05 +00:00
Neko Box Coder
b39b5b5916 Changing behavior for TryBindKey() for lua to not write to bindings.json 2025-11-18 19:12:04 +00:00
Jöran Karl
bab39079b3 save: Remove a possible written backup in case the path has changed 2025-10-18 21:07:07 +02:00
Jöran Karl
02611f4ad2 backup: Keep path of stored & hashed backup files in a own $hash.path file
Since full escaped backup paths can become longer than the maximum filename size
and hashed filenames cannot be restored it is helpful to have a lookup file for
the user to resolve the hashed path.
2025-10-18 21:07:06 +02:00
Jöran Karl
1ce2202d9a util: Convert suffix added with AppendBackupSuffix() to simple constant 2025-10-18 21:06:47 +02:00
Jöran Karl
78d2c617ed util: Hash the path in DetermineEscapePath()
...in case the escaped path exceeds the file name length limit
2025-10-18 21:05:56 +02:00
niten94
85b4b2b788 Disable sudo save prompt on Windows
Display message stating that saving with sudo is unsupported on Windows,
immediately without a prompt when permission is denied.
2025-09-21 00:30:07 +08:00
Jöran Karl
45342bb0f1 Merge pull request #3760 from Neko-Box-Coder/MoreCharOptions
Adding indenttabchar, indentspacechar and spacechar options
2025-09-06 18:53:09 +02:00
Neko Box Coder
1ef6459846 Adding showchars option 2025-09-06 16:48:01 +01:00
Neko Box Coder
532c315f79 Simplifying draw to be less nested 2025-09-06 16:46:50 +01:00
Neko Box Coder
7b01fe4f56 Splitting draw out to getRuneStyle in bufwindow, removing @ for wide rune in bufwindow 2025-09-06 16:42:40 +01:00
cutelisp
0b9c7c0c4a Add toggle & togglelocal command (#3783) 2025-09-05 20:56:02 +02:00
Luca Stefani
e9f241af71 micro: Handle +/regex search from args (#3767)
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.
2025-09-05 20:53:37 +02:00
deepdring
b8057f28c6 refactor: use a more modern writing style to simplify code (#3834)
Signed-off-by: deepdring <deepdrink@icloud.com>
2025-08-26 02:00:51 +02:00
Dmytro Maluka
094b02da4c plugin installer: Remove extra spaces in log messages 2025-08-20 22:19:47 +02:00
Dmytro Maluka
7a252f4986 Merge pull request #3810 from Neko-Box-Coder/ShowBuiltinPlugins
Adding the ability to differentiate builtin plugins when listing
2025-08-20 22:05:07 +02:00
Jöran Karl
1dbb058773 Merge pull request #3814 from JoeKar/fix/sudo-save
save: Use `dd` with the `notrunc` & `fsync` and postpone truncation
2025-08-12 19:37:16 +02:00
Neko Box Coder
177f4d5b01 Updating remove plugin message to specify plugin name 2025-08-09 10:58:16 +01:00
Jöran Karl
165a5a4896 save: Use dd with the notrunc & fsync option
Using notrunc  will stop the overall truncation of the target file done by sudo.
We need to do this because dd, like other coreutils, already truncates the file
on open(). In case we can't store the backup file afterwards we would end up in
a truncated file for which the user has no write permission by default.
Instead we use a second call of `dd` to perform the necessary truncation
on the command line.
With the fsync option we force the dd process to synchronize the written file
to the underlying device.
2025-08-06 20:13:36 +02:00
Dmytro Maluka
0a9fa4f2ea Always use temporary file when writing backup
When writing a backup file, we should write it atomically (i.e. use a
temporary file + rename) in all cases, not only when replacing an
existing backup. Just like we do in util.SafeWrite(). Otherwise, if
micro crashes while writing this backup, even if that doesn't result
in corrupting an existing good backup, it still results in creating
an undesired backup with invalid contents.
2025-08-03 18:41:34 +02:00
Dmytro Maluka
a862c9709e Unify backup write logic
Use the same backup write helper function for both periodic
background backups and for temporary backups in safeWrite().

Besides just removing code duplication, this brings the advantages
of both together:

- Temporary backups in safeWrite() now use the same atomic mechanism
  when replacing an already existing backup. So that if micro crashes
  in the middle of writing the backup in safeWrite(), this corrupted
  backup will not overwrite a previous good backup.

- Better error handling for periodic backups.
2025-08-03 18:37:00 +02:00
Dmytro Maluka
04b878bc2d Ignore the backup option when removing backup
When we need to remove existing backup for whatever reason (e.g. because
we've just successfully saved the file), we should do that regardless of
whether backups are enabled or not, since a backup may exist regardless
(it could have been created before the `backup` option got disabled).
2025-08-03 16:32:25 +02:00
Dmytro Maluka
7aa495fd3f Remove backup when buffer becomes unmodified
We should cancel previously requested periodic backup (and remove this
backup if it has already been created) not only when saving or closing
the buffer but also in other cases when the buffer's state changes from
modified to unmodified, i.e. when the user undoes all unsaved changes.

Otherwise, if micro terminates abnormally before the buffer is closed,
this backup will not get removed (so next time micro will suggest the
user to recover this file), even though all changes to this file were
successfully saved.
2025-08-03 16:17:53 +02:00
Dmytro Maluka
2c010afbe4 Fix races between removing backups and creating periodic backups
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.
2025-08-03 16:17:03 +02:00
Dmytro Maluka
e84d44d451 Move backup & save related stuff from Buffer to SharedBuffer
Various methods of Buffer should be rather methods of SharedBuffer. This
commit doesn't move all of them to SharedBuffer yet, only those that
need to be moved to SharedBuffer in order to be able to request creating
or removing backups in other SharedBuffer methods.
2025-08-03 14:53:29 +02:00
Dmytro Maluka
f938f62e31 Make isModified reflect actual modified/unmodified state of buffer
Instead of calculating the hash of the buffer every time Modified() is
called, do that every time b.isModified is updated (i.e. every time the
buffer is modified) and set b.isModified value accordingly.

This change means that the hash will be recalculated every time the user
types or deletes a character. But that is what already happens anyway,
since inserting or deleting characters triggers redrawing the display,
in particular redrawing the status line, which triggers Modified() in
order to show the up-to-date modified/unmodified status in the status
line. And with this change, we will be able to check this status
more than once during a single "handle event & redraw" cycle, while
still recalculating the hash only once.
2025-08-03 14:48:26 +02:00
Dmytro Maluka
4ade5cdf24 Make calcHash() a method of SharedBuffer
This will make it easier to use calcHash() in other SharedBuffer
methods.
2025-08-03 14:47:27 +02:00
Neko Box Coder
21edb89693 Adding explicit checks for initlua for different plugin commands 2025-07-30 01:15:58 +01:00
Neko Box Coder
1096c4f3ba Adding the ability to differenitate builtin plugins when listing 2025-07-29 23:00:55 +01:00
Jöran Karl
87ce5738e1 save: gofmt 2025-07-23 22:00:10 +02:00
Neko Box Coder
d7e43d4974 Adding missing file closes, rewriting safeWrite() to be more robust (#3807) 2025-07-22 22:58:18 +02:00
cutelisp
3a7705a090 Enhance GetNativeValue 2025-07-11 11:21:40 +02:00
blamedrop
55a553041b Update log buffer name as well
Using such fake path have some issues as mentioned in https://github.com/zyedidia/micro/pull/3791#discussion_r2176197355 comment
2025-07-09 00:47:15 +02:00
blamedrop
532a229c57 Add buffer name for raw pane 2025-07-09 00:47:15 +02:00
Dmytro Maluka
41b912b539 Merge pull request #3779 from dmaluka/on-pre-mouse-pass-te
Pass mouse info to {on,pre}MouseXXX callbacks
2025-06-29 22:46:10 +02:00
Jöran Karl
da02f836ff Merge pull request #3761 from dmaluka/colorscheme-plugins-regression-fix
Fix non-working colorscheme plugins
2025-06-25 20:57:49 +02:00
Dmytro Maluka
73066fb69b Disable early validation of colorscheme option
Adding early validation of options in ReadSettings() caused a regression:
colorschemes registered by plugins via config.AddRuntimeFile() stopped
working, since ReadSettings() is called when plugins are not initialized
(or even loaded) yet, so a colorscheme is not registered yet and thus
its validation fails.

Fix that with an ad-hoc fix: treat the "colorscheme" option as a special
case and do not verify it early when reading settings.json, postponing
that until the moment when we try to load this colorscheme.
2025-06-24 22:24:47 +02:00
Dmytro Maluka
baa632e6cc Remove PluginCBRune()
Now that we can pass extra args directly to PluginCB(), we can remove
PluginCBRune() for simplicity.
2025-06-21 03:09:55 +02:00
Dmytro Maluka
7861b00cd1 Pass mouse info to {on,pre}MouseXXX callbacks
Pass *tcell.EventMouse to action callbacks for "mouse actions", i.e. to
onMousePress, preMouseDrag and so on, similarly to how we pass it to lua
functions bound to mouse events.
2025-06-21 03:06:48 +02:00
Dmytro Maluka
54ba3cdb4f Make PluginCB() a variadic function
So that we can pass extra arguments to bufpane callbacks easily, by
passing them directly to PluginCB().
2025-06-21 03:04:37 +02:00
cutelisp
5eddf5b85d Change MainTab calls (#3750)
Swaping `MainTab` calls to `h.tab` will not change the normal micro
behaviour.
This changes will make possible to call `ForceQuit`, `VSplitIndex` and
`HSplitIndex` for tabs that aren't main one.
2025-05-26 22:07:14 +02:00
Jöran Karl
cd0dc9a701 options: Add truecolor to control the usage (#2867)
- `auto`: enable usage of true color if it is supported, otherwise disable it
- `on`: force usage of true color
- `off`: disable true color usage

Co-authored-by: Dmytro Maluka <dmitrymaluka@gmail.com>
2025-05-26 18:25:07 +02:00
Dmytro Maluka
98ff79dbca Relocate buffer view after setting options that affect it (#3743)
Whenever the user changes the value of an option that affects the
calculation of display params in updateDisplayInfo(), we should
immediately recalculate those params and relocate the buffer view
accordingly.

For example: after enabling ruler via `set ruler on`, if the cursor is
currently at the rightmost edge of the bufpane and softwrap is disabled,
then the cursor becomes invisible (since it is now outside the view,
since the buffer view width is decreased as a result of adding the ruler
but StartCol is not updated accordingly), it only becomes visible again
after the user types a character (or performs some other action that
triggers updateDisplayInfo() + relocate). Fix it.
2025-05-11 16:20:23 +02:00