mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 22:42:48 +03:00
wezterm: windows: automatically add WSL entries to the launcher menu
This feels like a better out of the box experience. The list can be disabled through the config if desired.
This commit is contained in:
parent
03ba1a98f0
commit
c5f270f48b
@ -29,6 +29,12 @@ brief notes about them may accumulate here.
|
||||
You can switch to the old behavior either by explicitly binding those keys
|
||||
or by setting `send_composed_key_when_alt_is_pressed = false` in your
|
||||
configuration file.
|
||||
* Windows: the launcher menu now automatically lists out any WSL environments
|
||||
you have installed so that you can quickly spawn a shall in any of them.
|
||||
You can suppress this behavior if you wish by setting
|
||||
`add_wsl_distributions_to_launch_menu = false`.
|
||||
[Read more about the launcher menuu](config/launch.html#the-launcher-menu)
|
||||
|
||||
|
||||
### 20200517-122836-92c201c6
|
||||
|
||||
|
@ -117,6 +117,10 @@ return {
|
||||
Here's a fancy example that will add some helpful entries to the launcher
|
||||
menu when running on Windows:
|
||||
|
||||
*since: latest nightly*: The launcher menu automatically includes WSL
|
||||
entries by default, unless disabled using `add_wsl_distributions_to_launch_menu = false`.
|
||||
|
||||
|
||||
```lua
|
||||
local wezterm = require 'wezterm';
|
||||
|
||||
|
@ -511,6 +511,9 @@ pub struct Config {
|
||||
#[serde(default)]
|
||||
pub launch_menu: Vec<SpawnCommand>,
|
||||
|
||||
#[serde(default = "default_true")]
|
||||
pub add_wsl_distributions_to_launch_menu: bool,
|
||||
|
||||
#[serde(default = "default_true")]
|
||||
pub check_for_updates: bool,
|
||||
|
||||
|
@ -43,6 +43,59 @@ impl Entry {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn enumerate_wsl_entries(entries: &mut Vec<Entry>) -> anyhow::Result<()> {
|
||||
use std::os::windows::process::CommandExt;
|
||||
let mut cmd = std::process::Command::new("wsl.exe");
|
||||
cmd.arg("-l");
|
||||
cmd.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW);
|
||||
let output = cmd.output()?;
|
||||
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
anyhow::ensure!(
|
||||
output.status.success(),
|
||||
"wsl -l command invocation failed: {}",
|
||||
stderr
|
||||
);
|
||||
|
||||
/// Ungh: https://github.com/microsoft/WSL/issues/4456
|
||||
fn utf16_to_utf8(bytes: &[u8]) -> anyhow::Result<String> {
|
||||
if bytes.len() % 2 != 0 {
|
||||
anyhow::bail!("input data has odd length, cannot be utf16");
|
||||
}
|
||||
|
||||
// This is "safe" because we checked that the length seems reasonable,
|
||||
// and our new slice is within those same bounds.
|
||||
let wide: &[u16] =
|
||||
unsafe { std::slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len() / 2) };
|
||||
|
||||
String::from_utf16(wide).map_err(|_| anyhow!("wsl -l output is not valid utf16"))
|
||||
}
|
||||
|
||||
let wsl_list = utf16_to_utf8(&output.stdout)?.replace("\r\n", "\n");
|
||||
for line in wsl_list.lines().skip(1) {
|
||||
// Remove the "(Default)" marker, if present, to leave just the distro name
|
||||
let distro = line.replace(" (Default)", "");
|
||||
let label = format!("{} (WSL)", distro);
|
||||
|
||||
entries.push(Entry::Spawn {
|
||||
label: label.clone(),
|
||||
command: SpawnCommand {
|
||||
label: Some(label),
|
||||
args: Some(vec![
|
||||
"wsl.exe".to_owned(),
|
||||
"--distribution".to_owned(),
|
||||
distro.to_owned(),
|
||||
]),
|
||||
..Default::default()
|
||||
},
|
||||
new_window: false,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn launcher(
|
||||
_tab_id: TabId,
|
||||
domain_id_of_current_tab: DomainId,
|
||||
@ -57,9 +110,11 @@ pub fn launcher(
|
||||
|
||||
term.set_raw_mode()?;
|
||||
|
||||
let config = configuration();
|
||||
|
||||
// Pull in the user defined entries from the launch_menu
|
||||
// section of the configuration.
|
||||
for item in &configuration().launch_menu {
|
||||
for item in &config.launch_menu {
|
||||
entries.push(Entry::Spawn {
|
||||
label: match item.label.as_ref() {
|
||||
Some(label) => label.to_string(),
|
||||
@ -73,6 +128,13 @@ pub fn launcher(
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if config.add_wsl_distributions_to_launch_menu {
|
||||
let _ = enumerate_wsl_entries(&mut entries);
|
||||
}
|
||||
}
|
||||
|
||||
for (domain_id, domain_state, domain_name) in &domains {
|
||||
let entry = if *domain_state == DomainState::Attached {
|
||||
Entry::Spawn {
|
||||
|
Loading…
Reference in New Issue
Block a user