Skip to content

Commit

Permalink
feat(nvim): control what direction to open log buf
Browse files Browse the repository at this point in the history
  • Loading branch information
kkharji committed May 7, 2022
1 parent a9eede7 commit a6d7251
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[features]
default = [ ]
xcodegen = [ "async", "dirs" ]
daemon = [ "serial", "compilation", "logging", "async", "watcher", "proc", "xcodegen", "parity-tokio-ipc", "nvim-rs", "async-stream", "tokio-stream" ]
daemon = [ "serial", "compilation", "logging", "async", "watcher", "proc", "xcodegen", "parity-tokio-ipc", "nvim-rs", "async-stream", "tokio-stream", "strum" ]
server = [ "serial", "logging", "dirs", "bsp-server", "url", "wax", "shell-words", "compilation" ]
lua = [ "mlua" ]
serial = [ "serde", "serde_json", "serde_yaml" ]
Expand Down
3 changes: 3 additions & 0 deletions lua/xcodebase/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ local defaults = {
--- Log level. Set to error to ignore everything
--- { "trace", "debug", "info", "warn", "error" }
log_level = "debug",
--- Default log buffer direction.
--- { "horizontal", "vertical", "float" }
default_log_buffer_direction = "horizontal",
}

--- Enahnced version of builtin type function that inclued list type.
Expand Down
62 changes: 47 additions & 15 deletions src/daemon/nvim.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
#![allow(dead_code)]
use std::{ops, path::Path};
use tokio_stream::StreamExt;
use std::{ops, path::Path, str::FromStr};
use tap::Pipe;
use tokio_stream::{Stream, StreamExt};

use anyhow::Result;
use anyhow::{Context, Result};
use nvim_rs::{
compat::tokio::Compat, create, error::LoopError, rpc::handler::Dummy, Buffer, Neovim,
};
use parity_tokio_ipc::Connection;
use tokio::{io::WriteHalf, task::JoinHandle};

pub struct Nvim {
pub nvim: Neovim<Compat<WriteHalf<Connection>>>,
handler: JoinHandle<Result<(), Box<LoopError>>>,
pub log_bufnr: i64,
}

#[derive(strum::EnumString)]
#[strum(ascii_case_insensitive)]
pub enum WindowType {
Float,
Vertical,
Horizontal,
}

pub struct Nvim {
pub nvim: Neovim<Compat<WriteHalf<Connection>>>,
handler: JoinHandle<Result<(), Box<LoopError>>>,
pub log_bufnr: i64,
impl WindowType {
fn to_nvim_command(&self, bufnr: i64) -> String {
match self {
// TOOD: support build log float
WindowType::Float => format!("sbuffer {bufnr}"),
WindowType::Vertical => format!("vert sbuffer {bufnr}"),
WindowType::Horizontal => format!("sbuffer {bufnr}"),
}
}
}

impl Nvim {
pub async fn new<P: AsRef<Path> + Clone>(address: P) -> Result<Self> {
let (neovim, handler) = create::tokio::new_path(address, Dummy::new()).await?;
let buffer = neovim.create_buf(false, true).await?;

buffer.set_name("[Xcodebase Logs]").await?;

Ok(Self {
nvim: neovim,
handler,
Expand Down Expand Up @@ -63,8 +80,8 @@ impl Nvim {
pub async fn log_to_buffer(
&self,
title: &str,
direction: WindowType,
mut stream: impl tokio_stream::Stream<Item = String> + Unpin,
direction: Option<WindowType>,
mut stream: impl Stream<Item = String> + Unpin,
clear: bool,
) -> Result<()> {
let title = format!("[ {title} ]: ----> ");
Expand All @@ -79,14 +96,14 @@ impl Nvim {
count => count,
};

// TODO(nvim): build log control what direction to open buffer
// TODO(nvim): build log correct width
// TODO(nvim): build log auto scroll
let command = match direction {
// TOOD: build log float
WindowType::Float => format!("sbuffer {}", self.log_bufnr),
WindowType::Vertical => format!("vert sbuffer {}", self.log_bufnr),
WindowType::Horizontal => format!("sbuffer {}", self.log_bufnr),
let command = match self.get_window_direction(direction).await {
Ok(open_command) => open_command,
Err(e) => {
tracing::error!("Unable to convert value to string {e}");
WindowType::Horizontal.to_nvim_command(self.log_bufnr)
}
};

self.exec(&command, false).await?;
Expand All @@ -101,6 +118,21 @@ impl Nvim {

Ok(())
}

async fn get_window_direction(&self, direction: Option<WindowType>) -> Result<String> {
if let Some(direction) = direction {
return Ok(direction.to_nvim_command(self.log_bufnr));
};

"return require'xcodebase.config'.values.default_log_buffer_direction"
.pipe(|str| self.exec_lua(str, vec![]))
.await?
.as_str()
.ok_or_else(|| anyhow::anyhow!("Unable to covnert value to string"))?
.pipe(WindowType::from_str)
.map(|d| d.to_nvim_command(self.log_bufnr))
.context("Convert to string to direction")
}
}

impl std::fmt::Debug for Nvim {
Expand Down
77 changes: 28 additions & 49 deletions src/daemon/requests/build.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
#[cfg(feature = "mlua")]
use crate::daemon::Daemon;

#[cfg(feature = "daemon")]
use crate::daemon::nvim::WindowType;

#[cfg(feature = "daemon")]
use async_stream::stream;

#[cfg(feature = "daemon")]
use tokio_stream::StreamExt;

#[cfg(feature = "daemon")]
use tap::Pipe;

#[cfg(feature = "daemon")]
use crate::daemon::{DaemonRequestHandler, DaemonState};

Expand All @@ -33,65 +27,53 @@ impl Build {
pub const KEY: &'static str = "build";
}

// TODO: Implement build command
// On neovim side:
// - Call the command after picking the target. If their is only a single target then just use that
// - This requires somehow given the client all information it needs in order present the user
// with the options needed to build
#[cfg(feature = "daemon")]
#[async_trait::async_trait]
impl DaemonRequestHandler<Build> for Build {
fn parse(args: Vec<&str>) -> Result<Self> {
if let (Some(pid), Some(root)) = (args.get(0), args.get(1)) {
Ok(Self {
return Ok(Self {
pid: pid.parse::<i32>()?,
root: root.to_string(),
target: args.get(2).map(ToString::to_string),
configuration: args.get(3).map(ToString::to_string),
scheme: args.get(4).map(ToString::to_string),
})
} else {
anyhow::bail!("Missing arugments: {:?}", args)
});
}

anyhow::bail!("Missing arugments: {:?}", args)
}

async fn handle(&self, state: DaemonState) -> Result<()> {
tracing::debug!("Handling build request..");

let state = state.lock().await;
let ws = match state.workspaces.get(&self.root) {
Some(ws) => ws,
None => anyhow::bail!("No workspace for {}", self.root),
};
let nvim = match ws.clients.get(&self.pid) {
Some(nvim) => nvim,
None => anyhow::bail!("No nvim client found to build project."),
};

let mut logs = ws.project.xcodebuild(&["build"]).await?;
let stream = Box::pin(stream! {
while let Some(step) = logs.next().await {
let line = match step {
xcodebuild::parser::Step::Exit(_) => { continue; }
step => step.to_string().trim().to_string(),
};

ws.project
.xcodebuild(&["build"])
.await?
.pipe(|mut logs| {
stream! {
while let Some(step) = logs.next().await {
let line = match step {
xcodebuild::parser::Step::Exit(_) => { continue; }
step => step.to_string().trim().to_string(),
};

if !line.is_empty() {
for line in line.split("\n") {
yield line.to_string();
}
}
if !line.is_empty() {
for line in line.split("\n") {
yield line.to_string();
}
}
})
.pipe(Box::pin)
.pipe(|stream| async {
let nvim = match ws.clients.get(&self.pid) {
Some(nvim) => nvim,
None => anyhow::bail!("No nvim client found to build project."),
};
nvim.log_to_buffer("Build", WindowType::Vertical, stream, true)
.await
})
.await?;
}
});

nvim.log_to_buffer("Build", None, stream, true).await?;

Ok(())
}
Expand All @@ -104,13 +86,10 @@ impl Build {
(pid, root, t, c, s): (i32, String, Option<String>, Option<String>, Option<String>),
) -> mlua::Result<()> {
use crate::util::mlua::LuaExtension;
lua.trace(
format!(
"Build (target: {:?} configuration: {:?}, scheme: {:?})",
t, c, s
)
.as_ref(),
)?;
lua.trace(&format!(
"Build (target: {:?} configuration: {:?}, scheme: {:?})",
t, c, s
))?;

let mut args = vec!["build".into(), pid.to_string(), root];

Expand Down

0 comments on commit a6d7251

Please sign in to comment.