Add support for QML

QML is a UI language, and its syntax is basically JSON-like structure
+ JavaScript. The tree-sitter parser is named after the upstream grammar
file qmljs.g, but the canonical language name is QML. So I choose Qml as
the Language enum.

https://doc.qt.io/qt-6/qmlapplications.html
pull/361/head
Yuya Nishihara 2022-09-08 17:34:13 +07:00
parent 79d594fc56
commit 84f0b25fb6
11 changed files with 91 additions and 2 deletions

@ -5,6 +5,10 @@
Improved diff cost model to prefer finding unchanged variable names Improved diff cost model to prefer finding unchanged variable names
over unchanged punctuation. over unchanged punctuation.
### Parsing
Added support for QML.
## 0.35 (released 2nd September 2022) ## 0.35 (released 2nd September 2022)
### Diffing ### Diffing

@ -287,6 +287,11 @@ fn main() {
src_dir: "vendor/tree-sitter-python-src", src_dir: "vendor/tree-sitter-python-src",
extra_files: vec!["scanner.cc"], extra_files: vec!["scanner.cc"],
}, },
TreeSitterParser {
name: "tree-sitter-qmljs",
src_dir: "vendor/tree-sitter-qmljs-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser { TreeSitterParser {
name: "tree-sitter-ruby", name: "tree-sitter-ruby",
src_dir: "vendor/tree-sitter-ruby-src", src_dir: "vendor/tree-sitter-ruby-src",

@ -36,6 +36,7 @@ with `difft --list-languages`.
| Perl | [ganezdragon/tree-sitter-perl](https://github.com/ganezdragon/tree-sitter-perl) | | Perl | [ganezdragon/tree-sitter-perl](https://github.com/ganezdragon/tree-sitter-perl) |
| PHP | [tree-sitter/tree-sitter-php](https://github.com/tree-sitter/tree-sitter-php) | | PHP | [tree-sitter/tree-sitter-php](https://github.com/tree-sitter/tree-sitter-php) |
| Python | [tree-sitter/tree-sitter-python](https://github.com/tree-sitter/tree-sitter-python) | | Python | [tree-sitter/tree-sitter-python](https://github.com/tree-sitter/tree-sitter-python) |
| QML | [tree-sitter/tree-sitter-qmljs](https://github.com/yuja/tree-sitter-qmljs) |
| Ruby | [tree-sitter/tree-sitter-ruby](https://github.com/tree-sitter/tree-sitter-ruby) | | Ruby | [tree-sitter/tree-sitter-ruby](https://github.com/tree-sitter/tree-sitter-ruby) |
| Rust | [tree-sitter/tree-sitter-rust](https://github.com/tree-sitter/tree-sitter-rust) ([forked](https://github.com/Wilfred/tree-sitter-rust/tree/non_special_token)) | | Rust | [tree-sitter/tree-sitter-rust](https://github.com/tree-sitter/tree-sitter-rust) ([forked](https://github.com/Wilfred/tree-sitter-rust/tree/non_special_token)) |
| Scala | [tree-sitter/tree-sitter-scala](https://github.com/tree-sitter/tree-sitter-scala) | | Scala | [tree-sitter/tree-sitter-scala](https://github.com/tree-sitter/tree-sitter-scala) |

@ -139,6 +139,9 @@ sample_files/prefer_outer_before.el sample_files/prefer_outer_after.el
sample_files/preprocesor_before.h sample_files/preprocesor_after.h sample_files/preprocesor_before.h sample_files/preprocesor_after.h
3e4331cb935cbe735a79ebc43786cd3a - 3e4331cb935cbe735a79ebc43786cd3a -
sample_files/qml_before.qml sample_files/qml_after.qml
53ddc9a9a88f7d0381558e4fabf46212 -
sample_files/ruby_before.rb sample_files/ruby_after.rb sample_files/ruby_before.rb sample_files/ruby_after.rb
d88046b43f826a34bbd4a7b9d6bb704d - d88046b43f826a34bbd4a7b9d6bb704d -

@ -0,0 +1,29 @@
// Taken from https://doc.qt.io/qt-6/qmlapplications.html
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
width: 400
height: 400
visible: true
Button {
id: button
hoverEnabled: true
text: "A Special Button"
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
color: {
if (button.down || button.hovered) {
"#d6d6d6"
} else {
"#f6f6f6"
}
}
border.color: "#26282a"
border.width: button.down ? 2 : 1
radius: 4
}
}
}

@ -0,0 +1,22 @@
// Taken from https://doc.qt.io/qt-6/qmlapplications.html
import QtQuick
import QtQuick.Controls
ApplicationWindow {
width: 400
height: 400
visible: true
Button {
id: button
text: "A Special Button"
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
color: button.down ? "#d6d6d6" : "#f6f6f6"
border.color: "#26282a"
border.width: 1
radius: 4
}
}
}

@ -69,8 +69,8 @@ fn prefer_outer_delimiter(language: guess_language::Language) -> bool {
// the inner delimiter is more relevant. // the inner delimiter is more relevant.
Bash | C | CMake | CPlusPlus | CSharp | Css | Dart | Elixir | Elm | Elvish | Gleam | Go Bash | C | CMake | CPlusPlus | CSharp | Css | Dart | Elixir | Elm | Elvish | Gleam | Go
| Hack | Haskell | Html | Java | JavaScript | Jsx | Julia | Kotlin | Lua | Make | Nix | Hack | Haskell | Html | Java | JavaScript | Jsx | Julia | Kotlin | Lua | Make | Nix
| OCaml | OCamlInterface | Perl | Php | Python | Ruby | Rust | Scala | Swift | Tsx | OCaml | OCamlInterface | Perl | Php | Python | Qml | Ruby | Rust | Scala | Swift
| TypeScript | Yaml | Zig => false, | Tsx | TypeScript | Yaml | Zig => false,
} }
} }

@ -52,6 +52,7 @@ pub enum Language {
Php, Php,
Perl, Perl,
Python, Python,
Qml,
Ruby, Ruby,
Rust, Rust,
Scala, Scala,
@ -101,6 +102,7 @@ pub fn language_name(language: Language) -> &'static str {
Php => "PHP", Php => "PHP",
Perl => "Perl", Perl => "Perl",
Python => "Python", Python => "Python",
Qml => "QML",
Ruby => "Ruby", Ruby => "Ruby",
Rust => "Rust", Rust => "Rust",
Scala => "Scala", Scala => "Scala",
@ -181,6 +183,7 @@ pub const LANG_EXTENSIONS: &'static [(Language, &[&str])] = &[
(Php, &["php"]), (Php, &["php"]),
(Perl, &["pm", "pl"]), (Perl, &["pm", "pl"]),
(Python, &["py", "py3", "pyi", "bzl"]), (Python, &["py", "py3", "pyi", "bzl"]),
(Qml, &["qml"]),
(Ruby, &["rb", "builder", "spec", "rake"]), (Ruby, &["rb", "builder", "spec", "rake"]),
(Rust, &["rs"]), (Rust, &["rs"]),
(Scala, &["scala", "sbt", "sc"]), (Scala, &["scala", "sbt", "sc"]),

@ -73,6 +73,7 @@ extern "C" {
fn tree_sitter_php() -> ts::Language; fn tree_sitter_php() -> ts::Language;
fn tree_sitter_perl() -> ts::Language; fn tree_sitter_perl() -> ts::Language;
fn tree_sitter_python() -> ts::Language; fn tree_sitter_python() -> ts::Language;
fn tree_sitter_qmljs() -> ts::Language;
fn tree_sitter_ruby() -> ts::Language; fn tree_sitter_ruby() -> ts::Language;
fn tree_sitter_rust() -> ts::Language; fn tree_sitter_rust() -> ts::Language;
fn tree_sitter_scala() -> ts::Language; fn tree_sitter_scala() -> ts::Language;
@ -608,6 +609,25 @@ pub fn from_language(language: guess::Language) -> TreeSitterConfig {
.unwrap(), .unwrap(),
} }
} }
Qml => {
let language = unsafe { tree_sitter_qmljs() };
TreeSitterConfig {
language,
atom_nodes: vec!["string", "template_string", "regex"]
.into_iter()
.collect(),
delimiter_tokens: vec![("{", "}"), ("(", ")"), ("[", "]"), ("<", ">")],
highlight_query: ts::Query::new(
language,
concat!(
include_str!("../../vendor/highlights/javascript.scm"),
include_str!("../../vendor/highlights/typescript.scm"),
include_str!("../../vendor/highlights/qmljs.scm"),
),
)
.unwrap(),
}
}
Ruby => { Ruby => {
let language = unsafe { tree_sitter_ruby() }; let language = unsafe { tree_sitter_ruby() };
TreeSitterConfig { TreeSitterConfig {

@ -0,0 +1 @@
../tree-sitter-qmljs/queries/highlights.scm

@ -0,0 +1 @@
tree-sitter-qmljs/src