tabry 0.1.0 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|