Skip to content

Commit

Permalink
feat: xtask themelint (helix-editor#3234)
Browse files Browse the repository at this point in the history
* feat: cargo xtask themelint <theme>

* fix: add docs and print json error status

* fix: refactor paths -> path

* fix: remove unused function

* fix: only report one err per scope (ui.statusline is reported if none of ui.statusline.* is recognized)

* fix: save work for later

* fix: finally decided on a design

* fix: ready for discussion

* fix: better rules

* fix: lint precision

* fix: String -> &'static str

* fix: allowlist not denylist for file type

* fix: add missing and indication of what's needed

* fix: copy pasteable errors

* fix: use Loader:read_names

* Update xtask/src/helpers.rs

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* fix: remove into and clone for str

* Update book/src/themes.md

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* fix: better lint output

* fix: cleaner logic for lint reporting

* style: use explicit imports

* Pascal support (helix-editor#3542)

* fix: add difference check for statusline normal,insert,select

* fix: fg for whitespace and early exit if and one is ok

* chore: cleaning up, no idea how these got here or how this will look

* chore: revert from older commit?

* refactor: use static fn to equalize api between difference and existance

* refactor: querycheck and clippy

* refactor: clippy fixes

* fix: query-check behaves as before

* fix: error with x of y message, not total count

* fix: consistent reporting and less mutable state

* fix: selection difference ref helix-editor#3942 ref helix-editor#1833

Co-authored-by: Ivan Tham <pickfire@riseup.net>
Co-authored-by: ath3 <45574139+ath3@users.noreply.github.com>
  • Loading branch information
3 people authored and Shekhinah Memmel committed Dec 11, 2022
1 parent 4d0380f commit 9a1b0e0
Show file tree
Hide file tree
Showing 9 changed files with 451 additions and 238 deletions.
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.

6 changes: 6 additions & 0 deletions book/src/themes.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,10 @@ These scopes are used for theming the editor interface.
| `diagnostic.warning` | Diagnostics warning (editing area) |
| `diagnostic.error` | Diagnostics error (editing area) |

You can check compliance to spec with

```shell
cargo xtask themelint onedark # replace onedark with <name>
```

[editor-section]: ./configuration.md#editor-section
1 change: 1 addition & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ edition = "2021"
[dependencies]
helix-term = { version = "0.6", path = "../helix-term" }
helix-core = { version = "0.6", path = "../helix-core" }
helix-view = { version = "0.6", path = "../helix-view" }
helix-loader = { version = "0.6", path = "../helix-loader" }
toml = "0.5"
117 changes: 117 additions & 0 deletions xtask/src/docgen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use crate::helpers;
use crate::path;
use crate::DynError;

use helix_term::commands::TYPABLE_COMMAND_LIST;
use helix_term::health::TsFeature;
use std::fs;

pub const TYPABLE_COMMANDS_MD_OUTPUT: &str = "typable-cmd.md";
pub const LANG_SUPPORT_MD_OUTPUT: &str = "lang-support.md";

fn md_table_heading(cols: &[String]) -> String {
let mut header = String::new();
header += &md_table_row(cols);
header += &md_table_row(&vec!["---".to_string(); cols.len()]);
header
}

fn md_table_row(cols: &[String]) -> String {
format!("| {} |\n", cols.join(" | "))
}

fn md_mono(s: &str) -> String {
format!("`{}`", s)
}

pub fn typable_commands() -> Result<String, DynError> {
let mut md = String::new();
md.push_str(&md_table_heading(&[
"Name".to_owned(),
"Description".to_owned(),
]));

let cmdify = |s: &str| format!("`:{}`", s);

for cmd in TYPABLE_COMMAND_LIST {
let names = std::iter::once(&cmd.name)
.chain(cmd.aliases.iter())
.map(|a| cmdify(a))
.collect::<Vec<_>>()
.join(", ");

let doc = cmd.doc.replace('\n', "<br>");

md.push_str(&md_table_row(&[names.to_owned(), doc.to_owned()]));
}

Ok(md)
}

pub fn lang_features() -> Result<String, DynError> {
let mut md = String::new();
let ts_features = TsFeature::all();

let mut cols = vec!["Language".to_owned()];
cols.append(
&mut ts_features
.iter()
.map(|t| t.long_title().to_string())
.collect::<Vec<_>>(),
);
cols.push("Default LSP".to_owned());

md.push_str(&md_table_heading(&cols));
let config = helpers::lang_config();

let mut langs = config
.language
.iter()
.map(|l| l.language_id.clone())
.collect::<Vec<_>>();
langs.sort_unstable();

let mut ts_features_to_langs = Vec::new();
for &feat in ts_features {
ts_features_to_langs.push((feat, helpers::ts_lang_support(feat)));
}

let mut row = Vec::new();
for lang in langs {
let lc = config
.language
.iter()
.find(|l| l.language_id == lang)
.unwrap(); // lang comes from config
row.push(lc.language_id.clone());

for (_feat, support_list) in &ts_features_to_langs {
row.push(
if support_list.contains(&lang) {
"✓"
} else {
""
}
.to_owned(),
);
}
row.push(
lc.language_server
.as_ref()
.map(|s| s.command.clone())
.map(|c| md_mono(&c))
.unwrap_or_default(),
);

md.push_str(&md_table_row(&row));
row.clear();
}

Ok(md)
}

pub fn write(filename: &str, data: &str) {
let error = format!("Could not write to {}", filename);
let path = path::book_gen().join(filename);
fs::write(path, data).expect(&error);
}
44 changes: 44 additions & 0 deletions xtask/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::path::{Path, PathBuf};

use crate::path;
use helix_core::syntax::Configuration as LangConfig;
use helix_term::health::TsFeature;

/// Get the list of languages that support a particular tree-sitter
/// based feature.
pub fn ts_lang_support(feat: TsFeature) -> Vec<String> {
let queries_dir = path::ts_queries();

find_files(&queries_dir, feat.runtime_filename())
.iter()
.map(|f| {
// .../helix/runtime/queries/python/highlights.scm
let tail = f.strip_prefix(&queries_dir).unwrap(); // python/highlights.scm
let lang = tail.components().next().unwrap(); // python
lang.as_os_str().to_string_lossy().to_string()
})
.collect()
}

// naive implementation, but suffices for our needs
pub fn find_files(dir: &Path, filename: &str) -> Vec<PathBuf> {
std::fs::read_dir(dir)
.unwrap()
.filter_map(|entry| {
let path = entry.ok()?.path();
if path.is_dir() {
Some(find_files(&path, filename))
} else if path.file_name()?.to_string_lossy() == filename {
Some(vec![path])
} else {
None
}
})
.flatten()
.collect()
}

pub fn lang_config() -> LangConfig {
let bytes = std::fs::read(path::lang_config()).unwrap();
toml::from_slice(&bytes).unwrap()
}
Loading

0 comments on commit 9a1b0e0

Please sign in to comment.