Skip to content

Commit

Permalink
Merge pull request #9 from zdcthomas/app-refactor
Browse files Browse the repository at this point in the history
ACTUALLY REFACTORS STUFF WOOT
  • Loading branch information
zdcthomas authored May 21, 2020
2 parents e0465f9 + ff253d7 commit d829e4e
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 106 deletions.
128 changes: 69 additions & 59 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,45 +120,10 @@ id. Pane id's can be found easily with
)
}

// I don't like the repetition here
#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(default = "default_layout_checksum")]
pub layout: String,
#[serde(default = "default_session_name")]
pub session_name: String,
#[serde(default = "default_number_of_panes")]
pub number_of_panes: i32,
#[serde(default = "default_search_dir")]
pub search_dir: PathBuf,
// TODO: This needs to be refactored, not sure how right now though
#[serde(default = "default_selected_dir")]
pub selected_dir: Option<PathBuf>,
#[serde(default = "default_commands")]
pub commands: Vec<String>,
}

impl Default for Config {
fn default() -> Self {
Self {
layout: default_layout_checksum(),
session_name: default_session_name(),
number_of_panes: default_number_of_panes(),
search_dir: dirs::home_dir().unwrap(),
selected_dir: None,
commands: default_commands(),
}
}
}

fn default_search_dir() -> PathBuf {
dirs::home_dir().unwrap()
}

fn default_selected_dir() -> Option<PathBuf> {
None
}

fn default_layout_checksum() -> String {
"34ed,230x56,0,0{132x56,0,0,3,97x56,133,0,222}".to_string()
}
Expand All @@ -176,7 +141,7 @@ fn default_commands() -> Vec<String> {
}

fn config_file_settings() -> config::Config {
let default = Config::default();
let default = WorkSpaceArgs::default();
let mut settings = config::Config::default();
let mut config_conf = dirs::config_dir().unwrap();
config_conf.push("dmux/dmux.conf.xxxx");
Expand Down Expand Up @@ -211,24 +176,61 @@ fn config_file_settings() -> config::Config {
.to_owned()
}

fn settings_config(settings: config::Config, target: Option<&str>) -> Config {
fn settings_config(settings: config::Config, target: Option<&str>) -> WorkSpaceArgs {
if let Some(target) = target {
let profile: Config = settings.get(target).unwrap();
let profile: WorkSpaceArgs = settings.get(target).unwrap();
return profile;
}
let profile: Config = settings.try_into().unwrap();
let profile: WorkSpaceArgs = settings.try_into().unwrap();
profile
}

pub struct PullConfig {
pub repo_url: Url,
pub target_dir: PathBuf,
pub open_config: Config,
pub struct SelectArgs {
pub workspace: WorkSpaceArgs,
}

pub enum CommandType {
Local(Config),
Pull(PullConfig),
Open(OpenArgs),
Select(SelectArgs),
Pull(PullArgs),
}

// I don't like the repetition here
#[derive(Deserialize, Debug)]
pub struct WorkSpaceArgs {
#[serde(default = "default_layout_checksum")]
pub layout: String,
#[serde(default = "default_session_name")]
pub session_name: String,
#[serde(default = "default_number_of_panes")]
pub number_of_panes: i32,
#[serde(default = "default_search_dir")]
pub search_dir: PathBuf,
#[serde(default = "default_commands")]
pub commands: Vec<String>,
}

impl Default for WorkSpaceArgs {
fn default() -> Self {
Self {
layout: default_layout_checksum(),
session_name: default_session_name(),
number_of_panes: default_number_of_panes(),
search_dir: dirs::home_dir().unwrap(),
commands: default_commands(),
}
}
}

pub struct OpenArgs {
pub workspace: WorkSpaceArgs,
pub selected_dir: PathBuf,
}

pub struct PullArgs {
pub repo_url: Url,
pub target_dir: PathBuf,
pub workspace: WorkSpaceArgs,
}

fn read_line_iter() -> String {
Expand All @@ -240,9 +242,7 @@ fn read_line_iter() -> String {
}

fn select_dir(args: &clap::ArgMatches) -> Option<PathBuf> {
if let Some("clone") = args.subcommand_name() {
None
} else if let Ok(selected_dir) = value_t!(args.value_of("selected_dir"), PathBuf) {
if let Ok(selected_dir) = value_t!(args.value_of("selected_dir"), PathBuf) {
Some(selected_dir)
} else if grep_cli::is_readable_stdin() && !grep_cli::is_tty_stdin() {
Some(PathBuf::from(read_line_iter()))
Expand All @@ -251,39 +251,49 @@ fn select_dir(args: &clap::ArgMatches) -> Option<PathBuf> {
}
}

pub fn build_app() -> CommandType {
fn build_workspace_args(args: &clap::ArgMatches) -> WorkSpaceArgs {
let settings = config_file_settings();
let args = args();
let conf_from_settings = settings_config(settings, args.value_of("profile"));
let search_dir =
value_t!(args.value_of("search_dir"), PathBuf).unwrap_or(conf_from_settings.search_dir);

let config = Config {
WorkSpaceArgs {
session_name: value_t!(args.value_of("session_name"), String)
.unwrap_or(conf_from_settings.session_name),
layout: value_t!(args.value_of("layout"), String).unwrap_or(conf_from_settings.layout),
number_of_panes: value_t!(args.value_of("number_of_panes"), i32)
.unwrap_or(conf_from_settings.number_of_panes),
commands: values_t!(args.values_of("commands"), String)
.unwrap_or(conf_from_settings.commands),
selected_dir: select_dir(&args),
search_dir,
};
}
}

pub fn build_app() -> CommandType {
let args = args();
let workspace = build_workspace_args(&args);
match args.subcommand_name() {
None => CommandType::Local(config),
None => {
if let Some(selected_dir) = select_dir(&args) {
CommandType::Open(OpenArgs {
workspace,
selected_dir,
})
} else {
CommandType::Select(SelectArgs { workspace })
}
}
Some("clone") => {
let clone_args = args.subcommand_matches("clone").unwrap();
let url = clone_args
.value_of("repo")
.expect("No repo specified, what should I clone?");
if let Ok(repo_url) = Url::parse(url) {
let pull = PullConfig {
CommandType::Pull(PullArgs {
repo_url,
target_dir: value_t!(args.value_of("target_dir"), PathBuf)
.unwrap_or_else(|_| dirs::home_dir().unwrap()),
open_config: config,
};
CommandType::Pull(pull)
workspace,
})
} else {
panic!("Sorry, {} isn't a valid url!", url);
}
Expand Down
80 changes: 33 additions & 47 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#[macro_use]
extern crate serde_derive;
extern crate clap;
extern crate config;
extern crate dirs;

#[macro_use]
extern crate serde_derive;

extern crate grep_cli;
extern crate skim;
extern crate tmux_interface;
Expand All @@ -15,73 +13,61 @@ mod app;
mod select;
mod tmux;

use app::{
CommandType::{Local, Pull},
Config,
};
use app::CommandType::{Open, Pull, Select};
use select::Selector;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use tmux::{Layout, WorkSpace};
use url::Url;

fn setup_workspace(config: Config, maybe_dir: Option<PathBuf>) {
let selected_dir: PathBuf;
if let Some(dir) = maybe_dir {
selected_dir = dir;
} else if let Some(dir) = config.selected_dir {
selected_dir = dir;
} else {
panic!("No dir was findable");
}

// TODO: can i get rid of this? Put this in a validator?
if !selected_dir.exists() {
panic!("dude, that's not a path")
}
let layout = Layout {
layout_string: config.layout,
window_count: config.number_of_panes,
};
let workspaces = WorkSpace {
commands: config.commands,
dir: String::from(selected_dir.to_str().unwrap()),
layout,
session_name: config.session_name,
window_name: path_to_window_name(&selected_dir).to_string(),
};
tmux::setup_workspace(workspaces);
}

fn main() {
let command = app::build_app();

match command {
Local(config) => {
if config.selected_dir.is_some() {
setup_workspace(config, None)
} else if let Some(dir) = Selector::new(&config.search_dir).select_dir() {
setup_workspace(config, Some(dir))
} else {
panic!()
Open(open_config) => open_selected_dir(open_config),
Select(select_config) => {
if let Some(dir) = Selector::new(&select_config.workspace.search_dir).select_dir() {
open_selected_dir(app::OpenArgs {
selected_dir: dir,
workspace: select_config.workspace,
})
}
}

Pull(pull_config) => {
let dir = clone_from(&pull_config);
setup_workspace(pull_config.open_config, Some(dir))
open_selected_dir(app::OpenArgs {
selected_dir: dir,
workspace: pull_config.workspace,
})
}
}
}

fn open_selected_dir(config: app::OpenArgs) {
if !config.selected_dir.exists() {
panic!("dude, that's not a path")
}
let layout = Layout {
layout_string: config.workspace.layout,
window_count: config.workspace.number_of_panes,
};
let workspaces = WorkSpace {
commands: config.workspace.commands,
dir: String::from(config.selected_dir.to_str().unwrap()),
layout,
session_name: config.workspace.session_name,
window_name: path_to_window_name(&config.selected_dir).to_string(),
};
tmux::setup_workspace(workspaces);
}

// TODO: -> Result<Output, Error>
fn git_url_to_dir_name(url: &Url) -> String {
let segments = url.path_segments().ok_or_else(|| "cannot be base").unwrap();
// TODO: use str.replace here
segments.last().unwrap().replace(".git", "")
}

fn clone_from(config: &app::PullConfig) -> PathBuf {
fn clone_from(config: &app::PullArgs) -> PathBuf {
let dir_name = git_url_to_dir_name(&config.repo_url);
let target = config.target_dir.join(dir_name);
if !target.exists() {
Expand Down

0 comments on commit d829e4e

Please sign in to comment.