fix: accept a URI typed into the location bar from any location
The location bar inherits its type from the tab's current location
(Message::EditLocationEnable), and the view has exactly two branches, next
to the existing "TODO: allow editing other locations": a Location::Network
is edited through with_uri, anything else through with_path. Typing
smb://server/share while standing in a local folder therefore produced
Path("smb://server/share"), which is not a directory, and the navigation
was dropped. The reverse direction was broken the same way: from the
Networks view a local path was passed to with_uri and became a bogus
network location.
EditLocationSubmit now decides by parsing the text instead of by the
location it came from:
* parses as a URL with a scheme other than "file" and has a host
-> Location::Network, using url::Url::as_str(), which also normalizes
away surrounding whitespace.
* fails to parse and the current location is a Network
-> Location::Path, with the text untrimmed, because a directory name
may legitimately end in a space.
* anything else is left as it was, so network:/// and foo:bar keep
behaving exactly as before.
The reliable indicator for "this is a path" is that parsing fails, not
that the host is missing: network:/// and file:///home both parse with
has_host() == false. Verified against url 2.5.8.
An unmounted share cannot be resolved, since Tab::resolve sends network
locations through mounter.dir_info, so resolve() returns None and the
navigation would be dropped again. Navigating there is what triggers the
mount, because Cmd::NetworkScan mounts the location it is asked to scan,
so the typed URI is used as a fallback. That fallback is restricted to
input recognised by the first rule above; applying it to any network
location would let unparseable text through, and because with_uri keeps
the display name and path of the previous location, the window would look
normal while the listing stayed empty.
Known cosmetic side effect: while the share is not mounted, resolve()
yields nothing and the tab shows the raw URI as its name. It is replaced
by the proper name as soon as the mount completes.
Drafted with AI assistance (Claude Code); the change was reviewed, built
and tested by me on real hardware as described.
Signed-off-by: chris-010 <10660568+chris-010@users.noreply.github.com>
This commit is contained in:
parent
e96b915f63
commit
3c9a78ac9f
1 changed files with 25 additions and 0 deletions
25
src/tab.rs
25
src/tab.rs
|
|
@ -3861,6 +3861,28 @@ impl Tab {
|
|||
}
|
||||
Message::EditLocationSubmit => {
|
||||
if let Some(mut edit_location) = self.edit_location.take() {
|
||||
let typed_opt = match &edit_location.location {
|
||||
Location::Path(path) => path.to_str().map(str::to_string),
|
||||
Location::Network(uri, ..) => Some(uri.clone()),
|
||||
_ => None,
|
||||
};
|
||||
let mut typed_uri = false;
|
||||
if let Some(typed) = typed_opt {
|
||||
match typed.trim().parse::<url::Url>() {
|
||||
Ok(url) if url.scheme() != "file" && url.has_host() => {
|
||||
let uri = url.as_str().to_string();
|
||||
edit_location =
|
||||
Location::Network(uri.clone(), uri, None).normalize().into();
|
||||
typed_uri = true;
|
||||
}
|
||||
Err(_) if matches!(edit_location.location, Location::Network(..)) => {
|
||||
edit_location =
|
||||
Location::Path(PathBuf::from(typed)).normalize().into();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Select first completion if current location does not exist
|
||||
if edit_location.selected.is_none()
|
||||
&& edit_location
|
||||
|
|
@ -3876,6 +3898,9 @@ impl Tab {
|
|||
}
|
||||
|
||||
cd = edit_location.resolve();
|
||||
if cd.is_none() && typed_uri {
|
||||
cd = Some(edit_location.location);
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::EditLocationTab => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue