Skip to content
63 changes: 28 additions & 35 deletions sindarin/extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Failing to do such encapsulation will trigger an update of the debugger presente
execute
1 | sindarin |
2 sindarin := self context sindarinDebugger.
3 self context debuggerActionModel preventUpdatesDuring: [
3 self context debuggerClientModel preventUpdatesDuring: [
4 sindarin stepUntil: [ sindarin selector = #parseObject ] ]
```

Expand Down Expand Up @@ -169,7 +169,7 @@ We have to adapt a bit the `execute` method to use the target operation instead
execute
| sindarin |
sindarin := self context sindarinDebugger.
self context debuggerActionModel preventUpdatesDuring: [
self context debuggerClientModel preventUpdatesDuring: [
sindarin stepUntil: [ sindarin selector = targetParsingMethod asSymbol ] ]
```
We now need to extend the debugger and its toolbar.
Expand Down Expand Up @@ -228,95 +228,88 @@ Our new menu is now available in newly opened debuggers (fig. *@fig:new-menu@*)!

### Saving and loading scripts

Until now, we have written severeal scripts. However, these scripts disappear when the debugger is closed. While it is
Until now, we have written several scripts. However, these scripts disappear when the debugger is closed. While it is
possible to preserve a script by turning it into a command, this process can be complex for quick or temporary scripts.

To solve this problem, we introduce the concept of scripts repositories, allowing users to save their scripts outside of the debugger session and load them later when needed.
To solve this problem, we introduce the concept of script repositories, allowing users to save their scripts outside of the debugger session and load them later when needed.

We continue with our example. Previously, we wrote the following script:
```Smalltalk
sindarin stepUntil: [ sindarin selector = #parseObject ]
```
Now that our scripts is written we can save it for future use.
Now that our script is written we can save it for future use.

First, we should give it a meaningfull name.
First, we should give it a meaningful name.
![Renaming the script to 'Step Until #parseObject'](graphics/sindarin-rename-parseObject.png)

Then simply click the save button and voilà, your scripts is saved and will persist beyond the current debugger session.
Then simply click the *save* button and your script is saved and will persist beyond the current debugger session.

Why stop at just one script ? Let's create another one by simply changing your script to:
```Smalltalk
sindarin stepUntil: [ sindarin selector = #parseValue ]
```
As with the first script, give it a name and click the save button.
As with the first script, give it a name and click the *save* button.
![Renaming the script to 'Step Until #parseValue'](graphics/sindarin-rename-parseValue.png)

The purpose of saving a script is to be able to retrieve it later and now is the time. Let's say we want to bring back 'Step Until #parseObject'.
The purpose of saving a script is to be able to retrieve it later and now is the time. Let's say we want to bring back `Step Until #parseObject`.

To do so, click the Load a script button. the layout should change to:
To do so, click the *Load a script* button. the layout should change to:
![The load script layout](graphics/sindarin-load-script-layout.png)

here, you can see all your saved scripts. Select 'Step Until #parseObject', then click on Load. And just like that your scripts is back !
Here, you can see all your saved scripts. Select `Step Until #parseObject`, then click on `Load`. And just like that your script is back !

### Automatically transforming scripts into debugger commands

Previously we learned how to turn a script to a command. We had to manually extend the debugger and its toolbar and create our SindarinCommand subclasse. Theses steps are not easy and can be redundant especially if you wish to have several commands.
Previously we learned how into turn a script to a command. We had to manually extend the debugger and its toolbar and create our `SindarinCommand` subclass. These steps are not easy and can be redundant especially if you wish to have several commands.

Fortunately transforming a script to a debugger command make this process for you !
Fortunately transforming a script to a debugger command makes this process for you !

First, load or write your script and then click the "Create a command from the current debugging scripts" button:
First, load or write your script and then click the *Create a command from the current debugging scripts* button:
![The create a command from scripts button](graphics/sindarin-create-command-button.png)
The layout should change to:
![The create command layout](graphics/sindarin-create-command-layout.png)

The script name is used to generate the command name.
You can give your command a description and select an icon (from the pharo icon list) before clicking 'Create'.
You can give your command a description and select an icon (from the Pharo icon list) before clicking `Create`.

Restart your debuggeur to update the menus lists and theirs commands (By default your command is created in the "Scripts" menu) now you should see your command menu with yout command in it !
Restart your debugger to update the menu lists and their commands (By default your command is created in the `Scripts` menu). You should see your command menu with your command in it !
![Your command in the Debugger toolbar](graphics/sindarin-command-in-scripts-menu-toolbar.png)

If you wish to find the generated code go to the package 'NewTools-Sindarin-Tools' (it's the default location):
- In tag 'Scripts' you can find your command
If you need to find the generated code go to the package `NewTools-Sindarin-Tools` (it's the default location):
- In tag `Scripts` you can find your command
![Your generated command class](graphics/sindarin-generated-command.png)
- In the tag 'Extensions', in StDebugger class side you can find the method to 'buildSindarin...ExtensionCommandsGroupWith: forRoot' that add your menu:
- In the tag `Extensions`, in StDebugger class side you can find the method to `buildSindarin...ExtensionCommandsGroupWith: forRoot` that adds your menu:
![Your generated command group](graphics/sindarin-build-extension-generated.png)

If you wish to remove a command from your group, load it from the script loader and delete it by pressing the "x" button. The generated code is deleted.
If you wish to remove a command from your group, load it from the script loader and delete it by pressing the *x* button. The generated code is also deleted.

### Build your own scripting library and make it available to the community

For now every commands you create are display in the 'Scripts' group. You may be working on domain specific scripts and wish to have them in a specific group, like previously with the STON group.
For now, every command you create are displayed in the `Scripts` group. You may be working on domain-specific scripts and wish to have them in a specific group, like previously with the STON group.

In the package you want to save your commands, create a class wich extend StSindarinDebuggerScriptRepository
In the package you want to save your commands, create a class which extends `StSindarinDebuggerScriptRepository`
```Smalltalk
StSindarinDebuggerScriptRepositoryAbstract << #MySindarinCommandsMenu
slots: {};
package: 'my-sindarin-commands'
```

Go to class side and implement repositoryName accessor
Go to class side and implement the required `repositoryName` accessor
``` Smalltalk
repositoryName
^ 'My Scripting Library'
```

Now in the debuggeur, click on the drop list next to the remove command, you should see your new Scripting Library.
Select it and every scripts and commands saved and created will be in your library.
Now in the debugger, click on the drop list next to the remove command, you should see your scripting library.
Select it and every script and command saved and created will be stored in your library.

Once you generate a command fron a script, your package become the corresponding class location.
Once you generate a command from a script, your package becomes the corresponding class location.
``` Smalltalk
SindarinCommand << #SindarinMyScriptingLibraryLastUpdatedCommand
slots: {};
package: 'my-sindarin-commands'
```

If you wish to share your library to the community, other only need your package. You can save it in a git repository and give acces to your code.
Because your package contains your commands, your scripts repository and the `StDebugger` extension to build your menu. Sharing your library is like sharing any other Pharo package. You just need the target image to load your package.

### How to load a scripting library

For this part we assume that the library is in a github repository.

Open the git repository browser "ctrl + oi", click 'Add a repository', enter the git repository credentials.
Load the Pharo repository in your image and just like the scriptings library is usable in the debuger.

Note that only commands are shared, unlike scripts.
*Note* : only commands are shared, scripts stay in your Pharo image.
Loading