tabry 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/bin/tabry-bash +3 -0
  3. data/bin/tabry-help +1 -1
  4. data/lib/tabry/config_loader.rb +9 -2
  5. data/lib/tabry/shells/bash.rb +35 -0
  6. data/lib/tabry/usage_generator.rb +5 -5
  7. data/sh/bash/README.md +36 -0
  8. data/sh/bash/tabry_bash.sh +22 -0
  9. data/sh/{tabry_bash.sh → bash/tabry_bash_core.sh} +6 -16
  10. data/sh/{tabry_bash_help.sh → bash/tabry_bash_help.sh} +1 -1
  11. data/spec/tabry/config_loader_spec.rb +9 -3
  12. data/tabry.gemspec +22 -2
  13. data/treesitter/Cargo.toml +26 -0
  14. data/treesitter/README.md +4 -0
  15. data/treesitter/binding.gyp +19 -0
  16. data/treesitter/bindings/node/binding.cc +28 -0
  17. data/treesitter/bindings/node/index.js +19 -0
  18. data/treesitter/bindings/rust/build.rs +40 -0
  19. data/treesitter/bindings/rust/lib.rs +52 -0
  20. data/treesitter/corpus/arg.txt +96 -0
  21. data/treesitter/corpus/at.txt +79 -0
  22. data/treesitter/corpus/comment.txt +13 -0
  23. data/treesitter/corpus/desc.txt +25 -0
  24. data/treesitter/corpus/examples_from_language_reference.txt +410 -0
  25. data/treesitter/corpus/flag.txt +48 -0
  26. data/treesitter/corpus/flag_desc_inline.txt +37 -0
  27. data/treesitter/corpus/opts.txt +21 -0
  28. data/treesitter/corpus/rapture.txt +61 -0
  29. data/treesitter/grammar.js +171 -0
  30. data/treesitter/jest_fixtures/examples_from_language_reference/argument_titles.yml +8 -0
  31. data/treesitter/jest_fixtures/examples_from_language_reference/arguments_and_possible_options__arg_.yml +23 -0
  32. data/treesitter/jest_fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.yml +37 -0
  33. data/treesitter/jest_fixtures/examples_from_language_reference/getting_started.yml +13 -0
  34. data/treesitter/jest_fixtures/examples_from_language_reference/includes.yml +57 -0
  35. data/treesitter/jest_fixtures/examples_from_language_reference/multi_line_descriptions.yml +7 -0
  36. data/treesitter/jest_fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.yml +16 -0
  37. data/treesitter/jest_fixtures/examples_from_language_reference/options.yml +24 -0
  38. data/treesitter/jest_fixtures/examples_from_language_reference/subcommands__sub__1.yml +23 -0
  39. data/treesitter/jest_fixtures/examples_from_language_reference/subcommands__sub__2.yml +15 -0
  40. data/treesitter/package.json +21 -0
  41. data/treesitter/parser_compile.sh +1 -0
  42. data/treesitter/src/grammar.json +615 -0
  43. data/treesitter/src/node-types.json +563 -0
  44. data/treesitter/src/parser.c +4706 -0
  45. data/treesitter/src/tree_sitter/parser.h +223 -0
  46. data/treesitter/tabry-compile.js +394 -0
  47. data/treesitter/tabry-compile.test.js +51 -0
  48. metadata +41 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8531aa56c6c59a5d678e280ccb39fa8fd891aadac1d4fd194d73cacee20aaa47
4
- data.tar.gz: ab532e18804f52824ccebf21667aa8da6416324eaa428d58140b758e22160b6a
3
+ metadata.gz: 1b1cb912ae500805787b62500d1c4995215bc9e3c8a4ccf32b7224bc4fa227c6
4
+ data.tar.gz: 68244bb100b3a262527b723b02fd6e73e9158f756bf44df960f8e5bd3d7e4679
5
5
  SHA512:
6
- metadata.gz: 62d4481040a2c2e06e5f16e0c5ef559fddf4cb6330d61d9962af8295c940d56c40bce23df662dbb168c83c48ed929fe30e1f2bf7e91ddc6fda06595c9576b63c
7
- data.tar.gz: 1447eb824ec57c40b4dcc4eaeaefbd1488f514bd10535c7035f3439558f03a1368c1cf1cc7674804d2976ab9dadede3d0a818ff9e87e140cd58f67e983026ffb
6
+ metadata.gz: 0d6e9694ca66c39e5627eed4e8159ad95510ae1f146221529d068ca92c32d3e9d3d3208d7da59909467f2833fcf0a064735e49c75816e3b11741fe659bf8d92f
7
+ data.tar.gz: 0572051e1da3fa757609b2c5e956f745f434487e089268db318c1410f72e32a5bf906d4a4a4277cc23a40b77ed64ac8d41b1ebcb9fa0a78c0d0cff3c382c81f9
data/bin/tabry-bash CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ # Run by the tabry_bash_core.sh bash tab completion function to plug into Tabry
5
+ # to get completion options.
6
+
4
7
  require "shellwords"
5
8
  require "yaml"
6
9
  require_relative "../lib/tabry/util"
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
@@ -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 |dir|
24
+ load_paths.each do |path|
25
25
  EXTENSIONS.each do |extension|
26
- filename = "#{dir}/#{name}.#{extension}"
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.last << if full_sub_name == ""
101
- " (global)".green.bold
102
- else
103
- " (#{full_sub_name})".green.bold
104
- end
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
- #/usr/bin/env bash
2
-
3
- # Bash completion
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=`"$_tabry_bash" "$COMP_LINE" "$COMP_POINT"`
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]}" )"/../bin/tabry-help
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.0"
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
- s.files = Dir.glob("{lib,bin,sh,spec}/**/*") + %w[tabry.gemspec]
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,4 @@
1
+ This directory contains the compiler which compiles `*.tabry` files -- Tabry's
2
+ mini-language for describing tab-completion/CLIs, into the JSON format used by
3
+ the tabry gem. See the [main Tabry README](../README.md) for more info on
4
+ compiling and using configs.
@@ -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
+
@@ -0,0 +1,13 @@
1
+ ========
2
+ Comments
3
+ ========
4
+
5
+ # hello
6
+ sub foo # ok
7
+
8
+ ---
9
+
10
+ (source_file
11
+ (sub_statement
12
+ (sub_name_list
13
+ (string))))