tabry 0.1.0 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/tabry-bash +3 -0
- data/bin/tabry-help +1 -1
- data/lib/tabry/config_loader.rb +9 -2
- data/lib/tabry/shells/bash.rb +35 -0
- data/lib/tabry/usage_generator.rb +5 -5
- data/sh/bash/README.md +36 -0
- data/sh/bash/tabry_bash.sh +22 -0
- data/sh/{tabry_bash.sh → bash/tabry_bash_core.sh} +6 -16
- data/sh/{tabry_bash_help.sh → bash/tabry_bash_help.sh} +1 -1
- data/spec/tabry/config_loader_spec.rb +9 -3
- data/tabry.gemspec +22 -2
- data/treesitter/Cargo.toml +26 -0
- data/treesitter/README.md +4 -0
- data/treesitter/binding.gyp +19 -0
- data/treesitter/bindings/node/binding.cc +28 -0
- data/treesitter/bindings/node/index.js +19 -0
- data/treesitter/bindings/rust/build.rs +40 -0
- data/treesitter/bindings/rust/lib.rs +52 -0
- data/treesitter/corpus/arg.txt +96 -0
- data/treesitter/corpus/at.txt +79 -0
- data/treesitter/corpus/comment.txt +13 -0
- data/treesitter/corpus/desc.txt +25 -0
- data/treesitter/corpus/examples_from_language_reference.txt +410 -0
- data/treesitter/corpus/flag.txt +48 -0
- data/treesitter/corpus/flag_desc_inline.txt +37 -0
- data/treesitter/corpus/opts.txt +21 -0
- data/treesitter/corpus/rapture.txt +61 -0
- data/treesitter/grammar.js +171 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/argument_titles.yml +8 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/arguments_and_possible_options__arg_.yml +23 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.yml +37 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/getting_started.yml +13 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/includes.yml +57 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/multi_line_descriptions.yml +7 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.yml +16 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/options.yml +24 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/subcommands__sub__1.yml +23 -0
- data/treesitter/jest_fixtures/examples_from_language_reference/subcommands__sub__2.yml +15 -0
- data/treesitter/package.json +21 -0
- data/treesitter/parser_compile.sh +1 -0
- data/treesitter/src/grammar.json +615 -0
- data/treesitter/src/node-types.json +563 -0
- data/treesitter/src/parser.c +4706 -0
- data/treesitter/src/tree_sitter/parser.h +223 -0
- data/treesitter/tabry-compile.js +394 -0
- data/treesitter/tabry-compile.test.js +51 -0
- metadata +41 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b1cb912ae500805787b62500d1c4995215bc9e3c8a4ccf32b7224bc4fa227c6
|
4
|
+
data.tar.gz: 68244bb100b3a262527b723b02fd6e73e9158f756bf44df960f8e5bd3d7e4679
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d6e9694ca66c39e5627eed4e8159ad95510ae1f146221529d068ca92c32d3e9d3d3208d7da59909467f2833fcf0a064735e49c75816e3b11741fe659bf8d92f
|
7
|
+
data.tar.gz: 0572051e1da3fa757609b2c5e956f745f434487e089268db318c1410f72e32a5bf906d4a4a4277cc23a40b77ed64ac8d41b1ebcb9fa0a78c0d0cff3c382c81f9
|
data/bin/tabry-bash
CHANGED
data/bin/tabry-help
CHANGED
@@ -5,7 +5,7 @@ require_relative "../lib/tabry/runner"
|
|
5
5
|
|
6
6
|
# Show usage information stored in a tabry configuration.
|
7
7
|
#
|
8
|
-
# For ease of use, source sh/tabry_bash_help.sh so you can just do
|
8
|
+
# For ease of use, source sh/bash/tabry_bash_help.sh so you can just do
|
9
9
|
# "help mycmd"
|
10
10
|
|
11
11
|
raise "Usage: tabry-help config_name [arg1 [arg2]]..." unless ARGV.length >= 1
|
data/lib/tabry/config_loader.rb
CHANGED
@@ -21,9 +21,16 @@ module Tabry
|
|
21
21
|
def load
|
22
22
|
return load_from_file(name) if name =~ /\.json$/i || name =~ /\.ya?ml$/i
|
23
23
|
|
24
|
-
load_paths.each do |
|
24
|
+
load_paths.each do |path|
|
25
25
|
EXTENSIONS.each do |extension|
|
26
|
-
|
26
|
+
basename = "/#{name}.#{extension}"
|
27
|
+
|
28
|
+
# First check if the path _is_ the file "mycmd.json", "mycmd.yml" we are looking for
|
29
|
+
return load_from_file(path) if path.end_with?(basename) && File.exist?(path)
|
30
|
+
|
31
|
+
# Then look for a file "mycmd.json", "mycmd.yml" etc. in the
|
32
|
+
# directory (assuming it is a directory)
|
33
|
+
filename = "#{path}/#{basename}"
|
27
34
|
return load_from_file(filename) if File.exist?(filename)
|
28
35
|
end
|
29
36
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Used to generate a tab-completion function for a Tabry CLI using absolute
|
4
|
+
# paths to the tabry-bash script in this repo and to the Tabry JSON/YML file.
|
5
|
+
# Using uniquely-named tab-completion functions and absolute paths means you can
|
6
|
+
# have different Tabry-based CLIs using different versions of Tabry without any
|
7
|
+
# conflicts.
|
8
|
+
# See sh/bash/README.md and "Adding Tab Completion to your CLI" in main README
|
9
|
+
|
10
|
+
module Tabry
|
11
|
+
module Shells
|
12
|
+
module Bash
|
13
|
+
# NOTE! This code uses sh/bash/tabry_bash_core.sh and is described in
|
14
|
+
# sh/bash/README.md; see that README for more info
|
15
|
+
def self.generate(cmd_name, tabry_file_path)
|
16
|
+
capitalized_cmd_name = cmd_name.upcase.gsub(/[^a-zA-Z0-9_]/, "_")
|
17
|
+
tabry_file = Shellwords.escape(File.expand_path(tabry_file_path))
|
18
|
+
path_to_tabry = Shellwords.escape(File.expand_path("#{__dir__}/../../../"))
|
19
|
+
|
20
|
+
core = File.read("#{__dir__}/../../../sh/bash/tabry_bash_core.sh")
|
21
|
+
core.gsub! "_tabry_completions_internal()", "_tabry_#{capitalized_cmd_name}_completions_internal()"
|
22
|
+
|
23
|
+
<<~END_BASH_CODE_TEMPLATE + core
|
24
|
+
# The following Autocomplete is for a Tabry-powered command. It was
|
25
|
+
# generated by the command itself. See the documentation located in
|
26
|
+
# #{path_to_tabry}/sh/bash/README.md
|
27
|
+
_tabry_#{capitalized_cmd_name}_completions() {
|
28
|
+
TABRY_IMPORTS_PATH=#{tabry_file} _tabry_#{capitalized_cmd_name}_completions_internal #{path_to_tabry}/bin/tabry-bash
|
29
|
+
}
|
30
|
+
complete -F _tabry_#{capitalized_cmd_name}_completions #{Shellwords.escape cmd_name}
|
31
|
+
END_BASH_CODE_TEMPLATE
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -97,11 +97,11 @@ module Tabry
|
|
97
97
|
lines << ""
|
98
98
|
lines << "FLAGS".green.bold
|
99
99
|
if sub != sub_stack.last
|
100
|
-
lines
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
lines[-1] += if full_sub_name == ""
|
101
|
+
" (global)".green.bold
|
102
|
+
else
|
103
|
+
" (#{full_sub_name})".green.bold
|
104
|
+
end
|
105
105
|
end
|
106
106
|
|
107
107
|
sub.flags.map(&:name).sort.each do |name|
|
data/sh/bash/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Tabry Bash glue
|
2
|
+
|
3
|
+
This directory contains code needed to make Tabry autocomplete work with bash.
|
4
|
+
The code here is basically glue code needed to connect bash's autocomplete
|
5
|
+
framework with Tabry (which does all the work of generating tab completion
|
6
|
+
options). Additionally, `tabry_bash_help.sh` is provided to override bash's
|
7
|
+
help command to provide help to commands that have tabry completion.
|
8
|
+
|
9
|
+
# Quickstart for adding Tab completion
|
10
|
+
* To add Tabry to non-tabry based CLIs, follow the instructions in `tabry_bash.sh`
|
11
|
+
* For Tabry-based CLIs, run "mycmd completion bash" and add the code to your `~/.bash_profile`
|
12
|
+
|
13
|
+
# Tabry Bash autocompletion technical overview
|
14
|
+
The main bash function which calls out to tabry to provide tab completion options is in
|
15
|
+
`tabry_bash_core.sh`. This defines a function called
|
16
|
+
`_tabry_completions_internal`. **If editing the file, it is important you
|
17
|
+
do not rename this function or add lines starting with this function name
|
18
|
+
without understanding the substitution as mentioned below.**
|
19
|
+
|
20
|
+
This file and bash function contained within is used in two ways:
|
21
|
+
* For Ruby CLIs written using tabry, this is renamed to to
|
22
|
+
`_tabry_MYCOMMAND_completions_internal`, and a bit of extra bash code is
|
23
|
+
added on, to make tab completion specific for the program. This is generated
|
24
|
+
for each command when the user runs "mycommand completion bash", which calls
|
25
|
+
`Tabry::Shells::Bash.generate`. A new function for each CLI so different CLIs
|
26
|
+
can use different versions of tabry without interfering with each other.
|
27
|
+
The name `_tabry_completions_internal_` is replaced in
|
28
|
+
`lib/tabry/shells/bash.rb` in the `generate` method, so if modifying
|
29
|
+
`tabry_bash_core.sh`, you should if make sure the substitution still works
|
30
|
+
properly.
|
31
|
+
See also "Adding Tab Completion to your CLI" in the main README.
|
32
|
+
* You can also use Tabry to add tab completion to other non-Tabry CLIs. In this
|
33
|
+
case, the `_tabry_completions_internal_` function is used as-is; it is
|
34
|
+
sourced from `tabry_bash.sh`. See `tabry_bash.sh` for details and
|
35
|
+
instructions on how to use it.
|
36
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Use this file to use Tabry tab completion with non-Tabry CLIs. To do this,
|
2
|
+
# source this file in your bash_profile and add lines like
|
3
|
+
# `complete -F _tabry_completions somecli` for each CLI. You will also
|
4
|
+
# need the tabry JSON/YML files in ~/.tabry/ or in a path in your
|
5
|
+
# TABRY_IMPORTS_PATH. For instance, to add tab completion to vaulted and
|
6
|
+
# rapture, you can add this to your ~/.bash_profile:
|
7
|
+
#
|
8
|
+
# source /path/to/tabry/sh/bash/tabry_bash.sh
|
9
|
+
# complete -F _tabry_completions rapture
|
10
|
+
# complete -F _tabry_completions vaulted
|
11
|
+
#
|
12
|
+
# Then be sure to either copy tabry/examples/tabry/vaulted.json and rapture.json to ~/.tabry/,
|
13
|
+
# or set TABRY_IMPORTS_PATH in ~/.bash_profile like so:
|
14
|
+
#
|
15
|
+
# TABRY_IMPORTS_PATH=$TABRY_IMPORTS_PATH:/path/to/tabry/examples/tabry/
|
16
|
+
#
|
17
|
+
|
18
|
+
source "$( dirname "${BASH_SOURCE[0]:-${(%):-%x}}" )"/tabry_bash_core.sh
|
19
|
+
_tabry_completions() {
|
20
|
+
_tabry_completions_internal "$( dirname "${BASH_SOURCE[0]:-${(%):-%x}}" )"/../../bin/tabry-bash
|
21
|
+
}
|
22
|
+
|
@@ -1,19 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
# _tabry_completions function is same for any command you use with tabry, you just need
|
5
|
-
# to do `complete -F _tabry_completions mycmd` for your command. This calls the tabry-bash
|
6
|
-
# ruby script. For more info see LANGUAGE_REFERENCE.md
|
7
|
-
|
8
|
-
_tabry_bash="$( dirname "${BASH_SOURCE[0]:-${(%):-%x}}" )"/../bin/tabry-bash
|
9
|
-
|
10
|
-
_tabry_completions()
|
1
|
+
# For more information, or before editing the tabry_bash_core.sh source file,
|
2
|
+
# See sh/bash/README.md and sh/bash/tabry_bash.sh in the tabry gem
|
3
|
+
_tabry_completions_internal()
|
11
4
|
{
|
5
|
+
local tabry_bash="$1"
|
6
|
+
|
12
7
|
[[ -n "$TABRY_DEBUG" ]] && echo && echo -n tabry start bash: && date +%s.%N >&2
|
13
8
|
local saveifs="$IFS"
|
14
9
|
IFS=$'\n'
|
15
10
|
|
16
|
-
local result=`"$
|
11
|
+
local result=`ruby "$tabry_bash" "$COMP_LINE" "$COMP_POINT"`
|
17
12
|
local specials
|
18
13
|
|
19
14
|
if [[ $result == *$'\n'$'\n'* ]]; then
|
@@ -54,8 +49,3 @@ _tabry_completions()
|
|
54
49
|
[[ -n "$TABRY_DEBUG" ]] && echo -n tabry end bash: && date +%s.%N >&2
|
55
50
|
}
|
56
51
|
|
57
|
-
# To use: put a .json/.yml tabry config file in ~/.tabry (e.g. ~/.aws.json)
|
58
|
-
# Then, run this script in your shell startup scripts, plus (e.g.)
|
59
|
-
#
|
60
|
-
# complete -F _tabry_completions aws
|
61
|
-
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# 'help mycommand' -> show tabry help for a tabry-CLI or command you have a
|
2
2
|
# tabry tab completion config for
|
3
3
|
|
4
|
-
_tabry_help="$( dirname "${BASH_SOURCE[0]}" )"
|
4
|
+
_tabry_help="$( dirname "${BASH_SOURCE[0]}" )"/../../bin/tabry-help
|
5
5
|
help() {
|
6
6
|
tabry-help "$@" 2>/dev/null || command help "$@"
|
7
7
|
}
|
@@ -24,22 +24,28 @@ describe Tabry::ConfigLoader do
|
|
24
24
|
describe "use of $TABRY_IMPORTS_PATH" do
|
25
25
|
before { ENV["TABRY_IMPORTS_PATH"] = "#{__dir__}/../fixtures/" }
|
26
26
|
|
27
|
-
it "looks for yaml files in TABRY_IMPORTS_PATH" do
|
27
|
+
it "looks for yaml files in directories in TABRY_IMPORTS_PATH" do
|
28
28
|
config = described_class.load(name: "vehicles")
|
29
29
|
expect(config.main.subs.map(&:name)).to eq(
|
30
30
|
%w[build list-vehicles move sub-with-sub-or-arg sub-with-mandatory-flag]
|
31
31
|
)
|
32
32
|
end
|
33
33
|
|
34
|
-
it "looks for json files in TABRY_IMPORTS_PATH" do
|
34
|
+
it "looks for json files in directories in TABRY_IMPORTS_PATH" do
|
35
35
|
config = described_class.load(name: "basiccli")
|
36
36
|
expect(config.main.subs.map(&:name)).to eq(%w[foo])
|
37
37
|
end
|
38
38
|
|
39
|
-
it "looks for yml files in TABRY_IMPORTS_PATH" do
|
39
|
+
it "looks for yml files in directories in TABRY_IMPORTS_PATH" do
|
40
40
|
config = described_class.load(name: "basiccli2")
|
41
41
|
expect(config.main.subs.map(&:name)).to eq(%w[waz])
|
42
42
|
end
|
43
|
+
|
44
|
+
it "looks for json files in TABRY_IMPORTS_PATH" do
|
45
|
+
ENV["TABRY_IMPORTS_PATH"] = "#{__dir__}/../fixtures/basiccli.json"
|
46
|
+
config = described_class.load(name: "basiccli")
|
47
|
+
expect(config.main.subs.map(&:name)).to eq(%w[foo])
|
48
|
+
end
|
43
49
|
end
|
44
50
|
|
45
51
|
describe "use of $HOME" do
|
data/tabry.gemspec
CHANGED
@@ -6,18 +6,38 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "tabry"
|
9
|
-
s.version = "0.1.
|
9
|
+
s.version = "0.1.3"
|
10
10
|
s.summary = "Tab completion and CLIs extraordinaire"
|
11
11
|
s.authors = ["Evan Battaglia"]
|
12
12
|
s.email = "battaglia.evan@gmail.com"
|
13
13
|
s.homepage = "https://github.com/evanbattaglia/tabry"
|
14
14
|
s.license = "MIT"
|
15
15
|
|
16
|
-
|
16
|
+
treesitter_files = %w[
|
17
|
+
binding.gyp
|
18
|
+
bindings/**/*
|
19
|
+
Cargo.toml
|
20
|
+
corpus/**/*
|
21
|
+
grammar.js
|
22
|
+
jest_fixtures/**/*
|
23
|
+
package.json
|
24
|
+
parser_compile.sh
|
25
|
+
README.md
|
26
|
+
src/**/*
|
27
|
+
tabry-compile.js
|
28
|
+
tabry-compile.test.js
|
29
|
+
]
|
30
|
+
|
31
|
+
s.files = Dir.glob("{lib,bin,sh,spec}/**/*") + %w[tabry.gemspec] +
|
32
|
+
treesitter_files.map { |path| Dir.glob("treesitter/#{path}") }
|
33
|
+
|
17
34
|
# TODO: more cargo cult possibly:
|
18
35
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
36
|
s.require_paths = ["lib"]
|
20
37
|
|
38
|
+
# Currently, to get tab completions, we run tabry without bundler. This makes
|
39
|
+
# it much faster, but requires it have no dependencies.
|
40
|
+
|
21
41
|
s.add_development_dependency "pry-byebug", "~> 3.10"
|
22
42
|
s.add_development_dependency "rspec", "~> 3.10"
|
23
43
|
s.add_development_dependency "rubocop", "~> 1.22"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
[package]
|
2
|
+
name = "tree-sitter-tabry"
|
3
|
+
description = "tabry grammar for the tree-sitter parsing library"
|
4
|
+
version = "0.0.1"
|
5
|
+
keywords = ["incremental", "parsing", "tabry"]
|
6
|
+
categories = ["parsing", "text-editors"]
|
7
|
+
repository = "https://github.com/tree-sitter/tree-sitter-tabry"
|
8
|
+
edition = "2018"
|
9
|
+
license = "MIT"
|
10
|
+
|
11
|
+
build = "bindings/rust/build.rs"
|
12
|
+
include = [
|
13
|
+
"bindings/rust/*",
|
14
|
+
"grammar.js",
|
15
|
+
"queries/*",
|
16
|
+
"src/*",
|
17
|
+
]
|
18
|
+
|
19
|
+
[lib]
|
20
|
+
path = "bindings/rust/lib.rs"
|
21
|
+
|
22
|
+
[dependencies]
|
23
|
+
tree-sitter = "~0.20.0"
|
24
|
+
|
25
|
+
[build-dependencies]
|
26
|
+
cc = "1.0"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"targets": [
|
3
|
+
{
|
4
|
+
"target_name": "tree_sitter_tabry_binding",
|
5
|
+
"include_dirs": [
|
6
|
+
"<!(node -e \"require('nan')\")",
|
7
|
+
"src"
|
8
|
+
],
|
9
|
+
"sources": [
|
10
|
+
"bindings/node/binding.cc",
|
11
|
+
"src/parser.c",
|
12
|
+
# If your language uses an external scanner, add it here.
|
13
|
+
],
|
14
|
+
"cflags_c": [
|
15
|
+
"-std=c99",
|
16
|
+
]
|
17
|
+
}
|
18
|
+
]
|
19
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#include "tree_sitter/parser.h"
|
2
|
+
#include <node.h>
|
3
|
+
#include "nan.h"
|
4
|
+
|
5
|
+
using namespace v8;
|
6
|
+
|
7
|
+
extern "C" TSLanguage * tree_sitter_tabry();
|
8
|
+
|
9
|
+
namespace {
|
10
|
+
|
11
|
+
NAN_METHOD(New) {}
|
12
|
+
|
13
|
+
void Init(Local<Object> exports, Local<Object> module) {
|
14
|
+
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
|
15
|
+
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
|
16
|
+
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
17
|
+
|
18
|
+
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
|
19
|
+
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
|
20
|
+
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_tabry());
|
21
|
+
|
22
|
+
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("tabry").ToLocalChecked());
|
23
|
+
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
|
24
|
+
}
|
25
|
+
|
26
|
+
NODE_MODULE(tree_sitter_tabry_binding, Init)
|
27
|
+
|
28
|
+
} // namespace
|
@@ -0,0 +1,19 @@
|
|
1
|
+
try {
|
2
|
+
module.exports = require("../../build/Release/tree_sitter_tabry_binding");
|
3
|
+
} catch (error1) {
|
4
|
+
if (error1.code !== 'MODULE_NOT_FOUND') {
|
5
|
+
throw error1;
|
6
|
+
}
|
7
|
+
try {
|
8
|
+
module.exports = require("../../build/Debug/tree_sitter_tabry_binding");
|
9
|
+
} catch (error2) {
|
10
|
+
if (error2.code !== 'MODULE_NOT_FOUND') {
|
11
|
+
throw error2;
|
12
|
+
}
|
13
|
+
throw error1
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
try {
|
18
|
+
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
19
|
+
} catch (_) {}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
fn main() {
|
2
|
+
let src_dir = std::path::Path::new("src");
|
3
|
+
|
4
|
+
let mut c_config = cc::Build::new();
|
5
|
+
c_config.include(&src_dir);
|
6
|
+
c_config
|
7
|
+
.flag_if_supported("-Wno-unused-parameter")
|
8
|
+
.flag_if_supported("-Wno-unused-but-set-variable")
|
9
|
+
.flag_if_supported("-Wno-trigraphs");
|
10
|
+
let parser_path = src_dir.join("parser.c");
|
11
|
+
c_config.file(&parser_path);
|
12
|
+
|
13
|
+
// If your language uses an external scanner written in C,
|
14
|
+
// then include this block of code:
|
15
|
+
|
16
|
+
/*
|
17
|
+
let scanner_path = src_dir.join("scanner.c");
|
18
|
+
c_config.file(&scanner_path);
|
19
|
+
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
20
|
+
*/
|
21
|
+
|
22
|
+
c_config.compile("parser");
|
23
|
+
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
24
|
+
|
25
|
+
// If your language uses an external scanner written in C++,
|
26
|
+
// then include this block of code:
|
27
|
+
|
28
|
+
/*
|
29
|
+
let mut cpp_config = cc::Build::new();
|
30
|
+
cpp_config.cpp(true);
|
31
|
+
cpp_config.include(&src_dir);
|
32
|
+
cpp_config
|
33
|
+
.flag_if_supported("-Wno-unused-parameter")
|
34
|
+
.flag_if_supported("-Wno-unused-but-set-variable");
|
35
|
+
let scanner_path = src_dir.join("scanner.cc");
|
36
|
+
cpp_config.file(&scanner_path);
|
37
|
+
cpp_config.compile("scanner");
|
38
|
+
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
39
|
+
*/
|
40
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
//! This crate provides tabry language support for the [tree-sitter][] parsing library.
|
2
|
+
//!
|
3
|
+
//! Typically, you will use the [language][language func] function to add this language to a
|
4
|
+
//! tree-sitter [Parser][], and then use the parser to parse some code:
|
5
|
+
//!
|
6
|
+
//! ```
|
7
|
+
//! let code = "";
|
8
|
+
//! let mut parser = tree_sitter::Parser::new();
|
9
|
+
//! parser.set_language(tree_sitter_tabry::language()).expect("Error loading tabry grammar");
|
10
|
+
//! let tree = parser.parse(code, None).unwrap();
|
11
|
+
//! ```
|
12
|
+
//!
|
13
|
+
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
|
14
|
+
//! [language func]: fn.language.html
|
15
|
+
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
|
16
|
+
//! [tree-sitter]: https://tree-sitter.github.io/
|
17
|
+
|
18
|
+
use tree_sitter::Language;
|
19
|
+
|
20
|
+
extern "C" {
|
21
|
+
fn tree_sitter_tabry() -> Language;
|
22
|
+
}
|
23
|
+
|
24
|
+
/// Get the tree-sitter [Language][] for this grammar.
|
25
|
+
///
|
26
|
+
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
|
27
|
+
pub fn language() -> Language {
|
28
|
+
unsafe { tree_sitter_tabry() }
|
29
|
+
}
|
30
|
+
|
31
|
+
/// The content of the [`node-types.json`][] file for this grammar.
|
32
|
+
///
|
33
|
+
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
|
34
|
+
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
|
35
|
+
|
36
|
+
// Uncomment these to include any queries that this grammar contains
|
37
|
+
|
38
|
+
// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
|
39
|
+
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
|
40
|
+
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
|
41
|
+
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
|
42
|
+
|
43
|
+
#[cfg(test)]
|
44
|
+
mod tests {
|
45
|
+
#[test]
|
46
|
+
fn test_can_load_grammar() {
|
47
|
+
let mut parser = tree_sitter::Parser::new();
|
48
|
+
parser
|
49
|
+
.set_language(super::language())
|
50
|
+
.expect("Error loading tabry language");
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
==============
|
2
|
+
Arg with two opts
|
3
|
+
==============
|
4
|
+
|
5
|
+
arg {
|
6
|
+
opts const "hello \"world\""
|
7
|
+
opts const abc
|
8
|
+
}
|
9
|
+
|
10
|
+
---
|
11
|
+
|
12
|
+
(source_file
|
13
|
+
(arg_statement
|
14
|
+
(arg_type)
|
15
|
+
(block
|
16
|
+
(opts_const_statement (string))
|
17
|
+
(opts_const_statement (string)))))
|
18
|
+
|
19
|
+
==============
|
20
|
+
Named args
|
21
|
+
==============
|
22
|
+
|
23
|
+
arg foo
|
24
|
+
arg foo @whatever
|
25
|
+
arg foo @whatever {
|
26
|
+
opts const abc
|
27
|
+
}
|
28
|
+
|
29
|
+
---
|
30
|
+
|
31
|
+
(source_file
|
32
|
+
(arg_statement
|
33
|
+
(arg_type)
|
34
|
+
(arg_name_list (string)))
|
35
|
+
(arg_statement
|
36
|
+
(arg_type)
|
37
|
+
(arg_name_list (string))
|
38
|
+
(at_identifier))
|
39
|
+
(arg_statement
|
40
|
+
(arg_type)
|
41
|
+
(arg_name_list (string))
|
42
|
+
(at_identifier)
|
43
|
+
(block
|
44
|
+
(opts_const_statement (string)))))
|
45
|
+
|
46
|
+
============
|
47
|
+
Name and description
|
48
|
+
============
|
49
|
+
|
50
|
+
arg foo "my description"
|
51
|
+
|
52
|
+
---
|
53
|
+
|
54
|
+
(source_file
|
55
|
+
(arg_statement
|
56
|
+
(arg_type)
|
57
|
+
(arg_name_list (string))
|
58
|
+
(string)))
|
59
|
+
|
60
|
+
============
|
61
|
+
Names and description
|
62
|
+
============
|
63
|
+
|
64
|
+
arg (foo bar) "my description"
|
65
|
+
|
66
|
+
---
|
67
|
+
|
68
|
+
(source_file
|
69
|
+
(arg_statement
|
70
|
+
(arg_type)
|
71
|
+
(arg_name_list (string) (string))
|
72
|
+
(string)))
|
73
|
+
|
74
|
+
============
|
75
|
+
Optional arg
|
76
|
+
============
|
77
|
+
|
78
|
+
opt arg
|
79
|
+
opt arg foo @whatever {
|
80
|
+
opts const abc
|
81
|
+
}
|
82
|
+
|
83
|
+
---
|
84
|
+
|
85
|
+
(source_file
|
86
|
+
(arg_statement
|
87
|
+
(arg_modifier)
|
88
|
+
(arg_type))
|
89
|
+
(arg_statement
|
90
|
+
(arg_modifier)
|
91
|
+
(arg_type)
|
92
|
+
(arg_name_list (string))
|
93
|
+
(at_identifier)
|
94
|
+
(block
|
95
|
+
(opts_const_statement (string)))))
|
96
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
==========
|
2
|
+
At include
|
3
|
+
==========
|
4
|
+
|
5
|
+
sub ok {
|
6
|
+
arg {
|
7
|
+
include @foo
|
8
|
+
opts const abc
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
---
|
13
|
+
|
14
|
+
(source_file
|
15
|
+
(sub_statement
|
16
|
+
(sub_name_list (string))
|
17
|
+
(block
|
18
|
+
(arg_statement
|
19
|
+
(arg_type)
|
20
|
+
(block
|
21
|
+
(include_statement
|
22
|
+
(at_identifier))
|
23
|
+
(opts_const_statement
|
24
|
+
(string)))))))
|
25
|
+
|
26
|
+
=============
|
27
|
+
At definition
|
28
|
+
=============
|
29
|
+
|
30
|
+
defopts @bar {
|
31
|
+
opts const def
|
32
|
+
}
|
33
|
+
|
34
|
+
defargs @foo {
|
35
|
+
arg
|
36
|
+
}
|
37
|
+
|
38
|
+
---
|
39
|
+
|
40
|
+
(source_file
|
41
|
+
(defopts_statement
|
42
|
+
(at_identifier)
|
43
|
+
(block
|
44
|
+
(opts_const_statement (string))))
|
45
|
+
(defargs_statement
|
46
|
+
(at_identifier)
|
47
|
+
(block
|
48
|
+
(arg_statement
|
49
|
+
(arg_type)))))
|
50
|
+
|
51
|
+
=================
|
52
|
+
Inline at include
|
53
|
+
=================
|
54
|
+
|
55
|
+
sub whatever @foo {
|
56
|
+
flagarg foo @wombat
|
57
|
+
arg @bar {
|
58
|
+
opts const abc
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
---
|
63
|
+
|
64
|
+
(source_file
|
65
|
+
(sub_statement
|
66
|
+
(sub_name_list (string))
|
67
|
+
(at_identifier)
|
68
|
+
(block
|
69
|
+
(flagarg_statement
|
70
|
+
(flag_name_list (string))
|
71
|
+
(at_identifier))
|
72
|
+
(arg_statement
|
73
|
+
(arg_type)
|
74
|
+
(at_identifier)
|
75
|
+
(block
|
76
|
+
(opts_const_statement
|
77
|
+
(string)))))))
|
78
|
+
|
79
|
+
|