|
6 | 6 | "net/url"
|
7 | 7 | "path"
|
8 | 8 | "path/filepath"
|
| 9 | + "runtime" |
9 | 10 | "strings"
|
10 | 11 |
|
11 | 12 | "github.com/skratchdot/open-golang/open"
|
@@ -119,8 +120,11 @@ func (r *RootCmd) openVSCode() *clibase.Cmd {
|
119 | 120 | return xerrors.Errorf("path %q requires expansion and is not supported, use an absolute path instead", d)
|
120 | 121 |
|
121 | 122 | case workspaceAgent.OperatingSystem == "windows":
|
122 |
| - // TODO(mafredri): For now we keep this simple instead of discerning out relative paths on Windows. |
123 |
| - directory = d |
| 123 | + if !isWindowsAbsPath(d) { |
| 124 | + directory = windowsJoinPath(workspaceAgent.ExpandedDirectory, d) |
| 125 | + } else { |
| 126 | + directory = d |
| 127 | + } |
124 | 128 |
|
125 | 129 | // Note that we use `path` instead of `filepath` since we want Unix behavior.
|
126 | 130 | case directory != "" && !path.IsAbs(d):
|
@@ -218,3 +222,44 @@ func (r *RootCmd) openVSCode() *clibase.Cmd {
|
218 | 222 |
|
219 | 223 | return cmd
|
220 | 224 | }
|
| 225 | + |
| 226 | +// isWindowsAbsPath checks if the path is an absolute path on Windows. On Unix |
| 227 | +// systems the check is very simplistic and does not cover edge cases. |
| 228 | +// |
| 229 | +//nolint:revive // Shadow path variable for readability. |
| 230 | +func isWindowsAbsPath(path string) bool { |
| 231 | + if runtime.GOOS == "windows" { |
| 232 | + return filepath.IsAbs(path) |
| 233 | + } |
| 234 | + |
| 235 | + switch { |
| 236 | + case len(path) >= 2 && path[1] == ':': |
| 237 | + // Path starts with a drive letter. |
| 238 | + return len(path) == 2 || (len(path) >= 4 && path[2] == '\\' && path[3] == '\\') |
| 239 | + default: |
| 240 | + return false |
| 241 | + } |
| 242 | +} |
| 243 | + |
| 244 | +// windowsJoinPath joins the elements into a path, using Windows path separator |
| 245 | +// and converting forward slashes to backslashes. On Unix systems a very |
| 246 | +// simplistic join operator is used. |
| 247 | +func windowsJoinPath(elem ...string) string { |
| 248 | + if runtime.GOOS == "windows" { |
| 249 | + return filepath.Join(elem...) |
| 250 | + } |
| 251 | + |
| 252 | + var s string |
| 253 | + for _, e := range elem { |
| 254 | + e = strings.ReplaceAll(e, "/", "\\") |
| 255 | + if e == "" { |
| 256 | + continue |
| 257 | + } |
| 258 | + if s == "" { |
| 259 | + s = e |
| 260 | + continue |
| 261 | + } |
| 262 | + s += "\\" + strings.TrimSuffix(s, "\\") |
| 263 | + } |
| 264 | + return s |
| 265 | +} |
0 commit comments