Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Update VSCode Config #400

Merged
merged 9 commits into from
Jan 21, 2025
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions harper-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ harper-literate-haskell = { path = "../harper-literate-haskell", version = "0.16
harper-core = { path = "../harper-core", version = "0.16.0" }
harper-comments = { path = "../harper-comments", version = "0.16.0" }
harper-typst = { path = "../harper-typst", version = "0.16.0" }
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.137"

[features]
Expand Down
43 changes: 37 additions & 6 deletions harper-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![doc = include_str!("../README.md")]

use std::collections::{BTreeMap, HashMap};
use std::path::{Path, PathBuf};

use anyhow::format_err;
Expand All @@ -10,6 +11,7 @@ use harper_core::linting::{LintGroup, LintGroupConfig, Linter};
use harper_core::parsers::{Markdown, MarkdownOptions};
use harper_core::{remove_overlaps, Dictionary, Document, FstDictionary, TokenKind};
use harper_literate_haskell::LiterateHaskellParser;
use serde::Serialize;

/// A debugging tool for the Harper grammar checker.
#[derive(Debug, Parser)]
Expand Down Expand Up @@ -41,18 +43,21 @@ enum Args {
Metadata { word: String },
/// Emit a decompressed, line-separated list of the words in Harper's dictionary.
Words,
/// Print the default config with descriptions.
Config,
}

fn main() -> anyhow::Result<()> {
let args = Args::parse();
let markdown_options = MarkdownOptions::default();
let linting_options = LintGroupConfig::default();
let dictionary = FstDictionary::curated();

match args {
Args::Lint { file, count } => {
let (doc, source) = load_file(&file, markdown_options)?;

let mut linter = LintGroup::new(linting_options, FstDictionary::curated());
let mut linter = LintGroup::new(linting_options, dictionary);
let mut lints = linter.lint(&doc);

if count {
Expand Down Expand Up @@ -145,11 +150,9 @@ fn main() -> anyhow::Result<()> {
Ok(())
}
Args::Words => {
let dict = FstDictionary::curated();

let mut word_str = String::new();

for word in dict.words_iter() {
for word in dictionary.words_iter() {
word_str.clear();
word_str.extend(word);

Expand All @@ -159,12 +162,40 @@ fn main() -> anyhow::Result<()> {
Ok(())
}
Args::Metadata { word } => {
let dict = FstDictionary::curated();
let metadata = dict.get_word_metadata_str(&word);
let metadata = dictionary.get_word_metadata_str(&word);
let json = serde_json::to_string_pretty(&metadata).unwrap();

println!("{json}");

Ok(())
}
Args::Config => {
#[derive(Serialize)]
struct Config {
default_value: bool,
description: String,
}

let mut linter = LintGroup::new(linting_options, dictionary);
linter.config.fill_default_values();

let default_config: HashMap<String, bool> =
serde_json::from_str(&serde_json::to_string(&linter.config).unwrap()).unwrap();

// Use `BTreeMap` so output is sorted by keys.
let mut configs = BTreeMap::new();
for (key, desc) in linter.all_descriptions().to_vec_pairs() {
configs.insert(
key.to_owned(),
Config {
default_value: default_config[key],
description: desc.to_owned(),
},
);
}

println!("{}", serde_json::to_string_pretty(&configs).unwrap());

Ok(())
}
}
Expand Down
18 changes: 12 additions & 6 deletions harper-ls/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,25 @@ impl Config {
};

if let Some(v) = value.get("userDictPath") {
if let Value::String(path) = v {
base.user_dict_path = path.try_resolve()?.to_path_buf();
} else {
if !v.is_string() {
bail!("userDict path must be a string.");
}

let path = v.as_str().unwrap();
if !path.is_empty() {
base.user_dict_path = path.try_resolve()?.to_path_buf();
}
}

if let Some(v) = value.get("fileDictPath") {
if let Value::String(path) = v {
base.file_dict_path = path.try_resolve()?.to_path_buf();
} else {
if !v.is_string() {
bail!("fileDict path must be a string.");
}

let path = v.as_str().unwrap();
if !path.is_empty() {
base.file_dict_path = path.try_resolve()?.to_path_buf();
}
}

if let Some(v) = value.get("linters") {
Expand Down
32 changes: 32 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,38 @@ package-vscode target="":
yarn package
fi

update-vscode-linters:
#! /bin/bash
set -eo pipefail

linters=$(
cargo run --bin harper-cli -- config |
jq 'with_entries(.key |= "harper-ls.linters." + . |
.value |= {
"scope": "resource",
"type": "boolean",
"default": .default_value,
"description": .description
}
)'
)

cd "{{justfile_directory()}}/packages/vscode-plugin"

manifest_without_linters=$(
jq 'walk(
if type == "object" then
with_entries(select(.key | startswith("harper-ls.linters") | not))
end
)' package.json
)

jq --argjson linters "$linters" \
'.contributes.configuration.properties += $linters' <<< \
"$manifest_without_linters" > \
package.json
yarn prettier --write package.json

# Run Rust formatting and linting.
check-rust:
#! /bin/bash
Expand Down
Loading
Loading