{"id":13412791,"url":"https://github.com/ziontee113/syntax-tree-surfer","last_synced_at":"2025-04-05T18:09:59.872Z","repository":{"id":37508079,"uuid":"481025402","full_name":"ziontee113/syntax-tree-surfer","owner":"ziontee113","description":"A plugin for Neovim that helps you surf through your document and move elements around using the nvim-treesitter API.","archived":false,"fork":false,"pushed_at":"2024-02-02T08:29:42.000Z","size":68,"stargazers_count":470,"open_issues_count":5,"forks_count":10,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-10-10T23:30:52.090Z","etag":null,"topics":["lua","neovim","nvim","treesitter-api"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ziontee113.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-13T01:11:59.000Z","updated_at":"2024-10-10T12:19:05.000Z","dependencies_parsed_at":"2024-01-03T03:31:15.495Z","dependency_job_id":"c5f402b3-ab0a-4dde-8d03-f809d5fb4e65","html_url":"https://github.com/ziontee113/syntax-tree-surfer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ziontee113%2Fsyntax-tree-surfer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ziontee113%2Fsyntax-tree-surfer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ziontee113%2Fsyntax-tree-surfer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ziontee113%2Fsyntax-tree-surfer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ziontee113","download_url":"https://codeload.github.com/ziontee113/syntax-tree-surfer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247378149,"owners_count":20929297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua","neovim","nvim","treesitter-api"],"created_at":"2024-07-30T20:01:29.254Z","updated_at":"2025-04-05T18:09:59.845Z","avatar_url":"https://github.com/ziontee113.png","language":"Lua","funding_links":[],"categories":["Motion","Lua"],"sub_categories":["Treesitter Based"],"readme":"# 🌳 syntax-tree-surfer 🌳🌊\n\n### Syntax Tree Surfer is a plugin for Neovim that helps you surf through your document and move elements around using the nvim-treesitter API.\n\n![tree surfing cover](https://user-images.githubusercontent.com/102876811/163170119-89369c35-a061-4058-aaeb-1706ea6fa4cf.jpg)\n\n## Table of Contents\n\n1. [Version 1.0 Functionalities](#version-10-functionalities)\n1. [How do I install?](#how-do-i-install)\n1. [Version 1.1 Update](#version-11-update)\n1. [Version 2.0 Beta Update](#version-20-beta-update)\n1. [Version 2.2 Update](#version-22-update)\n\n# Version 1.0 Functionalities\n\n### **Navigate** around your document based on Treesitter's abstract Syntax Tree. Step into, step out, step over, step back.\n\nhttps://user-images.githubusercontent.com/102876811/163170843-a7c9f1a1-4ffb-4a39-9636-fc81521bd9b5.mp4\n\n---\n\n### **Move / Swap** elements around based on your visual selection\n\n\u003c!-- https://user-images.githubusercontent.com/102876811/163171460-4620be6b-360f-4d39-b025-55c412f54a96.mp4 --\u003e\n\nhttps://user-images.githubusercontent.com/102876811/163171686-4ad49b7a-9fd3-41d5-a2c2-deae1bb41c3d.mp4\n\n### **Swap in Normal Mode** - Now supports Dot (.) Repeat\n\nhttps://user-images.githubusercontent.com/102876811/174811583-52b7beb0-853f-4ac9-9498-eb718ce626d9.mp4\n\n\u003c!-- https://user-images.githubusercontent.com/102876811/163173466-b4bfd70f-c239-4e9c-a7ae-c540c093e0f4.mp4 --\u003e\n\n# How do I install?\n\n#### Use your favorite Plugin Manager with the link [ziontee113/syntax-tree-surfer](ziontee113/syntax-tree-surfer)\n\nFor Packer:\n\n```lua\nuse \"ziontee113/syntax-tree-surfer\"\n```\n\n# How do I set things up?\n\n### Here's my suggestion:\n\n```lua\n-- Syntax Tree Surfer\nlocal opts = {noremap = true, silent = true}\n\n-- Normal Mode Swapping:\n-- Swap The Master Node relative to the cursor with it's siblings, Dot Repeatable\nvim.keymap.set(\"n\", \"vU\", function()\n\tvim.opt.opfunc = \"v:lua.STSSwapUpNormal_Dot\"\n\treturn \"g@l\"\nend, { silent = true, expr = true })\nvim.keymap.set(\"n\", \"vD\", function()\n\tvim.opt.opfunc = \"v:lua.STSSwapDownNormal_Dot\"\n\treturn \"g@l\"\nend, { silent = true, expr = true })\n\n-- Swap Current Node at the Cursor with it's siblings, Dot Repeatable\nvim.keymap.set(\"n\", \"vd\", function()\n\tvim.opt.opfunc = \"v:lua.STSSwapCurrentNodeNextNormal_Dot\"\n\treturn \"g@l\"\nend, { silent = true, expr = true })\nvim.keymap.set(\"n\", \"vu\", function()\n\tvim.opt.opfunc = \"v:lua.STSSwapCurrentNodePrevNormal_Dot\"\n\treturn \"g@l\"\nend, { silent = true, expr = true })\n\n--\u003e If the mappings above don't work, use these instead (no dot repeatable)\n-- vim.keymap.set(\"n\", \"vd\", '\u003ccmd\u003eSTSSwapCurrentNodeNextNormal\u003ccr\u003e', opts)\n-- vim.keymap.set(\"n\", \"vu\", '\u003ccmd\u003eSTSSwapCurrentNodePrevNormal\u003ccr\u003e', opts)\n-- vim.keymap.set(\"n\", \"vD\", '\u003ccmd\u003eSTSSwapDownNormal\u003ccr\u003e', opts)\n-- vim.keymap.set(\"n\", \"vU\", '\u003ccmd\u003eSTSSwapUpNormal\u003ccr\u003e', opts)\n\n-- Visual Selection from Normal Mode\nvim.keymap.set(\"n\", \"vx\", '\u003ccmd\u003eSTSSelectMasterNode\u003ccr\u003e', opts)\nvim.keymap.set(\"n\", \"vn\", '\u003ccmd\u003eSTSSelectCurrentNode\u003ccr\u003e', opts)\n\n-- Select Nodes in Visual Mode\nvim.keymap.set(\"x\", \"J\", '\u003ccmd\u003eSTSSelectNextSiblingNode\u003ccr\u003e', opts)\nvim.keymap.set(\"x\", \"K\", '\u003ccmd\u003eSTSSelectPrevSiblingNode\u003ccr\u003e', opts)\nvim.keymap.set(\"x\", \"H\", '\u003ccmd\u003eSTSSelectParentNode\u003ccr\u003e', opts)\nvim.keymap.set(\"x\", \"L\", '\u003ccmd\u003eSTSSelectChildNode\u003ccr\u003e', opts)\n\n-- Swapping Nodes in Visual Mode\nvim.keymap.set(\"x\", \"\u003cA-j\u003e\", '\u003ccmd\u003eSTSSwapNextVisual\u003ccr\u003e', opts)\nvim.keymap.set(\"x\", \"\u003cA-k\u003e\", '\u003ccmd\u003eSTSSwapPrevVisual\u003ccr\u003e', opts)\n```\n\n# Now let's start Tree Surfing! 🌲💦\n\n### Version 1.1 update\n\nThis feature will help you save some keystrokes \u0026 brain power when you want to create some code at the top level node of your current cursor position.\n\n```lua\nlua require(\"syntax-tree-surfer\").go_to_top_node_and_execute_commands(false, { \"normal! O\", \"normal! O\", \"startinsert\" })\u003ccr\u003e\n```\n\nThe .go_to_top_node_and_execute_commands() method takes 2 arguments:\n\n1. boolean: if false then it will jump to the beginning of the node, if true it jumps to the end.\n\n1. lua table: a table that contains strings, each string is a vim command example: { \"normal! O\", \"normal! O\", \"startinsert\" }\n\n---\n\n# Version 2.0 Beta Update\n\n### Targeted Jump with Virtual Text\n\nhttps://user-images.githubusercontent.com/102876811/169820839-5ec66bd9-bf14-49f6-8e5a-3078b8ec43c4.mp4\n\n### Filtered Jump through user-defined node types\n\nhttps://user-images.githubusercontent.com/102876811/169820922-b1eefa5e-6ed9-4ebd-95d1-f3f35e0388da.mp4\n\n### These are experimental features and I wish to expand them even further. If you have any suggestions, please feel free to let me know 😊\n\nExample mappings for Version 2.0 Beta functionalities:\n\n```lua\n-- Syntax Tree Surfer V2 Mappings\n-- Targeted Jump with virtual_text\nlocal sts = require(\"syntax-tree-surfer\")\nvim.keymap.set(\"n\", \"gv\", function() -- only jump to variable_declarations\n\tsts.targeted_jump({ \"variable_declaration\" })\nend, opts)\nvim.keymap.set(\"n\", \"gfu\", function() -- only jump to functions\n\tsts.targeted_jump({ \"function\", \"arrrow_function\", \"function_definition\" })\n  --\u003e In this example, the Lua language schema uses \"function\",\n  --  when the Python language uses \"function_definition\"\n  --  we include both, so this keymap will work on both languages\nend, opts)\nvim.keymap.set(\"n\", \"gif\", function() -- only jump to if_statements\n\tsts.targeted_jump({ \"if_statement\" })\nend, opts)\nvim.keymap.set(\"n\", \"gfo\", function() -- only jump to for_statements\n\tsts.targeted_jump({ \"for_statement\" })\nend, opts)\nvim.keymap.set(\"n\", \"gj\", function() -- jump to all that you specify\n\tsts.targeted_jump({\n\t\t\"function\",\n\t  \"if_statement\",\n\t\t\"else_clause\",\n\t\t\"else_statement\",\n\t\t\"elseif_statement\",\n\t\t\"for_statement\",\n\t\t\"while_statement\",\n\t\t\"switch_statement\",\n\t})\nend, opts)\n\n-------------------------------\n-- filtered_jump --\n-- \"default\" means that you jump to the default_desired_types or your lastest jump types\nvim.keymap.set(\"n\", \"\u003cA-n\u003e\", function()\n\tsts.filtered_jump(\"default\", true) --\u003e true means jump forward\nend, opts)\nvim.keymap.set(\"n\", \"\u003cA-p\u003e\", function()\n\tsts.filtered_jump(\"default\", false) --\u003e false means jump backwards\nend, opts)\n\n-- non-default jump --\u003e custom desired_types\nvim.keymap.set(\"n\", \"your_keymap\", function()\n\tsts.filtered_jump({\n\t\t\"if_statement\",\n\t\t\"else_clause\",\n\t\t\"else_statement\",\n\t}, true) --\u003e true means jump forward\nend, opts)\nvim.keymap.set(\"n\", \"your_keymap\", function()\n\tsts.filtered_jump({\n\t\t\"if_statement\",\n\t\t\"else_clause\",\n\t\t\"else_statement\",\n\t}, false) --\u003e false means jump backwards\nend, opts)\n\n-------------------------------\n-- jump with limited targets --\n-- jump to sibling nodes only\nvim.keymap.set(\"n\", \"-\", function()\n\tsts.filtered_jump({\n\t\t\"if_statement\",\n\t\t\"else_clause\",\n\t\t\"else_statement\",\n\t}, false, { destination = \"siblings\" })\nend, opts)\nvim.keymap.set(\"n\", \"=\", function()\n\tsts.filtered_jump({ \"if_statement\", \"else_clause\", \"else_statement\" }, true, { destination = \"siblings\" })\nend, opts)\n\n-- jump to parent or child nodes only\nvim.keymap.set(\"n\", \"_\", function()\n\tsts.filtered_jump({\n\t\t\"if_statement\",\n\t\t\"else_clause\",\n\t\t\"else_statement\",\n\t}, false, { destination = \"parent\" })\nend, opts)\nvim.keymap.set(\"n\", \"+\", function()\n\tsts.filtered_jump({\n\t\t\"if_statement\",\n\t\t\"else_clause\",\n\t\t\"else_statement\",\n\t}, true, { destination = \"children\" })\nend, opts)\n\n-- Setup Function example:\n-- These are the default options:\nrequire(\"syntax-tree-surfer\").setup({\n\thighlight_group = \"STS_highlight\",\n\tdisable_no_instance_found_report = false,\n\tdefault_desired_types = {\n\t\t\"function\",\n\t\t\"arrow_function\",\n\t\t\"function_definition\",\n\t\t\"if_statement\",\n\t\t\"else_clause\",\n\t\t\"else_statement\",\n\t\t\"elseif_statement\",\n\t\t\"for_statement\",\n\t\t\"while_statement\",\n\t\t\"switch_statement\",\n\t},\n\tleft_hand_side = \"fdsawervcxqtzb\",\n\tright_hand_side = \"jkl;oiu.,mpy/n\",\n\ticon_dictionary = {\n\t\t[\"if_statement\"] = \"\",\n\t\t[\"else_clause\"] = \"\",\n\t\t[\"else_statement\"] = \"\",\n\t\t[\"elseif_statement\"] = \"\",\n\t\t[\"for_statement\"] = \"ﭜ\",\n\t\t[\"while_statement\"] = \"ﯩ\",\n\t\t[\"switch_statement\"] = \"ﳟ\",\n\t\t[\"function\"] = \"\",\n\t\t[\"function_definition\"] = \"\",\n\t\t[\"variable_declaration\"] = \"\",\n\t},\n})\n```\n\n### Because every languages have different schemas and node-types, you can check the node-types that you're interested in with https://github.com/nvim-treesitter/playground\n\n#### You can also do a quick check using the command :STSPrintNodesAtCursor\n\n\n# Version 2.2 Update\n\n### Hold and swap nodes\nhttps://user-images.githubusercontent.com/8104435/225992362-4e82d677-2ff5-463a-a910-6a6bdbf4fc9c.mp4\n\nThis feature allows marking a node and then swapping it with another node.\n\nExample mapping:\n\n```lua\n-- Holds a node, or swaps the held node\nvim.keymap.set(\"n\", \"gnh\", \"\u003ccmd\u003eSTSSwapOrHold\u003ccr\u003e\", opts)\n-- Same for visual\nvim.keymap.set(\"x\", \"gnh\", \"\u003ccmd\u003eSTSSwapOrHoldVisual\u003ccr\u003e\", opts)\n```\n\nThe lower-level functionality can be accessed via:\n```lua\nrequire(\"syntax-tree-surfer\").hold_or_swap(true) -- param is_visual boolean\nrequire(\"syntax-tree-surfer\").clear_held_node()\n```\nnote that `STSSwapOrHoldVisual` will clear the visual selection, but `hold_or_swap(true)` will not.\n\n# Special Thanks To:\n### Dr. David A. Kunz for creating [Let's create a Neovim plugin using Treesitter and Lua](https://www.youtube.com/watch?v=dPQfsASHNkg)\n### NVIM Treesitter Team - https://github.com/nvim-treesitter/nvim-treesitter\n### @lmburns for [#9](https://github.com/ziontee113/syntax-tree-surfer/pull/9)\n### @spiderforrest for [#14](https://github.com/ziontee113/syntax-tree-surfer/pull/14)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fziontee113%2Fsyntax-tree-surfer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fziontee113%2Fsyntax-tree-surfer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fziontee113%2Fsyntax-tree-surfer/lists"}