zellij-org / zellij

A terminal workspace with batteries included
https://zellij.dev
MIT License
20.83k stars 638 forks source link

[FEATURE] windows support #316

Open Slach opened 3 years ago

Slach commented 3 years ago

currently under windows 10

cargo install zellij

return lot of errors during compile termion

error[E0425]: cannot find function `set_terminal_attr` in this scope
   --> C:\Users\Slach\.cargo\registry\src\github.com-1ecc6299db9ec823\termion-1.5.6\src\raw.rs:119:9
    |
119 |         set_terminal_attr(&self.prev_ios)?;
    |         ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `get_terminal_attr` in this scope
   --> C:\Users\Slach\.cargo\registry\src\github.com-1ecc6299db9ec823\termion-1.5.6\src\raw.rs:125:23
    |
125 |         let mut ios = get_terminal_attr()?;
    |                       ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `raw_terminal_attr` in this scope
   --> C:\Users\Slach\.cargo\registry\src\github.com-1ecc6299db9ec823\termion-1.5.6\src\raw.rs:126:9
    |
126 |         raw_terminal_attr(&mut ios);
    |         ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `set_terminal_attr` in this scope
   --> C:\Users\Slach\.cargo\registry\src\github.com-1ecc6299db9ec823\termion-1.5.6\src\raw.rs:127:9
    |
127 |         set_terminal_attr(&ios)?;
    |         ^^^^^^^^^^^^^^^^^ not found in this scope
rashil2000 commented 3 years ago

Termion is a unix-only library. I think zellij devs might need to shift to crossterm to become cross platform.

imsnif commented 3 years ago

Moving to crossterm would definitely be the first step. We only use termion for input parsing, so crossterm could probably do the trick for us.

rashil2000 commented 3 years ago

That sounds great!

Zellij just might become the first ever terminal multiplexer to have native Windows support ๐Ÿ˜…

davidhewitt commented 3 years ago

I took a quick look at this today. This is a non-exhaustive list of obstacles I ran into:

With a bit of conditional #[cfg] application it's probably possible to get it all to piece together, but it's likely to be quite hard. I agree that a first step to achieve this would be to move to crossterm just so that there's less other stuff that needs to be tweaked to get a build passing on Windows.

If I were to try again I'd build zellij inside WSL2 while porting over to crossterm. However, not sure I'm likely to find a chance to have another look in the near future, so anyone else interested in this should definitely not wait and assume I'll ever get around to it ๐Ÿ˜…

blm768 commented 3 years ago

Unfortunately, I'm not so sure that crossterm will be as useful as might be hoped in its current state. It's got great primitives for reading events from the terminal and drawing to it, but it doesn't seem to provide a great way to "chain" those two halves, i.e. to go from an Event to an ANSI sequence that can be forwarded to a child's PTY. A Command can be written as an ANSI sequence (at least on UNIX and Windows 10), but mapping from Events to Commands isn't entirely trivial, and I'm not sure yet that Command even provides the right abstractions. That being said, it might not be terribly difficult to extend crossterm to support what we'd need.

imsnif commented 3 years ago

@blm768 - the only thing we use termion for right now is parsing STDIN. The rest we do "in house", so I think on that front if we can switch that to crossterm (which as you say I think can handle that bit?) we should be good.

blm768 commented 3 years ago

We seem to pass raw ANSI sequences from termion into Action::Write, though; crossterm doesn't expose those raw sequences, so we'd have to construct them ourselves from the parsed events or use something like anes. The plugin API is another place we'd run into issues; AFAICT, crossterm only parses from /dev/tty, so we can't easily just point it at a child PTY.

imsnif commented 3 years ago

@blm768 - I see what you're saying now, right. If crossterm can't do that then we can totally offload this to an external library. I'm not sure I understand what trouble you're referring to with the plugin API though... we parse input from stdin and then send it ourselves to plugins... or am I misunderstanding you?

blm768 commented 3 years ago

The problem with parsing plugin output is that we currently do it with termion. crossterm doesn't provide a replacement for the termion APIs we're using; AFAICT, it's strictly hard-coded to only parse input from /dev/tty, not an arbitrary pipe attached to a plugin.

Looking at how terminals encode typical key sequences, it doesn't seem like it should be hard to translate from Zellij's key event types to ANSI sequences, so at least that part shouldn't be too bad. Parsing basic key sequences probably isn't too hard, either, so perhaps this stuff won't be as bad as I was initially thinking.

imsnif commented 3 years ago

I'm still unsure what you're referring to in the plugins, tbh. Could you link to the part of the code you mean?

blm768 commented 3 years ago

parse_keys is the point where we're using termion for plugins. It's defined here and used here.

imsnif commented 3 years ago

Aha! I see. I actually wasn't fully aware we were doing that :D

We should probably be able to get away with just sending the events directly to the plugins and bypassing termion in this case altogether. I mean, we parse them to events, interpret them, then serialize them (because that's what the terminals want) and parse them again (because that's what the plugins want). We can change the relevant instructions to include both the serialized and parsed versions, I think

kirawi commented 3 years ago

Could termwiz be a viable alternative?

blm768 commented 3 years ago

Could termwiz be a viable alternative?

Probably worth looking into, at least. The portable_pty crate by the same author could prove useful for PTY support on Windows; it's almost certainly farther along than my own unreleased PTY library. It's probably not as stable as crossterm yet, though, so if we end up just needing to parse and serialize keyboard/mouse escape sequences as opposed to all possible ANSI sequences, we might be better off in the short term to roll our own parsing.

kirawi commented 3 years ago

I wonder if crossterm would be opposed to supporting raw keys. This was also a problem Helix hit: https://github.com/helix-editor/helix/issues/133

blm768 commented 3 years ago

I wonder if crossterm would be opposed to supporting raw keys.

They might be willing to expose support for raw ANSI sequence parsing. There are references in the crossterm code to future planes to use anes, so at least at some point, there was some interest in making raw ANSI visible in some fashion via a public API. We may be able to simply use anes ourselves. It hasn't had new commits in a couple of years, but it may be that it's more "feature-complete" than "dead".

This was also a problem Helix hit: helix-editor/helix#133

That doesn't sound like quite the same issue, although it's at least tangentially related. They seem to be looking for raw keyboard scan codes rather than raw ANSI sequences.

kirawi commented 2 years ago

Looking into this right now. An additional unix-only crate is nix. I'm unaware of a cross-platform alternative to termios. Would a wrapper have to be created?

imsnif commented 2 years ago

Yeah, definitely. Both for termios and nix we'd have to create a wrapper. I haven't dealt with that part of the code-base in a while, but I think they should already be in a wrapper, which is what we use the ServerOsInput (https://github.com/zellij-org/zellij/blob/main/zellij-server/src/os_input_output.rs#L203) and ClientOsInput (https://github.com/zellij-org/zellij/blob/main/zellij-client/src/os_input_output.rs#L65) structs for. If for some reason it leaked outside, that's not good and we should totally fix that as part of this.

kirawi commented 2 years ago

Might take me some time to write the Windows equivalents for the termios code. I'll have to do some research first.

musjj commented 1 year ago

Any chance for a revival? A proper terminal multiplexer for Windows is something that I've been wanting for a long time.

imsnif commented 1 year ago

Adding windows support to the project is a significant undertaking. More so now as the project evolved since this thread was last active. It will likely require a few weeks of work on my part, as well as access to a windows machine. If this is of interest to anyone, I invite you to look into the "large project" tier of my Github Sponsors.

holly-hacker commented 1 year ago

Is there any chance this can be broken up into smaller, manageable chunks for external contributors to work on? I don't think many people can shell out 5000usd for a terminal multiplexer...

EDIT: I can also place a bounty on this issue, but not to the scale of multiple thousand dollars.

imsnif commented 1 year ago

That's the value of the work. As you can see, while I happily give away my work for free - that gives me the freedom to choose what I work on.

Even if someone magically comes about and implements this "perfectly"*, this being OSS - I have no way of knowing they would stick around. Then the maintenance work - for years to come - falls on me. Maintenance work that might become critical and even block other features.

*If there is such a thing...

dwat3r commented 1 year ago

While there's not much chance for one person to pay the cost upfront, I think a crowdfunding campaign for this feature could do the trick. At least I'd happily support it with a smaller amount I can afford. The campaign itself also could be organized with the community as well. I fell in love with zellij and for me it's the perfect companion for Alacritty on every OS, so it'd be great to have it on Windows as well.

imsnif commented 1 year ago

That's a cool idea and I'd be happy to support it in any way I can (though not myself be in charge of it). I would love for Zellij to support windows.

holly-hacker commented 1 year ago

I personally think a bounty system such as Bountysource would work best. I can contribute ~100usd to get it started. Once it reaches an amount you are happy with, you could pick it up and claim the bounty once it's finished.

Another option is to apply for a Rust Foundation grant. They support open source projects such as this and they may be open to providing sponsorship.

imsnif commented 1 year ago

Seems to me like if people want to get this going, someone needs to stand behind this: open a funding campaign in whatever platform they choose (personally I'd shy away from Bountysource, but this is not a deal breaker for me... I will not accept payment in cryptocurrencies though), promote it and make sure it reaches enough people. This is more significant than placing down individual funds.

I do not have the time or capacity for this - so dear issue readers/subscribers: this is now in your hands. :)

holly-hacker commented 1 year ago

I don't think much is happening in this area, but I've recently realized you can use Zellij (and other multiplexers) on windows through WSL, which can run Windows applications directly inside the WSL shell.

Here is an example where I am running cmd.exe within zellij (other shells such as pwsh.exe and nu.exe work just as well): FancyWM_doZ1VRV91m

Simply start a WSL shell, open Zellij and run a shell that is inside your Windows PATH using its binary name (ie. cmd.exe rather than just cmd).

ShrykeWindgrace commented 1 year ago

@holly-hacker if we are using WSL, then we can run tmux, can't we? ๐Ÿ˜€ Tabs and panes are supported by Windows Terminal, so the only discernable experience difference would be, imho, a cross-platform native terminal multiplexer.

holly-hacker commented 1 year ago

@holly-hacker if we are using WSL, then we can run tmux, can't we? ๐Ÿ˜€ Tabs and panes are supported by Windows Terminal, so the only discernable experience difference would be, imho, a cross-platform native terminal multiplexer.

If you prefer using tmux, you can use this method to run windows shells within tmux too!

My workflow does not allow me to use a linux shell and I really prefer using Alacritty over Windows Terminal which is why this trick is useful to me. I'm simply sharing it here in case others find it a suitable workaround as well. It won't work for people that cannot run WSL but I think it's still worth mentioning :)

YummyOreo commented 1 year ago

Also if it is marketed as good for beginners, this workaround can discourage them. But this is still a useful workaround.

imsnif commented 1 year ago

so the only discernable experience difference would be, imho, a cross-platform native terminal multiplexer.

Just to mention that if you think this, I would very much encourage you to look into the Zellij features and find out about a great deal more discernible experiences: https://zellij.dev/screencasts/

iXialumy commented 1 year ago

Is there any chance we can build up a tracking issue with all the building on windows errors? I think this would make it easier for someone to pick this issue up and work on resolving the pieces. Even resolving only part of the issues would be a win in my book since someone else can continue on that.

From what I saw most of the problem comes from terminal formatting and information getting not being platform independent. But I think it would be a great first step to build a list with the issues that would need to be fixed te get windows support up and running.

leet0rz commented 11 months ago

Windows needs this like yesterday, hoping to see zellij on windows.

afonsolage commented 11 months ago

It's such a shame Windows is not supported. I had to move to Windows, due to reasons on my job, and had a bad surprise that I wouldn't be able to use my fav term multiplexer.

leet0rz commented 11 months ago

It's such a shame Windows is not supported. I had to move to Windows, due to reasons on my job, and had a bad surprise that I wouldn't be able to use my fav term multiplexer.

Would love to see it on windows too. We need it.

iXialumy commented 11 months ago

I am starting to investigate things that have to be changed for zellij to build on windows. One thing that needs fixing is the ipc (Inter Process communication). At the moment it is not possible for windows to clone a session stream ipc.rs since this uses an unsafe workaround with unix file descriptors. (Unsafe as in unsafe block, not as in will likely crash).

This unfortunately has no windows equivalent as far as I could tell, but a try_clone feature is in the works on the ipc crate. I will try to help there, to allow us to fix the issue here.

This being said, IPC is only one of the components that needs reworking to be cross platform compatible and I will try to set up a tracking issue with the components I can find that need reworking for windows to compile and maybe can be worked on independently. If someone else wants to help, feel free to. A minimum amount of work anyone could do is locate something that needs rework and just add it to the conversation here.

imsnif commented 11 months ago

I very much appreciate your investigation and willingness to help and contribute @iXialumy - I'm sure many others who watch this thread do as well. As I mentioned above though - the main chunk of work that will be needed for windows is to adjust our pty handling to work with the windows ConPty stuff. Everything else is "cosmetic" - we might not even need some of these dependencies.

To say it differently: the work needs to start from the technology/ecosystem side and then adjusted as needed from the dependency side. I'm saying this because I don't want you or anyone else to waste time working on stuff that have a high likelihood of not being needed for this issue (eg. for ipc we might be able to switch to a different library).

Again - thanks for your willingness.

iXialumy commented 11 months ago

Thanks for the quick reply @imsnif . Can we maybe create a separate issue for that where we outline what work has to be done there andmaybe reference that here. I would also have no problem working on that, but at the moment I lack a sense of direction. If I (or someone else for that matter) would know where we have to change, it would be much easier to begin providing contributions.

I would be open to chat if that would be too big of a topic for a single issue in the beginning. Let me know how I can help :)

imsnif commented 11 months ago

Honestly, I don't know how to proceed forward with accepting contributions for this in a way that won't waste anyone's time and cause frustrations.

Here is how it usually happens for me:

  1. A very kind and enthusiastic contributor wants to contribute a large feature. They know it's large, but want to do it anyway.
  2. I provide guidance, spending time I could have spent on other features (or indeed on working on that feature myself). We break the feature into bits, I say what needs to be done, the enthusiastic contributor keeps working on the feature.
  3. We hit some sort of snag. Something that makes the work in 1 look actually larger for both me and the contributor. We are both frustrated. We find a path forward, but the work has now grown in an order of magnitude.
  4. The enthusiastic contributor is not so enthusiastic anymore. They committed to this, so they force themselves to keep going, but eventually other more pressing or interesting things demand their attention and they give up.
  5. Both me and the contributor lose a lot of time and effort, and are more frustrated with opensource in general and the feature specifically. Most of the time the work both of us put in is much larger than what I would have to put in alone if I just sat down and developed the feature on my own (because communication is hard, asynchronous work with someone you don't know is hard, getting into context on a new project is hard, and all the classic problems of collaboration in software development).

So... I don't know what to tell you other than pointing to my last comment for a way forward on this. That's something I haven't tried yet in the OSS world and am totally willing to give a try. This model described above is something I tried very often and it almost always happens in the way I described. It sucks, I know - but I just can't ignore my many experiences here.

iXialumy commented 11 months ago

Yes I totally understand that and I very much appreciate you voicing this concern. I think what would be valuable (wether or not me or someone else implements this at some point) to collect what the goal of the step should be. So for example in this specific case, if I understand this correctly, the places where the code interacts with the windows ConPty, and what we expect the 'new' behaviour to be.

That would make it easier to work on this myself without much feedback needed from you and I could keep silent until I may have come up with a solution that may need some help to merge at that point. Or in case a big decision is needed.

That would keep you out of the loop mostly and hopefully reduce frustration to a minimum if I don't succeed with this feature, but still gives yourself or someone else an outline of what this should look like in case this gets picked up later again.

Is that something that you could see working?

imsnif commented 11 months ago

Honestly @iXialumy - this sounds like the same process I described. I have been burnt by this too many times. I'm sorry, but I'm spending my full time on this project burning through my savings. My time is very calculated and critical for me. As much as I'd like to see windows support, I cannot risk it for a stranger from the Internet - kind and friendly as they may be.

If you want to start working on this without my input and come to me with a working and compiling version and a list of decisions that need to be made - sure. Otherwise the way forward with this is either a funding campaign as I mentioned in the comment above, or waiting until I get to it myself (which I fully plan to, but cannot yet provide an ETA for - I'm honestly doing what I think is best for the project at the order I feel is right).

iXialumy commented 11 months ago

Yes I fully understand. I guess I will do my best to get as far as I can with this and document what I have done and the Problems I'm facing, so this may provide value even if I can't finish the work.

iXialumy commented 10 months ago

I am going to continue writing on this in a draft PR, because it does not seem useful to post technical updates here.

sjplanet commented 6 months ago

Simply start a WSL shell

I try this with WSL. I like this idea. But on my system "paste" doesn't work. To copy it I can define copy_command "clip.exe" . Is this another issue?

PitiBouchon commented 5 months ago

It would be nice if Zellij was cross-platform as other tools like Helix, Alacritty, Nushell...

lost22git commented 4 months ago

windows users are waiting

imsnif commented 4 months ago

windows users are waiting

Dear windows user,

This is an OSS project run by volunteers. As indicated above you in this thread (which I assume you read before you decided to make this useful comment), said volunteers do not have the capacity or funds to develop this feature at the moment. As I am sure you have also read here, others from the community want this feature so badly they have decided to start developing it on their own - at great effort and with decidedly not enough appreciation for their hard work.

While I appreciate that you want this feature very bad and am sure you did not mean it this way, comments such as yours mostly serve to demoralize and frustrate people doing the actual work on the feature you want. So not only are they not helping, they also serve to actively deter the efforts of people who're working on the feature.

If you'd like to learn more, allow me to recommend this great blog post: Entitlement in Open Source.

Until then - I encourage you and others to be patient and show your appreciation for the very hard work that is being done in the sister PR of this issue.

No need to further comment (here or in the PR) if you don't have anything useful to add, you can use the various reactions kindly provided by GitHub.

All the best to you.

arunk commented 4 weeks ago

After reading this thread I still tried to run cargo install --locked zellij on my Windows machine just to see what would happen, and it chugged along for a bit, an installed quite a few packages and built them, but it finally bombed on one package. Well it bombed on a couple of packages, one of them because the build script was looking for perl, so I installed perl and that package seemed to build. Which left just this one package which didn't. I don't know if there are other packages as well that might not build if this one passes, but for what its worth this is the error I got:

error[E0793]: reference to packed field is unaligned
    --> C:\Users\arunk\.cargo\registry\src\index.crates.io-6f17d22bba15001f\ntapi-0.3.7\src\ntexapi.rs:2783:52
     |
2783 |         *tick_count.QuadPart_mut() = read_volatile(&(*USER_SHARED_DATA).u.TickCountQuad);
     |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
     = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
     = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

error[E0793]: reference to packed field is unaligned
    --> C:\Users\arunk\.cargo\registry\src\index.crates.io-6f17d22bba15001f\ntapi-0.3.7\src\ntexapi.rs:2807:25
     |
2807 |         ((read_volatile(&(*USER_SHARED_DATA).u.TickCountQuad)
     |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
     = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
     = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

For more information about this error, try `rustc --explain E0793`.
error: could not compile `ntapi` (lib) due to 2 previous errors

I've been meaning to learn some rust, I'll try and dig in and see what the issue is. See if I can help fix it. Any pointers would be great.

a-usr commented 4 weeks ago

@arunk That error originates from a crate ( a rust libary ) named ntapi, so its outside of zellij code. The fact that it isnt mentioned in the cargo.toml (The file where dependencies are declared) in the zellij repo indicates that it is a indirect dependency ( e.g. a dependency declared by a crate that zellij uses ).

Furthermore ntapi seems to be a crate that provides abstractions to the native Windows API, and the fact that this error doesnt seem to get thrown when building under linux / mac indicates that ntapi is only used by its dependand when building on windows (which is a valid design pattern in Rust).

And sorry for explaining everything like if you where an idiot regarding Rust, I just have no way of knowing how informed you are.

Also, if you want to find out the details of a crate (or browse through all aviable crates) take a look at crates.io

Lastly I'd try to avoid to discuss this here, since for every message 19 people are getting an email.