diff --git a/Cargo.lock b/Cargo.lock index 180b4bd..5f2e3a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1357,9 +1357,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.110" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58a4469763e4e3a906c4ed786e1c70512d16aa88f84dded826da42640fc6a1c" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libdbus-sys" @@ -1731,6 +1731,7 @@ dependencies = [ "futures 0.3.18", "ioctl-rs", "lazy_static 1.4.0", + "libc", "librespot-core", "librespot-playback", "librespot-protocol", diff --git a/Cargo.toml b/Cargo.toml index 5fcfb65..2b1fd82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ regex = "1" ioctl-rs = { version = "0.2", optional = true } serde_cbor = "0.11.2" pancurses = { version = "0.17.0", features = ["win32"] } +libc = "0.2.111" [dependencies.rspotify] version = "0.11.3" diff --git a/README.md b/README.md index 7d28e30..679e9b6 100644 --- a/README.md +++ b/README.md @@ -259,18 +259,19 @@ time with Escape. The following commands are supported: -| Command | Action | -| :--------------------------------- | :--------------------------------------------------------------- | -| `quit` | Quit `ncspot`. | -| `logout` | Remove any cached credentials from disk and quit `ncspot`. | -| `toggle` | Toggle playback. | -| `stop` | Stop playback. | -| `previous` | Play previous track. | -| `next` | Play next track. | -| `clear` | Clear playlist. | -| `share ` | Copies a sharable URL of the item to the system clipboard. | -| `newplaylist ` | Create new playlist with name ``. | +| Command | Action | +|---|---| +| `quit` | Quit `ncspot`. | +| `logout` | Remove any cached credentials from disk and quit `ncspot`. | +| `toggle` | Toggle playback. | +| `stop` | Stop playback. | +| `previous` | Play previous track. | +| `next` | Play next track. | +| `clear` | Clear playlist. | +| `share ` | Copies a sharable URL of the item to the system clipboard. | +| `newplaylist ` | Create new playlist with name ``. | | `sort ` | Sort a playlist by `` in direction ``. | +| `exec ` | Executes a command in the system shell. Be aware that command output is printed to the terminal, so redirection to `/dev/null` e.g. by appending `2> /dev/null` may be necessary. | Supported `` are: diff --git a/src/command.rs b/src/command.rs index 7d70a5d..1ba021a 100644 --- a/src/command.rs +++ b/src/command.rs @@ -136,6 +136,7 @@ pub enum Command { Logout, ShowRecommendations(TargetMode), Redraw, + Execute(String), } impl fmt::Display for Command { @@ -191,7 +192,7 @@ impl fmt::Display for Command { Command::Jump(mode) => match mode { JumpMode::Previous => "jumpprevious".to_string(), JumpMode::Next => "jumpnext".to_string(), - JumpMode::Query(term) => format!("jump {}", term).to_string(), + JumpMode::Query(term) => String::from(format!("jump {}", term)), }, Command::Help => "help".to_string(), Command::ReloadConfig => "reload".to_string(), @@ -201,6 +202,7 @@ impl fmt::Display for Command { Command::Logout => "logout".to_string(), Command::ShowRecommendations(mode) => format!("similar {}", mode), Command::Redraw => "redraw".to_string(), + Command::Execute(cmd) => format!("exec {}", cmd), }; // escape the command separator let repr = repr.replace(";", ";;"); @@ -471,6 +473,7 @@ pub fn parse(input: &str) -> Option> { .map(Command::ShowRecommendations), "noop" => Some(Command::Noop), "redraw" => Some(Command::Redraw), + "exec" => Some(Command::Execute(args.join(" "))), _ => None, }; commands.push(command?); diff --git a/src/commands.rs b/src/commands.rs index 0520451..4997700 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -253,6 +253,13 @@ impl CommandManager { s.quit(); Ok(None) } + Command::Execute(cmd) => { + log::info!("Executing command: {}", cmd); + let cmd = std::ffi::CString::new(cmd.clone()).unwrap(); + let result = unsafe { libc::system(cmd.as_ptr()) }; + log::info!("Exit code: {}", result); + Ok(None) + } Command::Jump(_) | Command::Move(_, _) | Command::Shift(_, _)