#![doc = include_str!("../README.md")]
use std::io::stderr;
use config::Config;
use tokio::net::TcpListener;
mod backend;
mod config;
mod diagnostics;
mod dictionary_io;
mod document_state;
mod git_commit_parser;
mod ignored_lints_io;
mod io_utils;
mod pos_conv;
use backend::Backend;
use clap::Parser;
use tower_lsp_server::{LspService, Server};
use tracing::{Level, error, info};
use tracing_subscriber::FmtSubscriber;
static DEFAULT_ADDRESS: &str = "127.0.0.1:4000";
pub fn ls_version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
#[derive(Debug, Parser)]
#[command(version, about)]
struct Args {
#[arg(short, long, default_value_t = false)]
stdio: bool,
#[arg(long, default_value_t = false)]
skip_version_check: bool,
}
#[tokio::main(worker_threads = 4)]
async fn main() -> anyhow::Result<()> {
let subscriber = FmtSubscriber::builder()
.map_writer(move |_| stderr)
.with_ansi(false)
.with_max_level(Level::WARN)
.finish();
tracing::subscriber::set_global_default(subscriber)?;
let args = Args::parse();
let config = Config::default();
if !args.skip_version_check {
tokio::spawn(log_version_info());
}
let (service, socket) = LspService::new(|client| Backend::new(client, config));
if args.stdio {
let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout();
Server::new(stdin, stdout, socket).serve(service).await;
} else {
let listener = TcpListener::bind(DEFAULT_ADDRESS).await.unwrap();
println!("Listening on {}", DEFAULT_ADDRESS);
let (stream, _) = listener.accept().await.unwrap();
let (read, write) = tokio::io::split(stream);
Server::new(read, write, socket).serve(service).await;
}
Ok(())
}
async fn get_latest_version() -> Result<String, reqwest::Error> {
let client = reqwest::Client::new();
client
.get("https://writewithharper.com/latestversion")
.header("Harper-Version", harper_core::core_version())
.send()
.await?
.error_for_status()?
.text()
.await
}
async fn log_version_info() {
match get_latest_version().await {
Ok(version) => info!("Latest available Harper version: {}", version),
Err(_err) => error!("Unable to obtain latest version."),
}
info!(
"Current harper-core version: {}",
harper_core::core_version()
);
info!("Current harper-ls version: {}", ls_version());
}