exa icon indicating copy to clipboard operation
exa copied to clipboard

Initial support for Windows

Open skyline75489 opened this issue 3 years ago • 95 comments

Supports #32

skyline75489 avatar Mar 26 '21 12:03 skyline75489

This PR is based on previous work by @zkat (see https://github.com/ogham/exa/issues/32#issuecomment-623042107). All the tests is green. This is what it looks like now:

exa-windows

There are still things that need to be fixed, of course. For example git does not seem to work Git works now but timezone detection does not work. If the author want this, I'd like to continue improving the support for Windows.

skyline75489 avatar Mar 26 '21 12:03 skyline75489

Hi @ariasuni can I get a little help with the CI build? I've test it myself. It works on both Windows & Linux.

skyline75489 avatar Mar 26 '21 13:03 skyline75489

I suppose the compilation error is due to the fact the CI uses Rust 1.42.0. Are you able to locally build exa with this version of Rust? If that’s the problem, you can just write two different size functions with the cfg attributes, or


I suppose that afterwards I should set:

os:
  - linux
  - windows

in .travis.yml on master branch?

ariasuni avatar Mar 27 '21 18:03 ariasuni

Hi @ariasuni Thanks for the feedback! I've fixed the build.

I'm like a true newbie of rust. Please double check to make sure I'm not doing anything stupid 😄

skyline75489 avatar Mar 28 '21 01:03 skyline75489

As for the CI build, it would be nice to have a Windows job. Also I'm honestly OK with not having at the moment, since the Windows support is still very initial. Passing the tests does not really mean the experience on Windows is good enough.

skyline75489 avatar Mar 28 '21 01:03 skyline75489

Just a heads up, the --git parameter works for conventional paths 🎉, but doesn't seem to work when the path is a UNC path (such as a network share). I'm not familiar enough with exa (or Rust) to know where the path from reorient is being used, but it may be such that the prefix \\?\... has to be preserved in these cases, but stripped when the path is something like \\?\X:\.... But that's just a guess.

Here is a side-by-side: exa git

For context, pwd.exe is GNU's pwd and pwd is Powershell's own builtin. (I should also say that for me personally this isn't a big deal, but I noticed the patch and wanted to check that case. Figured this would be good to know)

djdv avatar Mar 28 '21 04:03 djdv

thanks @djdv for the heads up. I do understand that the code currently won’t work with UNC paths and I plan to add support for UNC paths in the future. Right now I just want to build the basics things on Windows and start from there.

skyline75489 avatar Mar 28 '21 05:03 skyline75489

This is really cool! Although the --long output looks really, really different from what I expect exa to look like :)

On that note, I think it's worth changing the name of the left-most column. I only named it "Permissions" because I knew its Unix output was going to be ten or more characters wide. Now it's just one, it looks strange to me with that long header name with all the space there — none of the other columns change their width so drastically when the header is added. Of course, that affects things like the --no-permissions argument, and the help text, so it's not quite as simple as changing it in one place.

I'm willing to add UNC path support later because supporting Windows is already such a big jump.

ogham avatar Mar 30 '21 00:03 ogham

About the use of Rust 1.42: the MSRV is specified in the README and the Travis check is just there to check it doesn't go out-of-date, but I'm not tied to that particular version. If you need a feature from a later one then I'd be happy to bump it.

ogham avatar Mar 30 '21 00:03 ogham

@ogham thanks so much for this amazing software. I’m finally able to have a unified ls experience across different systems and I am glad to help the community, even though i’m a rust newbie 😃

skyline75489 avatar Mar 30 '21 01:03 skyline75489

Err… Would you mind attaching a final Windows binary here or somewhere nearby, please?

sergeevabc avatar Mar 30 '21 02:03 sergeevabc

@ogham I have some thoughts about the permission as well. I would love to make it the same as Mode in PowerShell (see link. I assume this needs win32 APIs.

The timezone detection logic is also a missing piece. I haven't done the investigation but I assume we'll also need Win32 API for that.

skyline75489 avatar Mar 30 '21 02:03 skyline75489

@sergeevabc I think in the future we can put a binary in the release page once the Windows support is merged and the next release is available. At the moment the Windows support is still initial. If you really want to try it, feel free to checkout my branch and compile it.

skyline75489 avatar Mar 30 '21 05:03 skyline75489

OK I managed to implement "permission" to mimic the "mode" in PowerShell. Here's how it looks:

image

PowerShell gci result for reference:

image

skyline75489 avatar Mar 30 '21 10:03 skyline75489

Ah, "Mode" is much better! I'm glad there's a precedent for it in Powershell, so the column can contain the flags that people expect.

I think in the future we can put a binary in the release page once the Windows support is merged and the next release is available.

Yeah; I had to set up a Windows VM for testing one of my other projects. I can use it to compile Windows exa and make it part of the release when the time comes.

ogham avatar Mar 30 '21 13:03 ogham

For me there are two things that I think is crucial: first the -a semantic needs tweaking on Windows because on Windows the hidden attribute is not determined by the name (having dot prefix or not). Second the time zone detection logic needs to be implemented on Windows.

Besides those 2 issues I can totally rocking with exa as a daily tool now. @ogham what do you think? Anything else I need to do to get this merged & shipped in the future?

skyline75489 avatar Mar 30 '21 14:03 skyline75489

on Windows the hidden attribute is not determined by the name (having dot prefix or not)

I think this comes down to which type of hidden file a user will come into contact with the most.

For example, macOS has the same feature — a literal "hidden file" attribute — that means non-dotfiles can still be hidden in the file explorer. However, the vast, vast majority of hidden files will still be dotfiles, such as .git, ~/.local, ~/.config, and all the stuff that clutters your home directories. The convention seems to be:

  • The file explorer hides both "hidden files" and dotfiles.
  • ls without -a shows "hidden files", but still hides dotfiles.
  • ls -a shows both "hidden files" and dotfiles.

So the question is, how common is it to encounter "hidden files" in Windows? If it's not very common, exa should show them by default. But if there are several popular applications that set the "hidden file" flag and expect to have it respected, then exa should hide them, and have -a show both "hidden files" and dotfiles.

I've used Windows before, but because I end up installing a load of Unix utilities that still use the dotfile convention, I have no idea how common it is for files to set the "hidden file" flag.

the time zone detection logic needs to be implemented on Windows

exa uses the datetime library for this, which I also maintain. Unfortunately it's pretty Unix-centric (it assumes /etc/localtime will contain a link to a list of time zone offset tables). It could also do with some improvement — I won't blame you if you find the code hard to read or modify.

The two functions exa needs from Windows are:

  1. Some way to get the current time zone (as some structure).
  2. Some way to convert a FILETIME (such as its modified time) into a zoned time, using the structure from function 1.

Do you know if Windows has these exact functions, or will exa have to do something slightly differently?

ogham avatar Mar 30 '21 15:03 ogham

So the question is, how common is it to encounter "hidden files" in Windows

There are several files with the hidden flag created by default in the user profile directory, e.g. the AppData directory or the NTUSER.dat file. C:/ProgramData is hidden as well and there are a number of programs that create other hidden directories under C:/. In C:/Windows there are also a bunch of hidden files, and there's also a hidden desktop.ini in every directory with changed configuration. (Personally I manually tag files and directories as hidden quite often as well.)

All in all it's probably less common than under linux, but definitely existing.

Systemcluster avatar Mar 30 '21 15:03 Systemcluster

If it's that uncommon then I think the best thing to do is to mimic the behaviour of ls on macOS, hiding dotfiles but displaying "hidden files". And if this has unexpected side-effects there's still room to change it before v1.0.

ogham avatar Mar 30 '21 18:03 ogham

Both Windows Explorer and the cmd dir command hide hidden files and folders, but not dotfiles. In Windows Explorer you can enable an option to view hidden files, although this still excludes files with the 'System' attribute.

KnapSac avatar Mar 30 '21 18:03 KnapSac

@Systemcluster you think that's the wrong way to do it?

I was thinking about the behaviour of tools like Git, which are used on Windows even if they aren't originally native to that environment, so they still create dotfiles and dot-folders.

ogham avatar Mar 30 '21 18:03 ogham

How about making it configurable? So either mirror the 'default' Windows behavior, or mirror the behavior of ls on MacOS, based on the users preference.

KnapSac avatar Mar 30 '21 19:03 KnapSac

As @Systemcluster pointed out, it's not very common if you're only navigating your own files. But if you're working with Windows folders, the exa result might be a bit noisy comparing to gci and Windows Explorer. That's why I think this is something needs to be fixed. However, I don't really want to do it in this PR since it needs to modify the code in main.rs & possible various other places. I'd like to keep this PR as minimal as possible.

For the time zone, there's the API GetTimeZoneInformation which should gives us what we want. Again, this would require win32 API crates and I don't want to make this PR bloated.

So generally I think this PR is ready now. I'm happy to open issues to track future works we mentioned in this thread.

skyline75489 avatar Mar 31 '21 02:03 skyline75489

I'd like to help out with the Windows support, so some tracking issues would be nice.

KnapSac avatar Mar 31 '21 06:03 KnapSac

As @Systemcluster pointed out, it's not very common if you're only navigating your own files. But if you're working with Windows folders, the exa result might be a bit noisy comparing to gci and Windows Explorer. That's why I think this is something needs to be fixed. However, I don't really want to do it in this PR since it needs to modify the code in main.rs & possible various other places. I'd like to keep this PR as minimal as possible.

For the time zone, there's the API GetTimeZoneInformation which should gives us what we want. Again, this would require win32 API crates and I don't want to make this PR bloated.

So generally I think this PR is ready now. I'm happy to open issues to track future works we mentioned in this thread.

@skyline75489 there is also a rust library for the win32 api now. See https://github.com/microsoft/windows-rs maybe it's possible to use it?

floh96 avatar Mar 31 '21 07:03 floh96

@floh96 Yes that is one option to do this. I'm aware of the library provided by Microsoft. And I think it's a good choice. However calling the API isn't really enough. Will need to investigate more to find out how to make it work with exa code.

skyline75489 avatar Mar 31 '21 08:03 skyline75489

Just FYI, files with leading _ are also "hidden" by lots of older Windows applications. In the past, some built-in windows applications (eg, "File Explorer") refused to create files without a file "base" name seeing ".FILENAME" as a nameless file with only an extension. "_FILENAME" was used by various more POSIXy application ports as an alternative.

Prior art (msls) straddles the lines, hiding both ".FILENAME" and "_FILENAME" files as well as any files with the Windows hidden or system attributes. ".FILENAME" and "_FILENAME" are both somewhat odd filenames, so I think hiding them (on top of attribute HIDDEN and SYSTEM files) would be a good default for all systems. It hides files which IMO most users would expect to be hidden. Then, no extra flags or configuration would be needed. The usual -a could be used to display those hidden files.

rivy avatar Mar 31 '21 15:03 rivy

So the question is, how common is it to encounter "hidden files" in Windows? If it's not very common, exa should show them by default. But if there are several popular applications that set the "hidden file" flag and expect to have it respected, then exa should hide them, and have -a show both "hidden files" and dotfiles.

I've used Windows before, but because I end up installing a load of Unix utilities that still use the dotfile convention, I have no idea how common it is for files to set the "hidden file" flag.

exa will likely be most used by developers who also install Windows and POSIXy utilities. Those (we?) folks will much more commonly encounter hidden files (and are also most likely to be annoyed by files they don't want to see at baseline).

rivy avatar Mar 31 '21 15:03 rivy

I think in the future we can put a binary in the release page once the Windows support is merged and the next release is available.

Yeah; I had to set up a Windows VM for testing one of my other projects. I can use it to compile Windows exa and make it part of the release when the time comes.

There's no need to set up a VM.

GitHub Actions can compile and upload binaries for releases automatically. You can use the "softprops/action-gh-release@v1" action and just point to the files you want uploaded to the release. I've helped build a few examples (see the [pastel] CI). Once you're testing the code on GitHub Actions windows platforms, the binary upload for releases is straight forward and can be completely automatic.

rivy avatar Mar 31 '21 15:03 rivy

@rivy thanks for the heads up. Does the _ prefix only apply to file, or does is also apply to folders?

I’m aware of the existence of _ prefix file back in the days dot prefix is not supported. But right now Windows is way more Unix-friendly and dot prefix works just fine. So I’m not really sure whether it’s relevant any more.

skyline75489 avatar Mar 31 '21 22:03 skyline75489