Skip to content

Commit

Permalink
Allow formatting via latexindent for BibTeX files
Browse files Browse the repository at this point in the history
  • Loading branch information
pfoerster committed Apr 11, 2020
1 parent d030edf commit 8b2d3a6
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 51 deletions.
5 changes: 4 additions & 1 deletion src/citeproc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ pub fn render_citation(tree: &bibtex::Tree, key: &str) -> Option<MarkupContent>
}

fn convert_to_ris(tree: &bibtex::Tree, key: &str) -> Option<RisReference> {
let options = BibtexFormattingOptions { line_length: None };
let options = BibtexFormattingOptions {
line_length: None,
formatter: None,
};
let params = bibtex::FormattingParams {
insert_spaces: true,
tab_size: 4,
Expand Down
2 changes: 1 addition & 1 deletion src/hover/bibtex/string_reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl BibtexStringReferenceHoverProvider {
return None;
}

let options = BibtexFormattingOptions { line_length: None };
let options = BibtexFormattingOptions { line_length: None, formatter: None };
let text = bibtex::format(
tree,
tree.children(string_node).next()?,
Expand Down
14 changes: 14 additions & 0 deletions src/protocol/options.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum BibtexFormatter {
Texlab,
Latexindent,
}

impl Default for BibtexFormatter {
fn default() -> Self {
Self::Texlab
}
}

#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BibtexFormattingOptions {
pub line_length: Option<i32>,
pub formatter: Option<BibtexFormatter>,
}

#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
Expand Down
67 changes: 40 additions & 27 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
reference::ReferenceProvider,
rename::{PrepareRenameProvider, RenameProvider},
symbol::{document_symbols, workspace_symbols, SymbolProvider},
syntax::{bibtex, latex, CharStream, SyntaxNode},
syntax::{bibtex, latexindent, CharStream, SyntaxNode},
tex::{DistributionKind, DynamicDistribution, KpsewhichError},
workspace::{DocumentContent, Workspace},
};
Expand Down Expand Up @@ -378,17 +378,9 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
.await?;
let mut edits = Vec::new();
match &req.current().content {
DocumentContent::Latex(_) => match latex::format(&req.current().text).await {
Ok(text) => {
let mut stream = CharStream::new(&text);
while stream.next().is_some() {}
let range = Range::new(Position::new(0, 0), stream.current_position);
edits.push(TextEdit::new(range, text));
}
Err(why) => {
debug!("Failed to run latexindent.pl: {}", why);
}
},
DocumentContent::Latex(_) => {
Self::run_latexindent(&req.current().text, "tex", &mut edits).await;
}
DocumentContent::Bibtex(tree) => {
let options = req
.options
Expand All @@ -397,28 +389,49 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
.and_then(|opts| opts.formatting)
.unwrap_or_default();

let params = bibtex::FormattingParams {
tab_size: req.params.options.tab_size as usize,
insert_spaces: req.params.options.insert_spaces,
options: &options,
};

for node in tree.children(tree.root) {
let should_format = match &tree.graph[node] {
bibtex::Node::Preamble(_) | bibtex::Node::String(_) => true,
bibtex::Node::Entry(entry) => !entry.is_comment(),
_ => false,
};
if should_format {
let text = bibtex::format(&tree, node, params);
edits.push(TextEdit::new(tree.graph[node].range(), text));
match options.formatter.unwrap_or_default() {
BibtexFormatter::Texlab => {
let params = bibtex::FormattingParams {
tab_size: req.params.options.tab_size as usize,
insert_spaces: req.params.options.insert_spaces,
options: &options,
};

for node in tree.children(tree.root) {
let should_format = match &tree.graph[node] {
bibtex::Node::Preamble(_) | bibtex::Node::String(_) => true,
bibtex::Node::Entry(entry) => !entry.is_comment(),
_ => false,
};
if should_format {
let text = bibtex::format(&tree, node, params);
edits.push(TextEdit::new(tree.graph[node].range(), text));
}
}
}
BibtexFormatter::Latexindent => {
Self::run_latexindent(&req.current().text, "bib", &mut edits).await;
}
}
}
}
Ok(edits)
}

async fn run_latexindent(old_text: &str, extension: &str, edits: &mut Vec<TextEdit>) {
match latexindent::format(old_text, extension).await {
Ok(new_text) => {
let mut stream = CharStream::new(&old_text);
while stream.next().is_some() {}
let range = Range::new(Position::new(0, 0), stream.current_position);
edits.push(TextEdit::new(range, new_text));
}
Err(why) => {
debug!("Failed to run latexindent.pl: {}", why);
}
}
}

#[jsonrpc_method("textDocument/prepareRename", kind = "request")]
pub async fn prepare_rename(
&self,
Expand Down
1 change: 1 addition & 0 deletions src/syntax/bibtex/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ mod tests {
let tree = bibtex::open(source);
let options = BibtexFormattingOptions {
line_length: Some(line_length),
formatter: None,
};

let mut children = tree.children(tree.root);
Expand Down
20 changes: 0 additions & 20 deletions src/syntax/latex/formatter.rs

This file was deleted.

3 changes: 1 addition & 2 deletions src/syntax/latex/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
mod analysis;
mod ast;
mod formatter;
mod lexer;
mod parser;

pub use self::{analysis::*, ast::*, formatter::*};
pub use self::{analysis::*, ast::*};

use self::{lexer::Lexer, parser::Parser};
use crate::{
Expand Down
21 changes: 21 additions & 0 deletions src/syntax/latexindent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use std::{io, process::Stdio};
use tempfile::tempdir;
use tokio::{fs, process::Command};

pub async fn format(text: &str, extension: &str) -> io::Result<String> {
let dir = tempdir()?;
let input = format!("input.{}", extension);
let output = format!("output.{}", extension);
fs::write(dir.path().join(&input), text).await?;

Command::new("latexindent")
.args(&["-o", &output, &input])
.current_dir(dir.path())
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()?
.await?;

fs::read_to_string(dir.path().join(&output)).await
}
1 change: 1 addition & 0 deletions src/syntax/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod bibtex;
mod lang_data;
pub mod latex;
pub mod latexindent;
mod lsp_kind;
mod text;

Expand Down

0 comments on commit 8b2d3a6

Please sign in to comment.