Skip to content

Commit 1c3cf57

Browse files
committed
Add command to show dependency graph as DOT file
1 parent 1fb8eb7 commit 1c3cf57

File tree

7 files changed

+73
-7
lines changed

7 files changed

+73
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- `texlab.experimental.mathEnvironments`
1414
- `texlab.experimental.enumEnvironments`
1515
- `texlab.experimental.verbatimEnvironments`
16+
- Add `texlab.changeEnvironment` workspace command ([#849](https://github.com/latex-lsp/texlab/issues/849))
17+
- Add `texlab.showDependencyGraph` workspace command
1618

1719
### Changed
1820

src/db/discovery.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ pub fn hidden_dependencies(
4040
base_dir: Location,
4141
dependencies: &mut Vec<Dependency>,
4242
) {
43-
dependencies.extend(hidden_dependency(db, document, base_dir, "log"));
44-
dependencies.extend(hidden_dependency(db, document, base_dir, "aux"));
43+
let uri = document.location(db).uri(db).as_str();
44+
if document.language(db) == Language::Tex && !uri.ends_with(".aux") {
45+
dependencies.extend(hidden_dependency(db, document, base_dir, "log"));
46+
dependencies.extend(hidden_dependency(db, document, base_dir, "aux"));
47+
}
4548
}
4649

4750
#[salsa::tracked]
@@ -158,7 +161,7 @@ impl DependencyGraph {
158161
}
159162
}
160163

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

src/features/definition/document.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub(super) fn goto_definition(context: &CursorContext) -> Option<Vec<DefinitionR
1212
.iter()
1313
.copied()
1414
.chain(std::iter::once(context.document))
15-
.flat_map(|parent| dependency_graph(db, parent).edges)
15+
.flat_map(|parent| dependency_graph(db, parent).edges.iter())
1616
.filter(|edge| edge.source == context.document)
1717
.find_map(|edge| {
1818
let range = edge.origin?.link.range(db);

src/features/workspace_command.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod change_environment;
22
pub mod clean;
3+
pub mod dep_graph;

src/features/workspace_command/change_environment.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn change_environment_context(
3535
new_name: params.new_name,
3636
},
3737
)
38-
.ok_or(ChangeEnvironmentError::FailedCreatiingContext.into())
38+
.ok_or(ChangeEnvironmentError::FailedCreatingContext.into())
3939
}
4040

4141
pub fn change_environment(
@@ -87,7 +87,7 @@ pub enum ChangeEnvironmentError {
8787
InvalidArg(serde_json::Error),
8888

8989
#[error("failed creating context")]
90-
FailedCreatiingContext,
90+
FailedCreatingContext,
9191

9292
#[error("could not create workspaces edit")]
9393
CouldNotCreateWorkspaceEdit,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use anyhow::Result;
2+
use itertools::Itertools;
3+
use std::io::Write;
4+
5+
use rustc_hash::FxHashMap;
6+
7+
use crate::{
8+
db::{dependency_graph, Document, Workspace},
9+
Db,
10+
};
11+
12+
pub fn show_dependency_graph(db: &dyn Db) -> Result<String> {
13+
let workspace = Workspace::get(db);
14+
15+
let documents = workspace
16+
.documents(db)
17+
.iter()
18+
.enumerate()
19+
.map(|(i, doc)| (*doc, format!("v{i:0>5}")))
20+
.collect::<FxHashMap<Document, String>>();
21+
22+
let mut writer = Vec::new();
23+
writeln!(&mut writer, "digraph G {{")?;
24+
writeln!(&mut writer, "rankdir = LR;")?;
25+
26+
for (document, node) in &documents {
27+
let label = document.location(db).uri(db).as_str();
28+
let shape = if document.can_be_root(db) {
29+
"tripleoctagon"
30+
} else if document.can_be_built(db) {
31+
"doubleoctagon"
32+
} else {
33+
"octagon"
34+
};
35+
36+
writeln!(&mut writer, "\t{node} [label=\"{label}\", shape={shape}];")?;
37+
}
38+
39+
for edge in workspace
40+
.documents(db)
41+
.iter()
42+
.flat_map(|start| dependency_graph(db, *start).edges.iter())
43+
.unique()
44+
{
45+
let source = &documents[&edge.source];
46+
let target = &documents[&edge.target];
47+
let label = edge
48+
.origin
49+
.as_ref()
50+
.map_or("<artifact>", |origin| &origin.link.path(db).text(db));
51+
52+
writeln!(&mut writer, "\t{source} -> {target} [label=\"{label}\"];")?;
53+
}
54+
55+
writeln!(&mut writer, "}}")?;
56+
Ok(String::from_utf8(writer)?)
57+
}

src/server.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::{
2929
completion::{self, builder::CompletionItemData},
3030
definition, folding, formatting, forward_search, highlight, hover, inlay_hint, link,
3131
reference, rename, symbol,
32-
workspace_command::{change_environment, clean},
32+
workspace_command::{change_environment, clean, dep_graph},
3333
},
3434
normalize_uri,
3535
syntax::bibtex,
@@ -675,6 +675,9 @@ impl Server {
675675
change_environment::change_environment(db, params.arguments)
676676
});
677677
}
678+
"texlab.showDependencyGraph" => {
679+
self.run_with_db(id, move |db| dep_graph::show_dependency_graph(db).unwrap());
680+
}
678681
_ => {
679682
self.client
680683
.send_error(

0 commit comments

Comments
 (0)