Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Encoding the current working path to a valid session filename will always have some form of issue #273

Open
josh-nz opened this issue Feb 29, 2024 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@josh-nz
Copy link

josh-nz commented Feb 29, 2024

Describe the bug
The current method to encode the current working directory into a filename that is valid (in order to name the session file) will always have some form of issue, regardless of platform. A different approach is required.

A number of Windows issues have been reported that all stem from the same encoding issue: #242 #195 #148
However, MacOS and *nix systems can also have issues with the encoding process.

Let's have a look the functions in question, from auto-session/lib.lua:

local function win32_unescaped_dir(dir)
  dir = dir:gsub("++", ":")
  if not vim.o.shellslash then
    dir = dir:gsub("-", "\\")
  end

  return dir
end

local function win32_escaped_dir(dir)
  dir = dir:gsub(":", "++")
  if not vim.o.shellslash then
    dir = dir:gsub("\\", "-")
    -- need to escape forward slash as well for windows, see issue #202
    dir = dir:gsub("/", "-")
  end

  return dir
end

local IS_WIN32 = vim.fn.has "win32" == Lib._VIM_TRUE

function Lib.unescape_dir(dir)
  return IS_WIN32 and win32_unescaped_dir(dir) or dir:gsub("%%", "/")
end

function Lib.escape_dir(dir)
  return IS_WIN32 and win32_escaped_dir(dir) or dir:gsub("/", "\\%%")
end

Let's focus first on Windows. You can see it's a simple substitution for a few characters. However, these substituted characters may exist in the path (since they are valid path/filename characters), and that means it's impossible to know which character/s should be unescaped. It is simply not possible to do simple character substitution to create a valid file name and be able to reliably reverse this process. Let's look at some examples:

C:\foo-bar will be escaped as C++-foo-bar and unescaped as C:\foo\bar
C:\foo++bar will be escaped as C++-foo++bar and unescaped as C:\foo:bar

Here is a MacOS/ *nix example, which uses a different substitution process but can still have issues:
/Users/Foo/bar%baz will be escaped as %Users%Foo%bar%baz and unescaped as /Users/Foo/bar/baz
(I could be wrong on this, I don't quite understand dir:gsub("/", "\\%%") but I think it's just Lua requiring string escaping to represent the % character. I was looking at the resulting filesystem name for this test. Note also, that in my test I somehow got the buffer filename in the session filename, which broke things. We can go over this if needed, but I think the solutions presented below will resolve this anomaly since I think the source of the issue is the same).

How can this be resolved?

The easiest way is to remove the coupling of the cwd from the session filename. When a new session is saved, some unique filename friendly identifier is assigned to it (I would suggest a guid), and this is used as the session filename. This mapping is saved in a file somewhere, similar to how the current session and alternate session is saved. The format is unimportant, it just needs to be a key-value system. If Lua can serialize tables directly to a file, that would be the easiest. So, you'd have something that would look like:

local session_mappings = {
  "C:\\foo-bar" = "f666dfb1-5064-4aaa-89e1-e17d71e3e254",
  "C:\\foo++bar" = "87ba1a7c-e68a-42df-9c91-ecad51d7d5e2"
  ...
}

or similar data structure, in the event that the above is not valid Lua syntax.

I think the above mapping system would probably (automatically?) solve issues #242 #195 #148

I am unfamiliar enough with Lua and nvim plugin development to try and implement this, but in theory it shouldn't be hard to do if someone knows the code.

I have seen #116 so I'm unsure if this is a change that would be considered for the current code base, or not acted upon until the rewrite occurs. If it is the latter, then I can't see a solution for the linked Windows issues.

@josh-nz josh-nz added the bug Something isn't working label Feb 29, 2024
@rmagatti
Copy link
Owner

This is probably a worthwhile change. Would require some deeper digging through the code to make sure things still work well as well as some ability to at least infer display names for sessions. Display names don't have to be used for the actual session parsing of course, but they are useful when calling require("auto-session.session-lens").search_session() for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants