feat: open files without file:// protocol (#4713)

**Overview**: add support for file paths starts with `../` `./` and `/`

To implement this I extended the existing regex variable in the
`src/config` dir. In a few test cases, extra space is added
intentionally to verify we don't include space in the URL as it looks &
feels odd.

Here is the text file content used for testing
```console
➜  ~ cat test.txt
https://google.com
file:///Users/ABC/oss/ghostty/build.zig
file:///Users/ABC/oss/ghostty/debug.sh


/Users/ABC/oss/ghostty/src/../debug.sh
../../Applications/Zed.app/Contents/Info.plist
[link](/home/user/ghostty.user/example) -- non-existent
[link](/Users/ABC/oss/ghostty/src/../debug.sh)
first time ../../Applications/Zed.app/Contents/Info.plist contributor
➜  ~
```

Here is the screen recording of the changes.

[![Screencast](https://img.youtube.com/vi/Q8qdwdBVbWk/0.jpg)](https://www.youtube.com/watch?v=Q8qdwdBVbWk)
This commit is contained in:
Mitchell Hashimoto
2025-01-06 16:00:40 -08:00
committed by GitHub

View File

@ -24,7 +24,7 @@ const oni = @import("oniguruma");
/// handling them well requires a non-regex approach. /// handling them well requires a non-regex approach.
pub const regex = pub const regex =
"(?:" ++ url_schemes ++ "(?:" ++ url_schemes ++
\\)(?:[\w\-.~:/?#@!$&*+,;=%]+(?:[\(\[]\w*[\)\]])?)+(?<![,.]) \\)(?:[\w\-.~:/?#@!$&*+,;=%]+(?:[\(\[]\w*[\)\]])?)+(?<![,.])|(?:\.\.\/|\.\/*|\/)[\w\-.~:\/?#@!$&*+,;=%]+(?:\/[\w\-.~:\/?#@!$&*+,;=%]*)*
; ;
const url_schemes = const url_schemes =
\\https?://|mailto:|ftp://|file:|ssh:|git://|ssh://|tel:|magnet:|ipfs://|ipns://|gemini://|gopher://|news: \\https?://|mailto:|ftp://|file:|ssh:|git://|ssh://|tel:|magnet:|ipfs://|ipns://|gemini://|gopher://|news:
@ -166,6 +166,34 @@ test "url regex" {
.input = "match news:comp.infosystems.www.servers.unix news links", .input = "match news:comp.infosystems.www.servers.unix news links",
.expect = "news:comp.infosystems.www.servers.unix", .expect = "news:comp.infosystems.www.servers.unix",
}, },
.{
.input = "/Users/ghostty.user/code/example.py",
.expect = "/Users/ghostty.user/code/example.py",
},
.{
.input = "/Users/ghostty.user/code/../example.py",
.expect = "/Users/ghostty.user/code/../example.py",
},
.{
.input = "/Users/ghostty.user/code/../example.py hello world",
.expect = "/Users/ghostty.user/code/../example.py",
},
.{
.input = "../example.py",
.expect = "../example.py",
},
.{
.input = "../example.py ",
.expect = "../example.py",
},
.{
.input = "first time ../example.py contributor ",
.expect = "../example.py",
},
.{
.input = "[link](/home/user/ghostty.user/example)",
.expect = "/home/user/ghostty.user/example",
},
}; };
for (cases) |case| { for (cases) |case| {