From 947c43052cdaebfbdff82a640fa02b2dfe09f329 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Sat, 19 Aug 2023 19:28:45 +0300 Subject: [PATCH] feat(injections): add printf format strings --- SUPPORTED_LANGUAGES.md | 2 + lockfile.json | 3 ++ lua/nvim-treesitter/parsers.lua | 10 ++++ runtime/queries/awk/injections.scm | 8 ++++ runtime/queries/bash/injections.scm | 25 ++++++++++ runtime/queries/c/injections.scm | 67 +++++++++++++++++++++++++++ runtime/queries/go/injections.scm | 14 ++++++ runtime/queries/java/injections.scm | 7 +++ runtime/queries/kotlin/injections.scm | 8 ++++ runtime/queries/lua/injections.scm | 17 +++++++ runtime/queries/printf/highlights.scm | 1 + runtime/queries/python/injections.scm | 5 ++ runtime/queries/teal/highlights.scm | 20 -------- runtime/queries/teal/injections.scm | 17 +++++++ 14 files changed, 184 insertions(+), 20 deletions(-) create mode 100644 runtime/queries/printf/highlights.scm diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index 2e8b960fb..613ac3a2a 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -153,6 +153,7 @@ jsx (queries only)[^jsx] | core | `HFIJ ` | | | @steelsojka [po](https://github.com/erasin/tree-sitter-po) | core | `HF J ` | | | @amaanq [poe_filter](https://github.com/ObserverOfTime/tree-sitter-poe-filter)[^poe_filter] | unsupported | `HFIJ ` | | | @ObserverOfTime [pony](https://github.com/amaanq/tree-sitter-pony) | core | `HFIJL` | | | @amaanq, @mfelsche +[printf](https://github.com/ObserverOfTime/tree-sitter-printf)[^printf] | core | `H    ` | | | @ObserverOfTime [prisma](https://github.com/victorhqc/tree-sitter-prisma) | community | `H    ` | | | @elianiva [promql](https://github.com/MichaHoffmann/tree-sitter-promql) | unsupported | `H  J ` | | | @MichaHoffmann [proto](https://github.com/treywood/tree-sitter-proto) | community | `HF   ` | | | @treywood @@ -241,6 +242,7 @@ jsx (queries only)[^jsx] | core | `HFIJ ` | | | @steelsojka [^markdown]: basic highlighting [^markdown_inline]: needed for full highlighting [^poe_filter]: Path of Exile item filter +[^printf]: printf format strings [^query]: Tree-sitter query language [^uxntal]: uxn tal diff --git a/lockfile.json b/lockfile.json index 92be351a8..87392751c 100644 --- a/lockfile.json +++ b/lockfile.json @@ -413,6 +413,9 @@ "pony": { "revision": "16f930b250433cfcd4fb4144df92bb98ad344c20" }, + "printf": { + "revision": "8a3f07c1f620ae46d14873e5b7ee0d3e114c15e8" + }, "prisma": { "revision": "eca2596a355b1a9952b4f80f8f9caed300a272b5" }, diff --git a/lua/nvim-treesitter/parsers.lua b/lua/nvim-treesitter/parsers.lua index e2cabb762..c5e02b8f4 100644 --- a/lua/nvim-treesitter/parsers.lua +++ b/lua/nvim-treesitter/parsers.lua @@ -1314,6 +1314,16 @@ M.configs = { tier = 2, }, + printf = { + install_info = { + url = 'https://github.com/ObserverOfTime/tree-sitter-printf', + files = { 'src/parser.c' }, + }, + maintainers = { '@ObserverOfTime' }, + readme_note = 'printf format strings', + tier = 2, + }, + prisma = { install_info = { url = 'https://github.com/victorhqc/tree-sitter-prisma', diff --git a/runtime/queries/awk/injections.scm b/runtime/queries/awk/injections.scm index bc35c8312..24db57d67 100644 --- a/runtime/queries/awk/injections.scm +++ b/runtime/queries/awk/injections.scm @@ -3,3 +3,11 @@ ((regex) @injection.content (#set! injection.language "regex")) + +((print_statement + (exp_list . (string) @injection.content)) + (#set! injection.language "printf")) + +((printf_statement + (exp_list . (string) @injection.content)) + (#set! injection.language "printf")) diff --git a/runtime/queries/bash/injections.scm b/runtime/queries/bash/injections.scm index 1e28848cc..9b7ff6198 100644 --- a/runtime/queries/bash/injections.scm +++ b/runtime/queries/bash/injections.scm @@ -8,3 +8,28 @@ (heredoc_body) @injection.content (heredoc_end) @injection.language) (#downcase! @injection.language)) + +; printf 'format' +((command + name: (command_name) @_command + . argument: [(string) (raw_string)] @injection.content) + (#eq? @_command "printf") + (#set! injection.language "printf")) + +; printf -v var 'format' +((command + name: (command_name) @_command + argument: (word) @_arg + . (_) . argument: [(string) (raw_string)] @injection.content) + (#eq? @_command "printf") + (#eq? @_arg "-v") + (#set! injection.language "printf")) + +; printf -- 'format' +((command + name: (command_name) @_command + argument: (word) @_arg + . argument: [(string) (raw_string)] @injection.content) + (#eq? @_command "printf") + (#eq? @_arg "--") + (#set! injection.language "printf")) diff --git a/runtime/queries/c/injections.scm b/runtime/queries/c/injections.scm index 310cde06e..e2a2129df 100644 --- a/runtime/queries/c/injections.scm +++ b/runtime/queries/c/injections.scm @@ -12,6 +12,73 @@ (#lua-match? @injection.content "/[*][!<*][^a-zA-Z]") (#set! injection.language "doxygen")) +((call_expression + function: (identifier) @_function + arguments: (argument_list + . (string_literal (string_content) @injection.content))) + (#any-of? @_function "printf" "printf_s" + "vprintf" "vprintf_s" + "scanf" "scanf_s" + "vscanf" "vscanf_s" + "wprintf" "wprintf_s" + "vwprintf" "vwprintf_s" + "wscanf" "wscanf_s" + "vwscanf" "vwscanf_s" + "cscanf" "_cscanf" + "printw" + "scanw") + (#set! injection.language "printf")) + +((call_expression + function: (identifier) @_function + arguments: (argument_list + (_) . (string_literal (string_content) @injection.content))) + (#any-of? @_function "fprintf" "fprintf_s" + "sprintf" + "dprintf" + "fscanf" "fscanf_s" + "sscanf" "sscanf_s" + "vsscanf" "vsscanf_s" + "vfprintf" "vfprintf_s" + "vsprintf" + "vdprintf" + "fwprintf" "fwprintf_s" + "vfwprintf" "vfwprintf_s" + "fwscanf" "fwscanf_s" + "swscanf" "swscanf_s" + "vswscanf" "vswscanf_s" + "vfscanf" "vfscanf_s" + "vfwscanf" "vfwscanf_s" + "wprintw" + "vw_printw" "vwprintw" + "wscanw" + "vw_scanw" "vwscanw") + (#set! injection.language "printf")) + +((call_expression + function: (identifier) @_function + arguments: (argument_list + (_) . (_) . (string_literal (string_content) @injection.content))) + (#any-of? @_function "sprintf_s" + "snprintf" "snprintf_s" + "vsprintf_s" + "vsnprintf" "vsnprintf_s" + "swprintf" "swprintf_s" + "snwprintf_s" + "vswprintf" "vswprintf_s" + "vsnwprintf_s" + "mvprintw" + "mvscanw") + (#set! injection.language "printf")) + +((call_expression + function: (identifier) @_function + arguments: (argument_list + (_) . (_) . (_) . (string_literal (string_content) @injection.content))) + (#any-of? @_function "mvwprintw" + "mvwscanw") + (#set! injection.language "printf")) + ; TODO: add when asm is added ; (gnu_asm_expression assembly_code: (string_literal) @injection.content ; (#set! injection.language "asm")) diff --git a/runtime/queries/go/injections.scm b/runtime/queries/go/injections.scm index affc7a115..cf19ebac5 100644 --- a/runtime/queries/go/injections.scm +++ b/runtime/queries/go/injections.scm @@ -19,6 +19,20 @@ (#offset! @injection.content 0 1 0 -1) (#set! injection.language "regex"))) + ((comment) @injection.content (#match? @injection.content "/\\*!([a-zA-Z]+:)?re2c") (#set! injection.language "re2c")) + +((call_expression + function: (selector_expression field: (field_identifier) @_method) + arguments: (argument_list . (interpreted_string_literal) @injection.content)) + (#any-of? @_method "Printf" "Sprintf" "Fatalf" "Scanf") + (#set! injection.language "printf")) + +((call_expression + function: (selector_expression field: (field_identifier) @_method) + arguments: (argument_list (_) . (interpreted_string_literal) @injection.content)) + (#eq? @_method "Fprintf") + (#set! injection.language "printf")) + diff --git a/runtime/queries/java/injections.scm b/runtime/queries/java/injections.scm index d79ffa6f1..8696c16ff 100644 --- a/runtime/queries/java/injections.scm +++ b/runtime/queries/java/injections.scm @@ -7,3 +7,10 @@ ((block_comment) @injection.content (#lua-match? @injection.content "/[*][!<*][^a-zA-Z]") (#set! injection.language "doxygen")) + +((method_invocation + name: (identifier) @_method + arguments: (argument_list + . (string_literal . (_) @injection.content))) + (#any-of? @_method "format" "printf") + (#set! injection.language "printf")) diff --git a/runtime/queries/kotlin/injections.scm b/runtime/queries/kotlin/injections.scm index 757259d10..8ac2eba60 100644 --- a/runtime/queries/kotlin/injections.scm +++ b/runtime/queries/kotlin/injections.scm @@ -34,3 +34,11 @@ (value_arguments (value_argument (string_literal) @injection.content (#set! injection.language "regex"))))) + +; "pi = %.2f".format(3.14159) +((call_expression + (navigation_expression + (string_literal) @injection.content + (navigation_suffix (simple_identifier) @_method))) + (#eq? @_method "format") + (#set! injection.language "printf")) diff --git a/runtime/queries/lua/injections.scm b/runtime/queries/lua/injections.scm index 85c677665..2e8c64275 100644 --- a/runtime/queries/lua/injections.scm +++ b/runtime/queries/lua/injections.scm @@ -87,6 +87,23 @@ (#set! injection.language "luap") (#set! injection.include-children)))) +; string.format("pi = %.2f", 3.14159) +((function_call + (dot_index_expression + field: (identifier) @_method) + arguments: (arguments + . (string (string_content) @injection.content))) + (#eq? @_method "format") + (#set! injection.language "printf")) + +; ("pi = %.2f"):format(3.14159) +((function_call + (method_index_expression + table: (_ (string (string_content) @injection.content)) + method: (identifier) @_method)) + (#eq? @_method "format") + (#set! injection.language "printf")) + ((comment) @injection.content (#set! injection.language "comment") (#set! injection.include-children)) diff --git a/runtime/queries/printf/highlights.scm b/runtime/queries/printf/highlights.scm new file mode 100644 index 000000000..db5ef9a3f --- /dev/null +++ b/runtime/queries/printf/highlights.scm @@ -0,0 +1 @@ +(format) @character diff --git a/runtime/queries/python/injections.scm b/runtime/queries/python/injections.scm index b836ea3f7..dcc7eada8 100644 --- a/runtime/queries/python/injections.scm +++ b/runtime/queries/python/injections.scm @@ -7,5 +7,10 @@ (#lua-match? @_string "^r.*") (#set! injection.language "regex")) +((binary_operator + left: (string (string_content) @injection.content) + operator: "%") + (#set! injection.language "printf")) + ((comment) @injection.content (#set! injection.language "comment")) diff --git a/runtime/queries/teal/highlights.scm b/runtime/queries/teal/highlights.scm index 4af3e212b..23c168276 100644 --- a/runtime/queries/teal/highlights.scm +++ b/runtime/queries/teal/highlights.scm @@ -112,24 +112,4 @@ . ">" @punctuation.bracket))) [ "(" ")" "[" "]" "{" "}" ] @punctuation.bracket -;; Only highlight format specifiers in calls to string.format -;; string.format('...') -;(function_call -; called_object: (index -; (identifier) @base -; key: (identifier) @entry) -; arguments: (arguments . -; (string (format_specifier) @string.escape)) -; -; (#eq? @base "string") -; (#eq? @entry "format")) - -;; ('...'):format() -;(function_call -; called_object: (method_index -; (string (format_specifier) @string.escape) -; key: (identifier) @func-name) -; (#eq? @func-name "format")) - - (ERROR) @error diff --git a/runtime/queries/teal/injections.scm b/runtime/queries/teal/injections.scm index 5eef08702..789826452 100644 --- a/runtime/queries/teal/injections.scm +++ b/runtime/queries/teal/injections.scm @@ -26,5 +26,22 @@ (#set! injection.language "c") ) +; string.format('...') +((function_call + (index + (identifier) @_base + key: (identifier) @_entry) + (arguments . (string) @injection.content)) + (#eq? @_base "string") + (#eq? @_entry "format") + (#set! injection.language "printf")) + +; ('...'):format() +((function_call + (method_index (string) @printf + key: (identifier) @_func)) + (#eq? @_func "format") + (#set! injection.language "printf")) + ((comment) @injection.content (#set! injection.language "comment"))