Skip to content

Commit

Permalink
Session shutdown improvements (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
ck3mp3r committed May 1, 2024
1 parent 4c61adc commit 0b854f0
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 49 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ jobs:
run: |
current_version=${{ steps.get_version.outputs.current-version }}
new_version=${{ steps.get_version.outputs.new-version }}
if [ "${current_version}" != "${new_version}" ]; then
is_release_build=${{ steps.get_version.outputs.is-release-build }}
if [ "${is_release_build}" == "true" ]; then
sed -i "s/^version = \".*\"/version = \"${new_version}\"/" Cargo.toml
sed -i -E "s/(version \")[^\"]*(\")/\1${new_version}\2/" Formula/laio.rb
nix develop --command cargo update -p ${{ env.APP_NAME }}
Expand All @@ -77,7 +78,7 @@ jobs:
runner: ubuntu-latest
target: aarch64-linux
- name: macos-amd64
runner: macos-latest
runner: macos-13
target: x86_64-darwin
- name: macos-arm64
runner: macos-14
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "laio"
version = "0.9.7"
version = "0.10.0"
edition = "2021"
description = "A simple flexbox-like layout manager for tmux."
homepage = "https://github.com/ck3mp3r/laio-cli"
Expand Down
47 changes: 30 additions & 17 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
description = "Simple flexbox-inspired layout manager for tmux.";
inputs = {
nixpkgs.url = "github:NixOs/nixpkgs/23.11";
nixpkgs.url = "github:NixOs/nixpkgs";
devshell.url = "github:numtide/devshell";
flake-utils.url = "github:numtide/flake-utils";
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
};

Expand Down
2 changes: 2 additions & 0 deletions src/app/cmd_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[cfg(test)]
pub mod test {
use anyhow::bail;
use log::trace;
use std::cell::RefCell;

Expand Down Expand Up @@ -106,6 +107,7 @@ pub mod test {
"tmux ls -F \"#{session_name}\"" => Ok(format!("{}","foo\nbar")),
"tmux show-environment -t \"valid\": LAIO_CONFIG" => Ok("LAIO_CONFIG=./src/app/manager/test/valid.yaml".to_string()),
"tmux show-environment -t \"foo\": LAIO_CONFIG" => Ok("LAIO_CONFIG=./src/app/manager/test/valid.yaml".to_string()),
"tmux show-environment -t \"bar\": LAIO_CONFIG" => bail!("Value doesn't exist".to_string()),
_ => {
println!("cmd {}", cmd);
Ok("".to_string())
Expand Down
56 changes: 48 additions & 8 deletions src/app/manager/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<R: CmdRunner> SessionManager<R> {

// create tmux client
let tmux = Tmux::new(
&Some(session.name.clone()),
&Some(session.name.to_string()),
&session.path,
Rc::clone(&self.cmd_runner),
);
Expand All @@ -63,10 +63,11 @@ impl<R: CmdRunner> SessionManager<R> {
}

tmux.create_session(&config)?;
tmux.flush_commands()?;

self.process_windows(&session, &tmux, &dimensions)?;

tmux.bind_key("prefix s", "display-popup -E \"SESSION=\\\"\\$(laio ls | fzf --exit-0 | sed 's/ \\{0,1\\}\\*$//')\\\" && if [ -n \\\"\\$SESSION\\\" ]; then laio start \\\"\\$SESSION\\\"; fi\"")?;
tmux.bind_key("prefix L", "display-popup -E \"SESSION=\\\"\\$(laio ls | fzf --exit-0 | sed 's/ \\{0,1\\}\\*$//')\\\" && if [ -n \\\"\\$SESSION\\\" ]; then laio start \\\"\\$SESSION\\\"; fi\"")?;

tmux.flush_commands()?;

Expand All @@ -83,13 +84,43 @@ impl<R: CmdRunner> SessionManager<R> {
&self,
name: &Option<String>,
skip_shutdown_cmds: &bool,
stop_all: &bool,
) -> Result<(), Error> {
let tmux = Tmux::new(name, &".".to_string(), Rc::clone(&self.cmd_runner));
let current_session_name = tmux.current_session_name()?;
log::trace!("Current session name: {}", current_session_name);

if !*stop_all && name.is_none() && !tmux.is_inside_session() {
bail!("Specify laio session you want to stop.");
}

if let Some(ref session_name) = name {
if !tmux.session_exists(session_name) {
bail!("Session {} does not exist!", session_name);
if *stop_all && name.is_some() {
bail!("Stopping all and specifying a session name are mutually exclusive.")
};

if *stop_all {
// stops all other laio sessions
log::trace!("Closing all laio sessions.");
for name in self.list()?.into_iter() {
if name == current_session_name {
log::trace!("Skipping current session: {:?}", current_session_name);
continue;
};

if self.is_laio_session(&name)? {
log::trace!("Closing session: {:?}", name);
self.stop(&Some(name.to_string()), skip_shutdown_cmds, &false)?;
}
}
};

let name = name.clone().unwrap_or(current_session_name.to_string());
if !tmux.session_exists(&name) {
bail!("Session {} does not exist!", &name);
}
if !self.is_laio_session(&name)? {
log::debug!("Not a laio session: {}", &name);
return Ok(());
}

let result = (|| -> Result<(), Error> {
Expand All @@ -109,13 +140,12 @@ impl<R: CmdRunner> SessionManager<R> {
}
}
} else {
log::trace!("Skipping shutdown commands for session: {:?}", name);
Ok(())
}
})();

let stop_result = tmux
.stop_session(name.as_deref().unwrap_or(""))
.map_err(Into::into);
let stop_result = tmux.stop_session(&name.as_str()).map_err(Into::into);

result.and(stop_result)
}
Expand Down Expand Up @@ -145,6 +175,16 @@ impl<R: CmdRunner> SessionManager<R> {
Ok(yaml)
}

pub(crate) fn is_laio_session(&self, name: &String) -> Result<bool> {
Ok(Tmux::new(
&Some(name.to_string()),
&".".to_string(),
Rc::clone(&self.cmd_runner),
)
.getenv("", "LAIO_CONFIG")
.is_ok())
}

fn process_windows(
&self,
session: &Session,
Expand Down
62 changes: 49 additions & 13 deletions src/app/manager/session_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,28 @@ fn session_stop() {
Rc::clone(&cmd_runner),
);

let res = session.stop(&Some(session_name.to_string()), &false);
let cmds = session.cmd_runner().cmds().borrow();
let res = session.stop(&Some(session_name.to_string()), &false, &false);
let mut cmds = session.cmd_runner().cmds().borrow().clone();
match res {
Ok(_) => {
assert_eq!(cmds.len(), 6);
assert_eq!(cmds[0].as_str(), "tmux has-session -t \"foo\"");
assert_eq!(cmds.len(), 8);
assert_eq!(
cmds.remove(0).to_string(),
"[ -n \"$TMUX\" ] && tmux display-message -p '#S' || true"
);
assert_eq!(cmds.remove(0).to_string(), "tmux has-session -t \"foo\"");
assert_eq!(
cmds[1].as_str(),
cmds.remove(0).to_string(),
"tmux show-environment -t \"foo\": LAIO_CONFIG"
);
assert_eq!(
cmds.remove(0).to_string(),
"tmux show-environment -t \"foo\": LAIO_CONFIG"
);
assert_eq!(cmds[2].as_str(), "dates");
assert_eq!(cmds[3].as_str(), "echo Bye");
assert_eq!(cmds[4].as_str(), "tmux has-session -t \"foo\"");
assert_eq!(cmds[5].as_str(), "tmux kill-session -t \"foo\"");
assert_eq!(cmds.remove(0).to_string(), "dates");
assert_eq!(cmds.remove(0).to_string(), "echo Bye");
assert_eq!(cmds.remove(0).to_string(), "tmux has-session -t \"foo\"");
assert_eq!(cmds.remove(0).to_string(), "tmux kill-session -t \"foo\"");
}
Err(e) => assert_eq!(
e.to_string(),
Expand Down Expand Up @@ -106,6 +114,10 @@ fn session_start() {
cmds.remove(0).to_string(),
"tmux new-session -d -s \"valid\" -c \"/tmp\""
);
assert!(cmds
.remove(0)
.to_string()
.starts_with("tmux setenv -t \"valid\": LAIO_CONFIG"));
assert_eq!(
cmds.remove(0).to_string(),
"tmux show-options -g base-index"
Expand Down Expand Up @@ -196,10 +208,6 @@ fn session_start() {
"tmux select-layout -t \"valid\":@2 \"149e,160x90,0,0[160x22,0,0,5,160x45,0,23,6,160x21,0,69,7]\""
);
assert!(cmds.remove(0).to_string().starts_with("tmux bind-key -T"));
assert!(cmds
.remove(0)
.to_string()
.starts_with("tmux setenv -t \"valid\": LAIO_CONFIG"));
assert_eq!(
cmds.remove(0).to_string(),
"tmux send-keys -t \"valid\":@1.%1 'cd \"/tmp\"' C-m"
Expand Down Expand Up @@ -250,6 +258,34 @@ fn session_start() {
}
}

#[test]
fn laio_session() {
initialize();
let cwd = current_dir().unwrap();

let cmd_runner = Rc::new(MockCmdRunner::new());
let session = SessionManager::new(
&format!("{}/src/session/test", cwd.to_string_lossy()),
Rc::clone(&cmd_runner),
);

let res1 = session.is_laio_session(&"bar".to_string());
let res2 = session.is_laio_session(&"foo".to_string());

let mut cmds = session.cmd_runner().cmds().borrow().clone();
assert_eq!(
cmds.remove(0).to_string(),
"tmux show-environment -t \"bar\": LAIO_CONFIG"
);
assert_eq!(
cmds.remove(0).to_string(),
"tmux show-environment -t \"foo\": LAIO_CONFIG"
);

assert_eq!(res1.unwrap(), false);
assert_eq!(res2.unwrap(), true);
}

#[test]
fn session_to_yaml() {
initialize();
Expand Down
11 changes: 9 additions & 2 deletions src/app/tmux.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::anyhow;
use anyhow::Error;
use anyhow::Result;
use serde::Deserialize;
use std::{cell::RefCell, collections::VecDeque, fmt::Debug, rc::Rc};
use termion::terminal_size;
Expand Down Expand Up @@ -31,7 +32,7 @@ impl<R: CmdRunner> Tmux<R> {
) -> Self {
Self {
session_name: match session_name {
Some(s) => s.clone(),
Some(s) => s.to_string(),
None => cmd_runner
.run(&cmd_basic!("tmux display-message -p \\#S"))
.unwrap_or_else(|_| "laio".to_string()),
Expand Down Expand Up @@ -79,6 +80,12 @@ impl<R: CmdRunner> Tmux<R> {
.map_or(false, |s: String| !s.is_empty())
}

pub(crate) fn current_session_name(&self) -> Result<String, Error> {
self.cmd_runner.run(&cmd_basic!(
"[ -n \"$TMUX\" ] && tmux display-message -p '#S' || true"
))
}

pub(crate) fn stop_session(&self, name: &str) -> Result<(), Error> {
self.session_exists(&name)
.then(|| {
Expand Down Expand Up @@ -140,7 +147,7 @@ impl<R: CmdRunner> Tmux<R> {
))
}

pub(crate) fn getenv(&self, target: &str, name: &str) -> Result<String, Error> {
pub(crate) fn getenv(&self, target: &str, name: &str) -> Result<String> {
let output: String = self.cmd_runner.run(&cmd_basic!(
"tmux show-environment -t \"{}\":{} {}",
&self.session_name,
Expand Down
Loading

0 comments on commit 0b854f0

Please sign in to comment.