Skip to content

Commit

Permalink
Add command to show dependency graph as DOT file
Browse files Browse the repository at this point in the history
  • Loading branch information
pfoerster committed Mar 12, 2023
1 parent 1fb8eb7 commit 1c3cf57
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `texlab.experimental.mathEnvironments`
- `texlab.experimental.enumEnvironments`
- `texlab.experimental.verbatimEnvironments`
- Add `texlab.changeEnvironment` workspace command ([#849](https://github.com/latex-lsp/texlab/issues/849))
- Add `texlab.showDependencyGraph` workspace command

### Changed

Expand Down
9 changes: 6 additions & 3 deletions src/db/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ pub fn hidden_dependencies(
base_dir: Location,
dependencies: &mut Vec<Dependency>,
) {
dependencies.extend(hidden_dependency(db, document, base_dir, "log"));
dependencies.extend(hidden_dependency(db, document, base_dir, "aux"));
let uri = document.location(db).uri(db).as_str();
if document.language(db) == Language::Tex && !uri.ends_with(".aux") {
dependencies.extend(hidden_dependency(db, document, base_dir, "log"));
dependencies.extend(hidden_dependency(db, document, base_dir, "aux"));
}
}

#[salsa::tracked]
Expand Down Expand Up @@ -158,7 +161,7 @@ impl DependencyGraph {
}
}

#[salsa::tracked]
#[salsa::tracked(return_ref)]
pub fn dependency_graph(db: &dyn Db, start: Document) -> DependencyGraph {
let workspace = Workspace::get(db);

Expand Down
2 changes: 1 addition & 1 deletion src/features/definition/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(super) fn goto_definition(context: &CursorContext) -> Option<Vec<DefinitionR
.iter()
.copied()
.chain(std::iter::once(context.document))
.flat_map(|parent| dependency_graph(db, parent).edges)
.flat_map(|parent| dependency_graph(db, parent).edges.iter())
.filter(|edge| edge.source == context.document)
.find_map(|edge| {
let range = edge.origin?.link.range(db);
Expand Down
1 change: 1 addition & 0 deletions src/features/workspace_command.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod change_environment;
pub mod clean;
pub mod dep_graph;
4 changes: 2 additions & 2 deletions src/features/workspace_command/change_environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn change_environment_context(
new_name: params.new_name,
},
)
.ok_or(ChangeEnvironmentError::FailedCreatiingContext.into())
.ok_or(ChangeEnvironmentError::FailedCreatingContext.into())
}

pub fn change_environment(
Expand Down Expand Up @@ -87,7 +87,7 @@ pub enum ChangeEnvironmentError {
InvalidArg(serde_json::Error),

#[error("failed creating context")]
FailedCreatiingContext,
FailedCreatingContext,

#[error("could not create workspaces edit")]
CouldNotCreateWorkspaceEdit,
Expand Down
57 changes: 57 additions & 0 deletions src/features/workspace_command/dep_graph.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use anyhow::Result;
use itertools::Itertools;
use std::io::Write;

use rustc_hash::FxHashMap;

use crate::{
db::{dependency_graph, Document, Workspace},
Db,
};

pub fn show_dependency_graph(db: &dyn Db) -> Result<String> {
let workspace = Workspace::get(db);

let documents = workspace
.documents(db)
.iter()
.enumerate()
.map(|(i, doc)| (*doc, format!("v{i:0>5}")))
.collect::<FxHashMap<Document, String>>();

let mut writer = Vec::new();
writeln!(&mut writer, "digraph G {{")?;
writeln!(&mut writer, "rankdir = LR;")?;

for (document, node) in &documents {
let label = document.location(db).uri(db).as_str();
let shape = if document.can_be_root(db) {
"tripleoctagon"
} else if document.can_be_built(db) {
"doubleoctagon"
} else {
"octagon"
};

writeln!(&mut writer, "\t{node} [label=\"{label}\", shape={shape}];")?;
}

for edge in workspace
.documents(db)
.iter()
.flat_map(|start| dependency_graph(db, *start).edges.iter())
.unique()
{
let source = &documents[&edge.source];
let target = &documents[&edge.target];
let label = edge
.origin
.as_ref()
.map_or("<artifact>", |origin| &origin.link.path(db).text(db));

writeln!(&mut writer, "\t{source} -> {target} [label=\"{label}\"];")?;
}

writeln!(&mut writer, "}}")?;
Ok(String::from_utf8(writer)?)
}
5 changes: 4 additions & 1 deletion src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{
completion::{self, builder::CompletionItemData},
definition, folding, formatting, forward_search, highlight, hover, inlay_hint, link,
reference, rename, symbol,
workspace_command::{change_environment, clean},
workspace_command::{change_environment, clean, dep_graph},
},
normalize_uri,
syntax::bibtex,
Expand Down Expand Up @@ -675,6 +675,9 @@ impl Server {
change_environment::change_environment(db, params.arguments)
});
}
"texlab.showDependencyGraph" => {
self.run_with_db(id, move |db| dep_graph::show_dependency_graph(db).unwrap());
}
_ => {
self.client
.send_error(
Expand Down

0 comments on commit 1c3cf57

Please sign in to comment.