Comments (21)
Hey everyone! This is now available in master
and will be available in the next release. For an example on how to use this new feature have a look at this example.
from bubbletea.
I also wanted to provide some updates on this issue. We're narrowing this ticket to be specific to spawning editors from within Bubble Tea (versus any sub-process), because most other processes (both blocking and non-blocking) can be currently handled fine in a tea.Cmd
.
Anyway, this is something we'd like to officially support in Bubble Tea. There are essentially two things to tackle:
- Spawning editors that block in the Terminal, such Vim. This is an easier case to handle because editors that live in the terminal will block until finished, so it's mostly just a matter of providing what will probably be a special
tea.Cmd
to handle editor spawning and cleanup. - Spawning editors that don't block, such as opening a file in VSCode. This is a more difficult case because it requires file-watching, which comes with a lot of pitfalls, particularly os-specific ones.
In the meantime, for those interested in spawning in-terminal editors like Vim (@antonmedv, @mritd, @knipferrc) I recommend taking a look at edist
, which seems to have a working, albeit hacky, solution. In particular this file illustrates the implementation and there are some detail on some pitfalls in PR#1.
from bubbletea.
Hi! Your code's pretty close. As a rule, you'll want to move all long running code into a tea.Cmd
, which runs in a goroutine internally. tea.Cmd
s return a message when finished, which triggers an update and in, a redraw. So I'd do something roughly like this:
type editingFinished struct{}
func openEditor(app string, args ...string) tea.Cmd {
return func() tea.Msg {
cmd := exec.Command(app, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
_ = cmd.Run() // blocks until finished
return editingFinished{}
}
}
func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.editMode {
return m, nil
}
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "e":
m.editMode = true
return m, tea.Batch(
tea.HideCursor,
openEditor(lookup([]string{"LLAMA_EDITOR", "EDITOR"}, "less"), filepath.Join(m.path, m.cursorFileName())),
)
}
case editingFinished:
m.editMode = false
return m, nil
}
// ...
}
Really nice work on llama, by the way. We actually added tea.HideCursor
for exactly your use case.
And by all means, let us know if you have any more questions.
from bubbletea.
I've just posted a draft PR that adds program.CancelInput
and program.RestoreInput
, as well as a little example demonstrating how to launch an editor: #237
While the PR is not ready to merge just yet, I'd love to hear your feedback: does it fix the swallowed keys issue and stdin crashes/errors for you? (it does for me)
from bubbletea.
@muesli has there been any progress on this front? I'd love to use bubbletea in a project I'm speccing out right now, but this would be a blocking issue. Thanks!
Yep, we're actively working on this, see PR #237.
from bubbletea.
Thanks a lot! 🔥
from bubbletea.
Probably, the right approach will be to use PTY.
from bubbletea.
Sure thing. Here is what I see once I start Vim in a command
from bubbletea.
Yes, using the exec-cancelreader
branch does fix all crashes and swallowed keys, in each of the situations described above. Thanks a lot :)
from bubbletea.
Yes, using the
exec-cancelreader
branch does fix all crashes and swallowed keys, in each of the situations described above.
Thanks for the feedback! I'll clean this PR up a bit and we'll merge this soon!
from bubbletea.
Thanks a lot for your awesome library!
from bubbletea.
For some reason, this approach does not work. And from example, vim and tea outputs get messed up. Can't figure out why. Trying to implement it in llama.
from bubbletea.
Saw your other issue. It's probably unrelated to the above approach and in the end (once we figure it out) you'll mostly likely need to move stuff back into a command (illustrated above) in order a trigger a repaint.
from bubbletea.
I also have the same issue when trying to open a file to edit via vim and then back into the app, the output gets messed up even after triggering a command to cause a repaint
from bubbletea.
I've looked into this one a little bit. No conclusions yet, but my hunch says we'll need to introduce some functionality into Bubble Tea (likely by way of Cmd
s) to do this properly. A few notes so far:
- Opening Vim by blocking in
Update
is reliable for me so far. If Bubble Tea is using the altscreen the Bubble Tea view does not repaint after exiting Vim, even when returning a command liketea.HideCursor
. - Opening Vim via a
tea.Cmd
results in very poor performance in Vim, an occasional input errors. For this approach to work Bubble Tea will likely need some additional functionality to effectively pause portions of the runtime. Opening dedicated TTYs for input in both Bubble Tea and Vim did not help. - When using the alt screen in Bubble Tea, redraws did not occur after exiting Vim, even when requesting to re-enter via
tea.EnterAltScreen
.
Here's an example program I've been testing with.
@knipferrc and @antonmedv: if it's convenient, I'd love to see a screenshot of the garbled output you're describing after closing Vim. I'm not able to reproduce that on my end yet.
from bubbletea.
I tried to integrate github.com/creack/pty but this is quite difficult, we can't just io.Copy, and need to get part of UI as a string.
from bubbletea.
Hi everyone 👋,
Just wanted to chime in and hopefully give some useful pointers.
This discussion is quite similar to one in tcell, another TUI framework which is also written in Go and had the same issue with running subcommands.
Long story short: tcell had a similar issue which was eventually fixed here. I wish I could be more helpful than just refer to the ticket (most of the implementation goes over my head), but I hope that the implementation can be useful for Bubble Tea.
(Btw, Bubble Tea is really great, I have been eagerly awaiting for this subcommand feature to see of I can replace the current TUI in clx
)
from bubbletea.
I successfully opened vim according to the example, but after vim exited, I received a keymsg:
It looks like this button appears in the standard input after the execution of vim is complete; I don't know what caused it.
@meowgorithm Do you have any suggestions?
from bubbletea.
@mritd That appears to be an open brace ([
, i.e. rune(91)
) which I'm guessing is part of a broken ANSI sequence. Hard to say where it's coming from without more context, however if it's something you're seeing consistently you could add some logic to ignore it after Vim exits.
from bubbletea.
Hello, a few elements that might be helpful :)
I tried to run your example program in several environments (all Linux based):
With kitty (https://sw.kovidgoyal.net/kitty/)
- opening vi:
- some keys have no effect (are "swallowed"). E.g. pressing 'i' twice doesn't display anything. Only happens when vi has just been opened.
- doesn't crash
- cursor OK
- opening neovim (nvim):
- some keys swallowed but harder to reproduce than in vi
- regularly crashes with
Error running program: read /dev/stdin: resource temporarily unavailable exit status 1
(not always but roughly 1 time out of 3) - cursor OK
- opening vim:
- some keys have no effect (same as vi)
- no crashes
- cursor OK
With neovim in kitty (opening a term in neovim with :terminal, then running the example, so we have vi, vim or nvim in nvim)
- opening vi:
- some keys have no effect (same as vi)
- no crashes
- no cursor displayed in vi, cursor reappears when back to the shell
- opening neovim:
- some keys swallowed but harder to reproduce than in vi
- regular crashes related to stdin
- cursor OK
- opening vim:
- some keys swallowed but harder to reproduce than in vi
- no crashes related to stdin
- cursor OK
It seems that the "swallowed" keys are interpreted by bubbletea. E.g. typing q at as your first key will sometimes lead to exiting the go program as soon as vi exits.
I tried the same experiments with xterm and the results were consistent with those above.
All these tests have been run with "vim/nvim -u NONE" to limit the influence of my vim config.
Thank you for your work on the charm projects, they are very fun to use :)
from bubbletea.
@muesli has there been any progress on this front? I'd love to use bubbletea in a project I'm speccing out right now, but this would be a blocking issue. Thanks!
from bubbletea.
Related Issues (20)
- First line not rendering until event happens HOT 3
- Part of the screen is not rendering when the view is exactly the size of the screen HOT 3
- Proposal: Model v2, program context HOT 1
- Exiting fullscreen glitch when also removing a line in output HOT 2
- Proposal: use x/input to handle input events HOT 1
- `tea.unknownCSISequenceMsg: unknown message type` panics HOT 3
- The visible area in viewport may seem incorrect when content exceed the viewport.Width HOT 10
- Flickering on Windows when using bubbletea >=0.26.0 HOT 2
- SetWindowTitle panic after upgrade from v0.26.2 -> v0.26.3 HOT 1
- When a large update is performed, it will cause a flash. HOT 1
- PR #1033 broke the tabs example HOT 2
- go version in go.mod is outdated HOT 2
- does Update() get called even when there are no keys being pressed?
- Can't write japanese characters in inputfield HOT 2
- Exit with error message to stderr and non-zero status code
- Async Clipboard
- Automatic command chaining: Cmd -> Cmd -> Msg HOT 1
- Allow WindowSizeMsg to be sent on sub-model Init HOT 5
- Progress bar behaving strangely
- Any support for charts?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bubbletea.