feat: improve error message for files with an unknown grammar path

This commit is contained in:
Amaan Qureshi 2024-02-12 16:13:22 -05:00
parent 48deb309db
commit 21f25a5305
7 changed files with 89 additions and 19 deletions

1
Cargo.lock generated
View file

@ -1340,6 +1340,7 @@ dependencies = [
"cc",
"dirs",
"fs4",
"indoc",
"libloading",
"once_cell",
"regex",

View file

@ -34,6 +34,7 @@ dirs.workspace = true
glob.workspace = true
html-escape.workspace = true
indexmap.workspace = true
indoc.workspace = true
lazy_static.workspace = true
log.workspace = true
memchr.workspace = true
@ -80,7 +81,6 @@ tempfile.workspace = true
pretty_assertions.workspace = true
ctor.workspace = true
unindent.workspace = true
indoc.workspace = true
[build-dependencies]
toml.workspace = true

View file

@ -575,6 +575,7 @@ fn run() -> Result<()> {
highlighter.parser = parser;
test_highlight::test_highlights(
&loader,
&config.get()?,
&mut highlighter,
&test_highlight_dir,
test_options.apply_all_captures,
@ -586,7 +587,7 @@ fn run() -> Result<()> {
if test_tag_dir.is_dir() {
let mut tags_context = TagsContext::new();
tags_context.parser = parser;
test_tags::test_tags(&loader, &mut tags_context, &test_tag_dir)?;
test_tags::test_tags(&loader, &config.get()?, &mut tags_context, &test_tag_dir)?;
}
}
@ -662,7 +663,7 @@ fn run() -> Result<()> {
if let Some(v) = loader.language_configuration_for_file_name(path)? {
v
} else {
eprintln!("No language found for path {path:?}");
eprintln!("{}", util::lang_not_found_for_path(path, &loader_config));
continue;
}
}
@ -744,6 +745,7 @@ fn run() -> Result<()> {
let paths = collect_paths(tags_options.paths_file.as_deref(), tags_options.paths)?;
tags::generate_tags(
&loader,
&config.get()?,
tags_options.scope.as_deref(),
&paths,
tags_options.quiet,

View file

@ -4,11 +4,12 @@ use std::io::{self, Write};
use std::path::Path;
use std::time::Instant;
use std::{fs, str};
use tree_sitter_loader::Loader;
use tree_sitter_loader::{Config, Loader};
use tree_sitter_tags::TagsContext;
pub fn generate_tags(
loader: &Loader,
loader_config: &Config,
scope: Option<&str>,
paths: &[String],
quiet: bool,
@ -35,7 +36,7 @@ pub fn generate_tags(
if let Some(v) = loader.language_configuration_for_file_name(path)? {
v
} else {
eprintln!("No language found for path {path:?}");
eprintln!("{}", util::lang_not_found_for_path(path, loader_config));
continue;
}
}

View file

@ -1,11 +1,16 @@
use crate::query_testing::{parse_position_comments, Assertion};
use ansi_term::Colour;
use anyhow::{anyhow, Result};
use std::fs;
use std::path::Path;
use ansi_term::Colour;
use anyhow::{anyhow, Result};
use tree_sitter::Point;
use tree_sitter_highlight::{Highlight, HighlightConfiguration, HighlightEvent, Highlighter};
use tree_sitter_loader::Loader;
use tree_sitter_loader::{Config, Loader};
use super::{
query_testing::{parse_position_comments, Assertion},
util,
};
#[derive(Debug)]
pub struct Failure {
@ -40,16 +45,25 @@ impl std::fmt::Display for Failure {
pub fn test_highlights(
loader: &Loader,
loader_config: &Config,
highlighter: &mut Highlighter,
directory: &Path,
apply_all_captures: bool,
) -> Result<()> {
println!("syntax highlighting:");
test_highlights_indented(loader, highlighter, directory, apply_all_captures, 2)
test_highlights_indented(
loader,
loader_config,
highlighter,
directory,
apply_all_captures,
2,
)
}
fn test_highlights_indented(
loader: &Loader,
loader_config: &Config,
highlighter: &mut Highlighter,
directory: &Path,
apply_all_captures: bool,
@ -70,6 +84,7 @@ fn test_highlights_indented(
println!("{}:", test_file_name.into_string().unwrap());
if test_highlights_indented(
loader,
loader_config,
highlighter,
&test_file_path,
apply_all_captures,
@ -82,7 +97,12 @@ fn test_highlights_indented(
} else {
let (language, language_config) = loader
.language_configuration_for_file_name(&test_file_path)?
.ok_or_else(|| anyhow!("No language found for path {test_file_path:?}"))?;
.ok_or_else(|| {
anyhow!(
"{}",
util::lang_not_found_for_path(test_file_path.as_path(), loader_config)
)
})?;
let highlight_config = language_config
.highlight_config(language, apply_all_captures, None)?
.ok_or_else(|| anyhow!("No highlighting config found for {test_file_path:?}"))?;

View file

@ -1,12 +1,17 @@
use crate::query_testing::{parse_position_comments, Assertion};
use ansi_term::Colour;
use anyhow::{anyhow, Result};
use std::fs;
use std::path::Path;
use ansi_term::Colour;
use anyhow::{anyhow, Result};
use tree_sitter::Point;
use tree_sitter_loader::Loader;
use tree_sitter_loader::{Config, Loader};
use tree_sitter_tags::{TagsConfiguration, TagsContext};
use super::{
query_testing::{parse_position_comments, Assertion},
util,
};
#[derive(Debug)]
pub struct Failure {
row: usize,
@ -38,7 +43,12 @@ impl std::fmt::Display for Failure {
}
}
pub fn test_tags(loader: &Loader, tags_context: &mut TagsContext, directory: &Path) -> Result<()> {
pub fn test_tags(
loader: &Loader,
loader_config: &Config,
tags_context: &mut TagsContext,
directory: &Path,
) -> Result<()> {
let mut failed = false;
println!("tags:");
@ -48,7 +58,12 @@ pub fn test_tags(loader: &Loader, tags_context: &mut TagsContext, directory: &Pa
let test_file_name = tag_test_file.file_name();
let (language, language_config) = loader
.language_configuration_for_file_name(&test_file_path)?
.ok_or_else(|| anyhow!("No language found for path {:?}", test_file_path))?;
.ok_or_else(|| {
anyhow!(
"{}",
util::lang_not_found_for_path(test_file_path.as_path(), loader_config)
)
})?;
let tags_config = language_config
.tags_config(language)?
.ok_or_else(|| anyhow!("No tags config found for {:?}", test_file_path))?;

View file

@ -1,13 +1,17 @@
use anyhow::{anyhow, Context, Result};
use std::{
path::PathBuf,
path::{Path, PathBuf},
process::{Child, ChildStdin, Command, Stdio},
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
};
use anyhow::{anyhow, Context, Result};
use indoc::indoc;
use tree_sitter::{Parser, Tree};
use tree_sitter_config::Config;
use tree_sitter_loader::Config as LoaderConfig;
const HTML_HEADER: &[u8] = b"
<!DOCTYPE html>
@ -18,6 +22,33 @@ svg { width: 100%; }
";
pub fn lang_not_found_for_path(path: &Path, loader_config: &LoaderConfig) -> String {
let path = path.display();
format!(
indoc! {"
No language found for path `{}`
If a language should be associated with this file extension, please ensure the path to `{}` is inside one of the following directories as specified by your 'config.json':\n\n{}\n
If the directory that contains the relevant grammar for `{}` is not listed above, please add the directory to the list of directories in your config file, {}
"},
path,
path,
loader_config
.parser_directories
.iter()
.enumerate()
.map(|(i, d)| format!(" {}. {}", i + 1, d.display()))
.collect::<Vec<_>>()
.join(" \n"),
path,
if let Ok(Some(config_path)) = Config::find_config_file() {
format!("located at {}", config_path.display())
} else {
String::from("which you need to create by running `tree-sitter init-config`")
}
)
}
#[must_use]
pub fn cancel_on_signal() -> Arc<AtomicUsize> {
let result = Arc::new(AtomicUsize::new(0));