plenary.nvim icon indicating copy to clipboard operation
plenary.nvim copied to clipboard

Support both forward and backslashes on Windows

Open archiif opened this issue 3 years ago • 1 comments

Both forward and backslashes are valid path separators on Windows. Right now, plenary doesn't seem to know what to do with Windows paths that contain forward slashes.

For example: :lua print(require("plenary").Path:new("C:/path/to/file"):parent()) will output whatever the current directory is for some reason, regardless of input.

Mixed slashes also don't work correctly: :lua print(require("plenary").Path:new("C:\\path/to/file"):parent()) outputs C:

While: :lua print(require("plenary").Path:new("C:/path\\to/file"):parent()) outputs D:\C:/path (D:\ was my current directory)

archiif avatar Aug 01 '22 20:08 archiif

Sorry for this write up, I just instigated a little bit.

I have been taking a look at rust documentation on how it handle absolute path's documentation:rust/std/path.rs:3184 source:rust/std/path.rs:3184

The rust documentation also links to others source about path's

#![feature(absolute_path)]
fn main() -> std::io::Result<()> {
  use std::path::{self, Path};

  // Relative to absolute
  let absolute = path::absolute("foo/./bar")?;
  assert!(absolute.ends_with(r"foo\bar"));

  // Absolute to absolute
  let absolute = path::absolute(r"C:\foo//test\..\./bar.rs")?;

  assert_eq!(absolute, Path::new(r"C:\foo\bar.rs"));
  Ok(())
}

I have tried writing a test in lua that looks like the rust version. however it does not seem to return the correct path.

local Path = require('plenary.path')
-- local eq = assert.are.same
-- local neq = assert.are_not.same

local path_absolute = Path:new([[C:/foo/test\..\./bar.rs]]):absolute()
-- eq(path_absolute, [[C:\foo\test\bar.rs]])
print(path_absolute)

path_absolute = Path:new([[\foo/test\..\./bar.rs]]):absolute()
-- eq(path_absolute, [[C:\foo\test\bar.rs]])
print(path_absolute)

path_absolute = Path:new([[/foo/test\..\./bar.rs]]):absolute()
-- eq(path_absolute, [[C:\foo\test\bar.rs]])
print(path_absolute)

local path_relative = Path:new([[foo/test\..\./bar.rs]]):absolute()
-- neq(path_absolute, [[C:\foo\test\bar.rs]])
print(path_relative)
C:\Users\kkmp\./bar.rs
C:\Users\kkmp\./bar.rs
C:\Users\kkmp\./bar.rs
C:\Users\kkmp\./bar.rs

I have read in some issues that you have made the path API as the python version. Here you can see how the python version handles absolute path.

from pathlib import Path

print(Path(r'C:\foo//test\..\./bar.rs').absolute()) # Defined as absolute
print(Path(r'\foo//test\..\./bar.rs').absolute()) # Defined as absolute
print(Path(r'/foo//test\..\./bar.rs').absolute()) # Defined as absolute
print(Path(r'foo//test\..\./bar.rs').absolute()) # Should be relative
C:\foo\test\..\bar.rs
C:\foo\test\..\bar.rs
C:\foo\test\..\bar.rs
C:\Users\kkmp\foo\test\..\bar.rs

kkmp-dk avatar Nov 22 '22 13:11 kkmp-dk