exa
exa copied to clipboard
Initial support for Windows
Supports #32
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:
There are still things that need to be fixed, of course. For example Git works now but timezone detection does not work. If the author want this, I'd like to continue improving the support for Windows.git
does not seem to work
Hi @ariasuni can I get a little help with the CI build? I've test it myself. It works on both Windows & Linux.
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?
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 😄
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.
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:
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)
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.
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.
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 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 😃
Err… Would you mind attaching a final Windows binary here or somewhere nearby, please?
@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.
@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.
OK I managed to implement "permission" to mimic the "mode" in PowerShell. Here's how it looks:
PowerShell gci result for reference:
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.
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?
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:
- Some way to get the current time zone (as some structure).
- 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?
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.
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.
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.
@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.
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.
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.
I'd like to help out with the Windows support, so some tracking issues would be nice.
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
andWindows 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 inmain.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 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.
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.
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).
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 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.