Skip to content

Conversation

@Profpatsch
Copy link

There is no really good way to create a new tab
that’s not bound to a specific file on disk without this function. Now you can create a new buffer from string, pass it to this function and add the resulting tab to the tabs list.

It’s still not particularly ergonomic, but at least it’s possible with a few lines of boilerplate.

I might have missed something else to do here.

There is no really good way to create a new tab
that’s not bound to a specific file on disk without
this function. Now you can create a new buffer from string,
pass it to this function and add the resulting tab to the tabs list.

It’s still not particularly ergonomic, but at least it’s possible
with a few lines of boilerplate.
@dmaluka
Copy link
Collaborator

dmaluka commented Sep 27, 2025

Initial obvious thoughts:

  1. This NewTabFromBuffer interface is stupid. Why on earth does it need these x, y, width, height to be passed to it, if it can easily find them out on its own?

As long as this is just micro's internal API, it is only our (micro developers') pain and embarrassment. We may fix it or we may not.

But if we are to expose this interface to Lua (and then, among other things, keep it forever for backward compatibility), we ought to clean this mess first.

  1. Isn't it a bit too low-level to expose it to Lua? It creates just an orphaned invisible tab, what use would it be to a plugin? A plugin would need at least to manually call Tabs.AddTab() to make it useful. And if the plugin doesn't do that, wouldn't the possible existence of such a "hidden" tab cause various subtle issues (like, the same file may be opened in 2 tabs: in a real visible tab and in this hidden one, so when the user closes the visible tab, micro doesn't ask to save unsaved changes in the file, since from micro's point of view the file is not quite closed yet, it is still open in the hidden tab)?

So shouldn't we rather expose a function that not just creates a tab but at least adds it to the tab list on its own?

@Profpatsch
Copy link
Author

Yes, if I grep through the source every place that uses this in the source code does a non-atomic add to the tab list right after, so I propose refactoring this before exposing more things to the Lua API.

As it stands, all Lua stuff is just the internal editor API (except for some things, which is highly confusing tbh)

@dmaluka
Copy link
Collaborator

dmaluka commented Oct 7, 2025

As it stands, all Lua stuff is just the internal editor API (except for some things, which is highly confusing tbh)

Yes, it is confusing and unfortunate. I wrote about that many times, for example here or here.

I mean, IMO the (unfixable) problem is not that we don't expose everything, but quite the opposite, that we expose too much (most of it not on purpose), which makes it quite powerful (which is both a good and a bad thing) but also very messy.

Anyway, for those exposed interfaces that we do document in plugins.md, we do expose them on purpose and thus we should care about their quality and preserving their compatibility.

@Profpatsch
Copy link
Author

I’d be okay with creating a specific plugin API that is designed to be used from lua and separate from the internal package docs, even if it means breaking backwards-compatibility.

Bonus points if the documentation is trivial to query from the command line (e.g. `micro --print-plugin-api) because to be honest it’s way easier to write Lua plugins if an LLM agent does it for you :P

@Neko-Box-Coder
Copy link
Contributor

Couldn't you do the same thing by running the NewTabCmd() and just get the buffer with micro.CurPane().Buf?

Unless you have a reason to hoist the *Tab and not add it to the tab bar?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants