summaryrefslogtreecommitdiff
path: root/support/texlab/src/main.rs
blob: 71338f1bcdb48ff81cedf84b3e936d305ee372db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::{env, fs::OpenOptions, io, path::PathBuf};

use anyhow::Result;
use clap::Parser;
use log::LevelFilter;
use lsp_server::Connection;
use texlab::Server;

/// An implementation of the Language Server Protocol for LaTeX
#[derive(Debug, Parser)]
#[clap(version)]
struct Opts {
    /// Increase message verbosity (-vvvv for max verbosity)
    #[clap(short, long, parse(from_occurrences))]
    verbosity: u8,

    /// No output printed to stderr
    #[clap(short, long)]
    quiet: bool,

    /// Write the logging output to FILE
    #[clap(long, name = "FILE", parse(from_os_str))]
    log_file: Option<PathBuf>,

    /// Print version information and exit
    #[clap(short = 'V', long)]
    version: bool,
}

fn main() -> Result<()> {
    let opts = Opts::parse();
    setup_logger(opts);

    let (connection, threads) = Connection::stdio();
    Server::with_connection(connection, env::current_dir()?, true).run()?;
    threads.join()?;

    Ok(())
}

fn setup_logger(opts: Opts) {
    let verbosity_level = if !opts.quiet {
        match opts.verbosity {
            0 => LevelFilter::Error,
            1 => LevelFilter::Warn,
            2 => LevelFilter::Info,
            3 => LevelFilter::Debug,
            _ => LevelFilter::Trace,
        }
    } else {
        LevelFilter::Off
    };

    let logger = fern::Dispatch::new()
        .format(|out, message, record| out.finish(format_args!("{} - {}", record.level(), message)))
        .level(verbosity_level)
        .filter(|metadata| {
            metadata.target().contains("texlab") || metadata.target().contains("lsp_server")
        })
        .chain(io::stderr());

    let logger = match opts.log_file {
        Some(log_file) => logger.chain(
            OpenOptions::new()
                .write(true)
                .create(true)
                .open(log_file)
                .expect("failed to open log file"),
        ),
        None => logger,
    };

    logger.apply().expect("failed to initialize logger");
}