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.
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))))