Closed rfgamaral closed 6 years ago
I don't know the deeper difference of SESSION_PTY_DATA
and SESSION_ADD_DATA
, but I do know that SESSION_PTY_DATA
is adding text to xterm.js but not the real terminal.
So dispatching this:
({ data, uid }) => ({
type: 'SESSION_PTY_DATA',
data,
uid,
now: Number(new Date()),
});
will add text to xterm, but it will not go into real terminal, so when hitting return, real terminal just don't know you have inserted some text.
And old ways:
// term is get from decorateTerm's onDecorated
const terminal = term.keyboard.terminal;
terminal.io.sendString('some command');
is not working either, since in hyper2.0 there is no keyboard
in term object, term.io
is not found too.
I am also waiting for an answer, maybe hyper should export more command exec related xterm.js API to extensions.
I get reference in decorateTerm
like this:
export default (Term: ComponentType<*>) =>
class DecorateTerm extends Component<*> {
render() {
return (
<Term
{...this.props}
onDecorated={terminal => {
if (this.props.onDecorated) this.props.onDecorated(terminal);
window.CLI2GUI_TERMINAL_REFERENCE = terminal;
}}
/>
);
}
};
And window.CLI2GUI_TERMINAL_REFERENCE.term
is:
There is no function to insert commands.
Another thread discussing this https://github.com/zeit/hyper/issues/2754
There is term.write()
hidden in the proto chain, It can write text to xterm.js, but not the real terminal.
I think when the user presses a key, the term will dispatch SESSION_USER_DATA action with the key value. https://github.com/zeit/hyper/blob/a14c55640c47c4e294095e50a610c5e77d2fad22/lib/containers/terms.js#L53 after the main process receives the user input, the value will be written into the corresponding session which I think it is a terminal instance. https://github.com/zeit/hyper/blob/a14c55640c47c4e294095e50a610c5e77d2fad22/app/session.js#L89
after the data has been handled. the renderer process will receive the output. and dispatch SESSION_PTY_DATA
and SESSION_ADD_DATA
, Finally, it will be shown on the canvas.
https://github.com/zeit/hyper/blob/a14c55640c47c4e294095e50a610c5e77d2fad22/lib/store/write-middleware.js#L10
above is my understand. If wrong, welcome to correct me.
@ivanwonder So you think this RPC ↓ https://github.com/zeit/hyper/blob/canary/lib/actions/sessions.js#L158 will result in this ↓ call? https://github.com/zeit/hyper/blob/a14c55640c47c4e294095e50a610c5e77d2fad22/app/session.js#L89 I think to understand the relation between I should read more code.
But good news! I found that this plugin is still working: https://github.com/curz46/hyper-startup/blob/master/index.js So to execute a command, just
win.sessions.get(uid).write(cmd + '\r');
where win
comes from onWindow
.
For input recording, you can have a look at hyper-history or my refactored implementation.
But It seems to execute the command in the main thread. I don't know whether it will work in tty like ssh.
So I think this issue can be closed.
I don't see how that solves my issue so I'm hesitant in closing it. Care to provide a basic plugin example on how to achieve what I asked on the first post?
why do you need a plugin to execute a command, and what problem the plugin wants to resolve.
@ivanwonder It's somewhat explained in the original post, I'm trying to solve an issue hharnisc/hypercwd#16 and I can't think of a different way.
@rfgamaral Does hyper-startup
run in Linux subsystem? It is working at least in Mac OS.
@linonetwo It doesn't, just tried:
commands: ['echo "hello world"'],
localPlugins: [
'hyper-startup'
],
After launching Hyper with that configuration:
win.sessions.get(uid).write(cmd + '\r');
in onWindow
maybe broken in windows or Windows Subsystem for Linux.
Even if it worked, I was going to see the output of the command on the Hyper window, right? Because the idea where would be to run a command in the context of the current WSL session, get the output from that command but never show any signs of that to the user.
Maybe you can try import { exec } from 'child_process';
's exec. And exec in main process likes onWindow or onApp, if you have hyper running in WSL.
Yes @linonetwo, you need to send the correct CWD too, check: https://github.com/Hyperline/hyperline/blob/master/src/lib/plugins/git-status.js#L56-L58 how hyperline is doing it.
I'm a little bit confused, could you guys provide a very basic plugin example where one could run a command like lsof | grep cwd
and get the returned value assigned to a variable that I could use within the plugin?
@linonetwo @albinekb Can you help me out with an example of the above please?
Hey @rfgamaral , try https://github.com/linonetwo/hyper-visual/blob/master/src/onWindow.js#L7
@linonetwo I'm trying your plugin to see how ti works but it doesn't even load for me... I've removed all plugins and even started from scratch by removing .hyper_plugins/node_modules
and hyper-visual
is installed but it' never loaded when I launch Hyper. There's no error message and the dev tools console is empty.
@rfgamaral That's true, https://github.com/zeit/hyper/issues/3013 But it really works in dev mode. You can try using that code into your plugin. I don't know why my plugin doesn't load. And hyper's developer is too busy to reply.
I was testing your plugin first to quickly check if your approach worked or not and how it worked. But maybe you can answer me this quickly... Does your plugin write the command (when you click it on the quick suggestion) to the terminal in a visible way to the user and you also see the output on the same window, correct?
@rfgamaral Yes. But if you want to exec command silently, you can just replace that line of code to exec('some command')
where import exec from 'child_process'
.
@linonetwo Unfortunately that doesn't work, exec
runs in the context of system running Hyper and not in the running Hyper shell.
It doesn't help me because I run Hyper on Windows and the shell is Windows Subsystem for Linux (WSL). When I use exec
it's like running a command inside cmd.exe
, which is not what I'm after. I want to run a silent command inside WSL (and read the result), which is running bash
.
You can read how hyper launches bash
here: https://github.com/zeit/hyper/blob/9a536722f8b0a43e8f3741a033d519864f55a957/app/session.js#L53-L58 @rfgamaral, it's using require('node-pty').spawn
, I think you can do the same in your plugin.
I don't believe that will solve my problem. I don't want to launch bash, I don't want to spawn/exec a new shell, I need to execute a command in the context of the current running shell and read the output of that command. Maybe this is not possible and that's a valid answer for this issue.
Also, I'm no trying to write a plugin but to fix WSL related issues on other plugins. These plugins rely on the current absolute path of the running shell to work. On Windows, they assume Command Prompt/PowerShell and both of these print the absolute path of the current directory into the prompt, which they read from the prompt and do their thing. On Linux, they rely on lsof
and the current running shell PID to read the current directory for that shell. None of these methods work on Windows with WSL (which is a Linux environment running on a Windows host).
Until something like Microsoft/WSL#3174 is implemented (and this will take a while...), I can't think of any other way than to run a command (silently) in the context of the running shell and read it's output, but again, this might not be possible at all. If that's true, I can't think of any other possible workaround to fix these particular plugins issues with WSL.
Wait @rfgamaral , I have another idea.
You can use win.sessions.get(uid).write(command);
to execute a command, and prevent the result being printed on the screen by hijacking SESSION_PTY_DATA and SESSION_ADD_DATA action after some EXTCUTE_COMMAND action.
Do you think it's an option?
I think that's the only option if you need to execute it in the exact same session but without printing the result, I think it's better to spawn a new instance where you do your headless queries in 👍
@linonetwo It could be, I'd need to test and see how it works. Thank you for the idea.
I think that's the only option if you need to execute it in the exact same session but without printing the result(...)
I didn't want to need to execute it in the exact same session but to achieve what I need to fix WSL issues on those plugins, I can't think of any other way.
I think it's better to spawn a new instance where you do your headless queries in
What doesn't work for what I'm trying to achieve. These plugins rely on the current directory for the current session to work. Spawning a new instance starts at the default working directory, which is no good.
@linonetwo Just tried to implement your idea but I don't think it will work either. And now that I think about it, writing a command into the running instance is not an option. Some of these plugins rely SESSION_ADD_DATA
and they do their thing on this action, meaning that I need to execute my code on these actions too and I can't write something to the window if the user itself is typing there.
You could get the current working directory and then spawn in there? Would that work?
@albinekb Getting the current working directory is actually the problem that I'm trying to solve.
Maybe you can use the same way as hyper-statusline finds the current working directory by pid? https://github.com/henrikdahl/hyper-statusline/blob/master/index.js#L329-L358 @rfgamaral
@albinekb That plugin does not work with WSL. It finds the current working directory by PID on Linux, not on Windows (WSL is Linux but runs under Windows), on Windows reads the prompt instead (which works fine for Command Prompt and PowerShell, but no WSL). That plugin is actually one of the plugins I'm trying to fix with this...
Wait @rfgamaral , I have another idea. You can use
win.sessions.get(uid).write(command);
to execute a command, and prevent the result being printed on the screen by hijacking SESSION_PTY_DATA and SESSION_ADD_DATA action after some EXTCUTE_COMMAND action. Do you think it's an option?
I'm seen this problem but dont work for now any other solution ?
I've took a look at the documentation available and some plugins source code but couldn't find if this is possible to achieve. My question is pretty much the issue title.
Say that you are running
/bin/bash
on Linux orcmd.exe
on Windows and on some action -SESSION_ADD
for instance - you execute a command inside the running instance of bash/cmd.exe/whatever and get the output from that command. Is this possible?My necessity for such thing comes from hharnisc/hypercwd#16, not sure if there's a better way though.