Skip to content

Instantly share code, notes, and snippets.

@kraftwerk28
Created February 2, 2021 23:04
Show Gist options
  • Save kraftwerk28/b78308e82c90b928c69ef7a387802cf7 to your computer and use it in GitHub Desktop.
Save kraftwerk28/b78308e82c90b928c69ef7a387802cf7 to your computer and use it in GitHub Desktop.
use regex::Regex;
use rmpv::{decode::read_value, encode::write_value, Value};
use std::{net::TcpStream, path::PathBuf, sync::atomic};
macro_rules! rmp_vec {
() => (Value::Array(Vec::new()));
($($x:expr),+$(,)*) => (Value::from([$(Value::from($x)),+].to_vec()));
}
struct Client {
conn: TcpStream,
tag_re: Regex,
}
static MSG_ID: atomic::AtomicU8 = atomic::AtomicU8::new(0);
impl Client {
fn new() -> Option<Self> {
let conn = TcpStream::connect("127.0.0.1:6969").ok()?;
let tag_re: Regex = Regex::new(r"\*(.*?)\*").ok()?;
Some(Self { conn, tag_re })
}
fn call(&mut self, method: &str, args: Value) -> Option<Value> {
write_value(&mut self.conn, &rmp_vec![0, msgid(), method, args]).ok()?;
read_value(&mut self.conn).ok()
}
fn get_help_link(&mut self, topic: &str) -> Option<String> {
let help_cmd = format!(":h {}", topic);
self.call("nvim_command", rmp_vec![help_cmd])?;
let tagpath = self
.call("nvim_buf_get_name", rmp_vec![0])
.and_then(|it| it[3].as_str().map(str::to_string))
.map(|it| PathBuf::from(it).file_stem().map(|it| it.to_owned()))
.flatten()?;
let tag = self
.call("nvim_get_current_line", rmp_vec![])
.and_then(|it| it[3].as_str().map(str::to_string))
.map(|it| self.tag_re.captures(&it).map(|c| c[1].to_string()))
.flatten()?;
Some(format!(
"https://neovim.io/doc/user/{}.html#{}",
tagpath.to_str()?,
tag
))
}
}
fn msgid() -> u8 {
MSG_ID.fetch_add(1, atomic::Ordering::SeqCst)
}
fn main() {
let mut cl = Client::new().unwrap();
println!("{:?}", cl.get_help_link("highlight"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment