diff --git a/docs/API/knut/ribbon.md b/docs/API/knut/ribbon.md index 9dac0eda..fb885d60 100644 --- a/docs/API/knut/ribbon.md +++ b/docs/API/knut/ribbon.md @@ -15,6 +15,12 @@ import Knut |string|**[id](#id)**| |[RibbonMenu](../knut/ribbonmenu.md)|**[menu](#menu)**| +## Methods + +| | Name | +|-|-| +|[RibbonElement](../knut/ribbonelement.md) |**[elementFromId](#elementFromId)**(string id)| + ## Detailed Description A ribbon is made of multiple items: @@ -43,3 +49,9 @@ This property holds the id of the ribbon. #### [RibbonMenu](../knut/ribbonmenu.md) **menu** This property holds the menu of the ribbon. + +## Method Documentation + +#### [RibbonElement](../knut/ribbonelement.md) **elementFromId**(string id) + +This method returns RibbonElement from identifier `id`. diff --git a/docs/getting-started/gui-treesitter-inspector.png b/docs/getting-started/gui-treesitter-inspector.png new file mode 100644 index 00000000..2a7352e5 Binary files /dev/null and b/docs/getting-started/gui-treesitter-inspector.png differ diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md index 8fa53c5c..94ef0804 100644 --- a/docs/getting-started/overview.md +++ b/docs/getting-started/overview.md @@ -2,11 +2,16 @@ ## General overview -Knut allows to automate some code modifications on a codebase. This allows applying some modification on multiple files at once, for example the source and header files in a C++ project. +Knut is built to automate code modifications on a codebase. +For many repetitive tasks, Knut aims to automate around 90% of the work, with a bit of fix-up required afterwards. +Knut achieves this by providing high-level APIs to access and modify your code base, which can easily be scripted with JavaScript to run arbitrary transformations. +It is even possible to apply modifications on multiple files at once, for example the source and header files in a C++ project. -When running knut, the first thing is to open a project, a project being just the root directory for the codebase. Once a project is open, knut can open one or multiple files inside the project, and run transformations on those files. Transformations are defined in script files (see [writing scripts](script.md)). +When running Knut, the first thing is to open a project, which is just the root directory for the codebase. +Once a project is open, Knut can open one or multiple files inside the project, and run transformations on those files. +Transformations are defined in script files (see [writing scripts](script.md)). -Each file open provides different API usable by the scripts, depending on the type of file: +Each open file provides different API usable by the scripts, depending on the type of file: - a text file has find/replace/navigation APIs (and more...) - a C++ file adds block navigation, switch header/source or declaration/definition... @@ -19,25 +24,26 @@ Each file open provides different API usable by the scripts, depending on the ty ### Setup -To run scripts you need to set it up accordingly: +To run scripts you need to set Knut up accordingly: -- start the knut user interface and go to `File`>`Options...` +- start the Knut user interface and go to `File`>`Options...` - or start directly the settings dialog via the command line: `knut` --gui-setting` -This will display a dialog with the script knut general settings. +This will display a dialog with the script Knut general settings. ![Knut settings](overview-settings.png) -You need at least one script directory. +You need at least one script path. +Script paths contain .js or .qml files that can be run by Knut (see [writing scripts](script.md)). ### Running -Once done, you can run any scripts: +Once done, you can run a script inside your script paths: - from the command line: - ``` knut --run ``` + - from the user interface, using the `Script`>`Run Script...` menu ## Settings @@ -49,7 +55,7 @@ Knut has 3 levels of settings: - project settings: stored in `/knut.json` Settings can be overridden, project settings have priority over user settings over internal settings. When a project is loaded, settings are saved in the project settings, otherwise in the user settings. -Script paths are merged between the user and project settings, allowing for some general scripts, and project-specific scripts. +Script paths are merged between the user and project settings, which allows accessing both general scripts, and project-specific scripts. Some settings (like Text Editor Behavior) are only per project. diff --git a/docs/getting-started/script.md b/docs/getting-started/script.md index 3f9f53fa..267142ea 100644 --- a/docs/getting-started/script.md +++ b/docs/getting-started/script.md @@ -11,13 +11,17 @@ If the first line is a comment, it will be used as the script description. !!! Note "" If you need to know more about QML, follow this link: [https://doc.qt.io/qt-6/qmlapplications.html](https://doc.qt.io/qt-6/qmlapplications.html) +Both Javascript and QML scripts use the same API, see the [Knut API reference](../API/knut/document.md). + +For more advanced use cases, take a look at: [Syntax tree queries using Tree-sitter](./treesitter.md) + ## Javascript script Javascript scripts **must** contain a main function, the entry point for the script: ```js // Script description -function main { +function main() { message.log("Hello World!") } ``` @@ -68,6 +72,9 @@ ScriptDialog { The `QLineEdit` (named `lineEdit`) in the ui file is accessed both in reading and writing via `data.lineEdit`. +Note that the `init()` function in the root item (visual or not) will automatically be called at startup. +In a visual script, the `init()` function usually should not start the code transformation, but should wait for the dialog to be accepted, or a button to be clicked, etc. + ### Supported widgets Here is the list of supported widgets for your dialogs, and how to access them from the QML script. diff --git a/docs/getting-started/treesitter.md b/docs/getting-started/treesitter.md index fd583fec..006a4bac 100644 --- a/docs/getting-started/treesitter.md +++ b/docs/getting-started/treesitter.md @@ -15,45 +15,56 @@ From the [Tree-sitter website][treesitter]: ## Tree-sitter in Knut -Current support in user scripts is limited to: +Knut exposes Tree-sitter via high-level APIs that allow: - Inspecting the concrete syntax tree generated by Tree-sitter using the "Tree-sitter Inspector". - Running [Tree-sitter Queries][queries] -- Only available on C/C++ files -However, this already allows for some very easy & powerful analysis and modification of C++ source files. +While this doesn't give access to all of the details exposed by Tree-sitter, this already allows for some very easy & powerful analysis and modification of code files. -Knut also returns Tree-sitter query results in some of its high-level methods. +Knut also returns Tree-sitter query results in many of its high-level methods. Usually in the form of the [QueryMatch][querymatch] class. See the [QueryMatch documentation][querymatch] for more details of how to use this class. -Compared to the language server, Tree-sitter is a lot more resistant to errors and works well, even if the current code would not compile. +Compared to a language server, Tree-sitter is a lot more resistant to errors and works well, even if the current code would not compile. For this reason many Knut functions internally rely on Tree-sitter instead of the language server. This may result in false-positives though, as Tree-sitter only works on a syntax level and doesn't understand the high-level structures of the code. Tree-sitter will especially struggle if symbols are overloaded, as all references may be picked up. -## Writing Tree-sitter queries +## Viewing the Tree-sitter state -Tree-sitter queries are a powerful tool, as the syntax tree parsed by Tree-sitter makes it easy to find functions, class definitions, etc. -For the exhaustive specification of the query syntax, see the [Tree-sitter website][queries]. +Familiarizing yourself with Tree-sitters state is the first step to writing your own queries. +Knut includes the `Tree-sitter Inspector`, which displays the concrete syntax tree (CST) generated by Tree-sitter. -Knut supports prototyping queries with the `Tree-sitter Inspector`, which can be accessed in the Knut GUI under the `C++` menu. +To open it, click `Code`>`Tree-sitter Inspector`. -The Tree-sitter Inspector allows you to inspect the syntax tree of the current file. -Note that this does not include anonymous nodes (e.g. any symbols like -> * + - / ). -These are still in the syntax tree and can be queried. -For details, see the [query documentation][queries]. +![Knut's Tree-sitter Inspector](./gui-treesitter-inspector.png) + +The `Tree-sitter Inspector` displays the CST on the left. As the syntax tree can become large very quickly, the Inspector provides a bi-directional mapping to the edited file. 1. Clicking any node in the inspector will select the corresponding text in the document 2. Any node that includes the cursor position is highlighted in green. -Additionally, you can test your queries in the bottom-left input field. +> Also note the `Show unnamed nodes` option in the bottom. +> The Tree-sitter CST is highly detailed and includes a lot of individual characters/keywords +> A lot of these nodes are hidden by default and won't be relevant for many queries. +> For the cases where these nodes may be relevant, the checkbox makes them visible. + +On the right side, you can prototype a [Tree-sitter query](queries), the results of which will immediately be displayed at the bottom and in the CST. The Tree-sitter Inspector will notify you of errors in your query and display the number of patterns, matches and captures as you type. Any captured nodes will also display their captures in the syntax tree view. +> ⚠️ Because the query runs immediately, testing complex queries on large files can cause Knut to freeze when typing. +> If this is the case, extracting the relevant code into a smaller file can be a good remedy. + +## Writing Tree-sitter queries + +Tree-sitter queries are a powerful tool, as the syntax tree parsed by Tree-sitter makes it easy to find functions, class definitions, etc. +For the exhaustive specification of the query syntax, see the [Tree-sitter website][queries]. + After prototyping a query, it can easily be included in a script by calling [`query`][codedocument-query] on any LSP capable document (e.g. C/C++). Together with Javascripts [Destructuring Assignment][destructuring] and [Template Literals][template-literals] this makes queries very ergonomic to use in your own scripts. @@ -85,8 +96,8 @@ if (!constructor) { let old_body = constructor.get("body").text; // Modify a capture -constructor.get("body").replace("body").replace(`{ - std::log << "${className} Constructor" << std::endl; +constructor.get("body").replace(`{ + std::cout << "${className} Constructor" << std::endl; }`); // Or remove it outright @@ -176,6 +187,8 @@ E.g.: To check that the type of a parameter is `const std::string &`, you can si (#eq_except? "const std::string &" @param "identifier")))) ``` +Note that for this exact use-case, using `#like_except?` would be a better fit, to match `const std::string&`, as well as `const std::string &`. + ### `(like_except? [pattern] [capture] [exclusion]+)` Check if the pattern and capture are "alike", excluding any (sub-)nodes that have a type listed in `exclusion`.