diff --git a/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.pbxproj b/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.pbxproj index 239f338..7660f65 100644 --- a/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.pbxproj +++ b/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 282C119329AA32C8004F1EA6 /* TreeSitterSQL in Frameworks */ = {isa = PBXBuildFile; productRef = 282C119229AA32C8004F1EA6 /* TreeSitterSQL */; }; 282E5977298051980064B34A /* TreeSitterYAML in Frameworks */ = {isa = PBXBuildFile; productRef = 282E5976298051980064B34A /* TreeSitterYAML */; }; 2846B262296BA1CF005F60B6 /* TreeSitterDockerfile in Frameworks */ = {isa = PBXBuildFile; productRef = 2846B261296BA1CF005F60B6 /* TreeSitterDockerfile */; }; + 285BF67329AAA45B00641989 /* TreeSitterLua in Frameworks */ = {isa = PBXBuildFile; productRef = 285BF67229AAA45B00641989 /* TreeSitterLua */; }; 2886C788298135540023E016 /* TreeSitterKotlin in Frameworks */ = {isa = PBXBuildFile; productRef = 2886C787298135540023E016 /* TreeSitterKotlin */; }; 28B3F010290C207D000CD04D /* CodeLanguages_Container.h in Headers */ = {isa = PBXBuildFile; fileRef = 28B3F00F290C207D000CD04D /* CodeLanguages_Container.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28B3F02D290C35D9000CD04D /* TreeSitterC in Frameworks */ = {isa = PBXBuildFile; productRef = 28B3F02C290C35D9000CD04D /* TreeSitterC */; }; @@ -48,6 +49,7 @@ files = ( 28B3F051290C36B1000CD04D /* TreeSitterPHP in Frameworks */, 28B3F042290C365C000CD04D /* TreeSitterHaskell in Frameworks */, + 285BF67329AAA45B00641989 /* TreeSitterLua in Frameworks */, 2846B262296BA1CF005F60B6 /* TreeSitterDockerfile in Frameworks */, 282C119329AA32C8004F1EA6 /* TreeSitterSQL in Frameworks */, 28B3F039290C362C000CD04D /* TreeSitterElixir in Frameworks */, @@ -172,6 +174,7 @@ 28171CB729814CD800523F1C /* TreeSitterObjC */, 9D6DA3B7298F1A4600E69066 /* TreeSitterOCaml */, 282C119229AA32C8004F1EA6 /* TreeSitterSQL */, + 285BF67229AAA45B00641989 /* TreeSitterLua */, ); productName = "CodeLanguages-Container"; productReference = 28B3F00C290C207D000CD04D /* CodeLanguages_Container.framework */; @@ -227,6 +230,7 @@ 28171CB629814CD800523F1C /* XCRemoteSwiftPackageReference "tree-sitter-objc" */, 9D6DA3B6298F1A4500E69066 /* XCRemoteSwiftPackageReference "tree-sitter-ocaml" */, 282C119129AA32C8004F1EA6 /* XCRemoteSwiftPackageReference "tree-sitter-sql" */, + 285BF67129AAA45B00641989 /* XCRemoteSwiftPackageReference "tree-sitter-lua" */, ); productRefGroup = 28B3F00D290C207D000CD04D /* Products */; projectDirPath = ""; @@ -498,6 +502,14 @@ kind = branch; }; }; + 285BF67129AAA45B00641989 /* XCRemoteSwiftPackageReference "tree-sitter-lua" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/lukepistrol/tree-sitter-lua.git"; + requirement = { + branch = feature/spm; + kind = branch; + }; + }; 2886C786298135540023E016 /* XCRemoteSwiftPackageReference "tree-sitter-kotlin" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/lukepistrol/tree-sitter-kotlin"; @@ -689,6 +701,11 @@ package = 2846B260296BA1CF005F60B6 /* XCRemoteSwiftPackageReference "tree-sitter-dockerfile" */; productName = TreeSitterDockerfile; }; + 285BF67229AAA45B00641989 /* TreeSitterLua */ = { + isa = XCSwiftPackageProductDependency; + package = 285BF67129AAA45B00641989 /* XCRemoteSwiftPackageReference "tree-sitter-lua" */; + productName = TreeSitterLua; + }; 2886C787298135540023E016 /* TreeSitterKotlin */ = { isa = XCSwiftPackageProductDependency; package = 2886C786298135540023E016 /* XCRemoteSwiftPackageReference "tree-sitter-kotlin" */; diff --git a/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1cfda61..e43e01b 100644 --- a/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeLanguages-Container/CodeLanguages-Container.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -144,6 +144,15 @@ "revision" : "e32e32678449efaeccd908e41ed6b27ec8c9d2cf" } }, + { + "identity" : "tree-sitter-lua", + "kind" : "remoteSourceControl", + "location" : "https://github.com/lukepistrol/tree-sitter-lua.git", + "state" : { + "branch" : "feature/spm", + "revision" : "47d56065016862b85ad327d6976b1e664e1c034b" + } + }, { "identity" : "tree-sitter-objc", "kind" : "remoteSourceControl", diff --git a/CodeLanguages-Container/CodeLanguages-Container/CodeLanguages_Container.h b/CodeLanguages-Container/CodeLanguages-Container/CodeLanguages_Container.h index 02daad4..8aa2579 100644 --- a/CodeLanguages-Container/CodeLanguages-Container/CodeLanguages_Container.h +++ b/CodeLanguages-Container/CodeLanguages-Container/CodeLanguages_Container.h @@ -37,6 +37,7 @@ extern TSLanguage *tree_sitter_java(); extern TSLanguage *tree_sitter_javascript(); extern TSLanguage *tree_sitter_json(); extern TSLanguage *tree_sitter_kotlin(); +extern TSLanguage *tree_sitter_lua(); extern TSLanguage *tree_sitter_objc(); extern TSLanguage *tree_sitter_ocaml(); extern TSLanguage *tree_sitter_ocaml_interface(); diff --git a/CodeLanguagesContainer.xcframework.zip b/CodeLanguagesContainer.xcframework.zip index 88e568c..444cbc0 100644 Binary files a/CodeLanguagesContainer.xcframework.zip and b/CodeLanguagesContainer.xcframework.zip differ diff --git a/README.md b/README.md index 6aed6ef..1b539f9 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ In order to add support for additional languages we have a complete guide on how | [JSON](https://github.com/mattmassicotte/tree-sitter-json) | ✅ | ✅ | | [Julia](https://github.com/tree-sitter/tree-sitter-julia) | | _not available_ | | [Kotlin](https://github.com/lukepistrol/tree-sitter-kotlin/tree/feature/spm-queries) | ✅ | ✅ | +| [Lua](https://github.com/lukepistrol/tree-sitter-lua/tree/feature/spm) | ✅ | ✅ | | [Markdown](https://github.com/ikatyang/tree-sitter-markdown) | | _not available_ | | [Objective C](https://github.com/lukepistrol/tree-sitter-objc/tree/feature/spm) | ✅ | ✅ | | [OCaml](https://github.com/cengelbart39/tree-sitter-ocaml/tree/feature/spm) | ✅ | ✅ | diff --git a/Sources/CodeEditLanguages/CodeLanguage+Definitions.swift b/Sources/CodeEditLanguages/CodeLanguage+Definitions.swift index 7db36a7..64d21bf 100644 --- a/Sources/CodeEditLanguages/CodeLanguage+Definitions.swift +++ b/Sources/CodeEditLanguages/CodeLanguage+Definitions.swift @@ -27,6 +27,7 @@ public extension CodeLanguage { .json, .jsx, .kotlin, + .lua, .objc, .ocaml, .ocamlInterface, @@ -154,6 +155,13 @@ public extension CodeLanguage { extensions: ["kt", "kts"] ) + /// A language structure for `Lua` + static let lua: CodeLanguage = .init( + id: .lua, + tsName: "lua", + extensions: ["lua"] + ) + /// A language structure for `Objective C` static let objc: CodeLanguage = .init( id: .objc, diff --git a/Sources/CodeEditLanguages/CodeLanguage.swift b/Sources/CodeEditLanguages/CodeLanguage.swift index d2983d2..b252776 100644 --- a/Sources/CodeEditLanguages/CodeLanguage.swift +++ b/Sources/CodeEditLanguages/CodeLanguage.swift @@ -98,6 +98,8 @@ public struct CodeLanguage { return tree_sitter_javascript() case .kotlin: return tree_sitter_kotlin() + case .lua: + return tree_sitter_lua() case .objc: return tree_sitter_objc() case .ocaml: diff --git a/Sources/CodeEditLanguages/Documentation.docc/CodeLanguage.md b/Sources/CodeEditLanguages/Documentation.docc/CodeLanguage.md index c2fff42..43e31f7 100644 --- a/Sources/CodeEditLanguages/Documentation.docc/CodeLanguage.md +++ b/Sources/CodeEditLanguages/Documentation.docc/CodeLanguage.md @@ -35,6 +35,7 @@ let language = CodeLanguage.detectLanguageFrom(url: fileURL) - JSON - JSX - Kotlin +- Lua - Objective C - OCaml / OCaml Interface - PHP @@ -83,6 +84,7 @@ let language = CodeLanguage.detectLanguageFrom(url: fileURL) - ``json`` - ``jsx`` - ``kotlin`` +- ``lua`` - ``objc`` - ``php`` - ``python`` diff --git a/Sources/CodeEditLanguages/Documentation.docc/TreeSitterModel.md b/Sources/CodeEditLanguages/Documentation.docc/TreeSitterModel.md index d0acc92..eb5d222 100644 --- a/Sources/CodeEditLanguages/Documentation.docc/TreeSitterModel.md +++ b/Sources/CodeEditLanguages/Documentation.docc/TreeSitterModel.md @@ -48,6 +48,7 @@ let query = TreeSitterModel.shared.swiftQuery - ``jsonQuery`` - ``jsxQuery`` - ``kotlinQuery`` +- ``luaQuery`` - ``objcQuery`` - ``ocamlQuery`` - ``ocamlInterfaceQuery`` diff --git a/Sources/CodeEditLanguages/Resources/tree-sitter-lua/highlights.scm b/Sources/CodeEditLanguages/Resources/tree-sitter-lua/highlights.scm new file mode 100644 index 0000000..f3009a7 --- /dev/null +++ b/Sources/CodeEditLanguages/Resources/tree-sitter-lua/highlights.scm @@ -0,0 +1,194 @@ +;; Keywords + +"return" @keyword.return + +[ + "goto" + "in" + "local" +] @keyword + +(label_statement) @label + +(break_statement) @keyword + +(do_statement +[ + "do" + "end" +] @keyword) + +(while_statement +[ + "while" + "do" + "end" +] @repeat) + +(repeat_statement +[ + "repeat" + "until" +] @repeat) + +(if_statement +[ + "if" + "elseif" + "else" + "then" + "end" +] @conditional) + +(elseif_statement +[ + "elseif" + "then" + "end" +] @conditional) + +(else_statement +[ + "else" + "end" +] @conditional) + +(for_statement +[ + "for" + "do" + "end" +] @repeat) + +(function_declaration +[ + "function" + "end" +] @keyword.function) + +(function_definition +[ + "function" + "end" +] @keyword.function) + +;; Operators + +[ + "and" + "not" + "or" +] @keyword.operator + +[ + "+" + "-" + "*" + "/" + "%" + "^" + "#" + "==" + "~=" + "<=" + ">=" + "<" + ">" + "=" + "&" + "~" + "|" + "<<" + ">>" + "//" + ".." +] @operator + +;; Punctuations + +[ + ";" + ":" + "," + "." +] @punctuation.delimiter + +;; Brackets + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +;; Variables + +(identifier) @variable + +((identifier) @variable.builtin + (#eq? @variable.builtin "self")) + +(variable_list + attribute: (attribute + (["<" ">"] @punctuation.bracket + (identifier) @attribute))) + +;; Constants + +((identifier) @constant + (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) + +(vararg_expression) @constant + +(nil) @constant.builtin + +[ + (false) + (true) +] @boolean + +;; Tables + +(field name: (identifier) @field) + +(dot_index_expression field: (identifier) @field) + +(table_constructor +[ + "{" + "}" +] @constructor) + +;; Functions + +(parameters (identifier) @parameter) + +(function_call name: (identifier) @function.call) +(function_declaration name: (identifier) @function) + +(function_call name: (dot_index_expression field: (identifier) @function.call)) +(function_declaration name: (dot_index_expression field: (identifier) @function)) + +(method_index_expression method: (identifier) @method) + +(function_call + (identifier) @function.builtin + (#any-of? @function.builtin + ;; built-in functions in Lua 5.1 + "assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs" + "load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print" + "rawequal" "rawget" "rawset" "require" "select" "setfenv" "setmetatable" + "tonumber" "tostring" "type" "unpack" "xpcall")) + +;; Others + +(comment) @comment + +(hash_bang_line) @preproc + +(number) @number + +(string) @string diff --git a/Sources/CodeEditLanguages/Resources/tree-sitter-lua/injections.scm b/Sources/CodeEditLanguages/Resources/tree-sitter-lua/injections.scm new file mode 100644 index 0000000..77379fa --- /dev/null +++ b/Sources/CodeEditLanguages/Resources/tree-sitter-lua/injections.scm @@ -0,0 +1,8 @@ +((function_call + name: [ + (identifier) @_cdef_identifier + (_ _ (identifier) @_cdef_identifier) + ] + arguments: (arguments (string content: _ @injection.content + (#set! injection.language "c")))) + (#eq? @_cdef_identifier "cdef")) diff --git a/Sources/CodeEditLanguages/Resources/tree-sitter-lua/locals.scm b/Sources/CodeEditLanguages/Resources/tree-sitter-lua/locals.scm new file mode 100644 index 0000000..9c00817 --- /dev/null +++ b/Sources/CodeEditLanguages/Resources/tree-sitter-lua/locals.scm @@ -0,0 +1,36 @@ +; Scopes + +[ + (chunk) + (do_statement) + (while_statement) + (repeat_statement) + (if_statement) + (for_statement) + (function_declaration) + (function_definition) +] @local.scope + +; Definitions + +(assignment_statement + (variable_list + (identifier) @local.definition)) + +(function_declaration + name: (identifier) @local.definition) + +(for_generic_clause + (variable_list + (identifier) @local.definition)) + +(for_numeric_clause + name: (identifier) @local.definition) + +(parameters (identifier) @local.definition) + +; References + +[ + (identifier) +] @local.reference diff --git a/Sources/CodeEditLanguages/TreeSitterLanguage.swift b/Sources/CodeEditLanguages/TreeSitterLanguage.swift index 400eb55..694055a 100644 --- a/Sources/CodeEditLanguages/TreeSitterLanguage.swift +++ b/Sources/CodeEditLanguages/TreeSitterLanguage.swift @@ -25,6 +25,7 @@ public enum TreeSitterLanguage: String { case json case jsx case kotlin + case lua case objc case ocaml case ocamlInterface diff --git a/Sources/CodeEditLanguages/TreeSitterModel.swift b/Sources/CodeEditLanguages/TreeSitterModel.swift index 469acef..1b6a931 100644 --- a/Sources/CodeEditLanguages/TreeSitterModel.swift +++ b/Sources/CodeEditLanguages/TreeSitterModel.swift @@ -52,6 +52,8 @@ public class TreeSitterModel { return jsxQuery case .kotlin: return kotlinQuery + case .lua: + return luaQuery case .objc: return objcQuery case .ocaml: @@ -159,6 +161,11 @@ public class TreeSitterModel { return queryFor(.kotlin) }() + /// Query for `Lua` files. + public private(set) lazy var luaQuery: Query? = { + return queryFor(.lua) + }() + /// Query for `Objective C` files. public private(set) lazy var objcQuery: Query? = { return queryFor(.objc) diff --git a/Tests/CodeEditLanguagesTests/CodeEditLanguagesTests.swift b/Tests/CodeEditLanguagesTests/CodeEditLanguagesTests.swift index 2b0f6e8..67bcaff 100644 --- a/Tests/CodeEditLanguagesTests/CodeEditLanguagesTests.swift +++ b/Tests/CodeEditLanguagesTests/CodeEditLanguagesTests.swift @@ -374,6 +374,25 @@ final class CodeEditLanguagesTests: XCTestCase { XCTAssertNotEqual(query?.patternCount, 0) } + // MARK: - Lua + + func test_CodeLanguageLua() throws { + let url = URL(fileURLWithPath: "~/path/to/file.lua") + let language = CodeLanguage.detectLanguageFrom(url: url) + + XCTAssertEqual(language.id, .lua) + } + + func test_FetchQueryLua() throws { + var language = CodeLanguage.lua + language.resourceURL = bundleURL + + let data = try Data(contentsOf: language.queryURL!) + let query = try? Query(language: language.language!, data: data) + XCTAssertNotNil(query) + XCTAssertNotEqual(query?.patternCount, 0) + } + // MARK: - Objective C func test_CodeLanguageObjC() throws {