While waiting for Add Snippets to Script Editor wish to be completed, I quickly wrote an add-in so I can have at least some sort of snippets while scripting in Script Editor. Add-in was put together fairly fast and it does still have bugs and issues (especially with focusing different elements in the UI). There might be changes to this add-in which will break the functionality of current snippets and/or their locations.
What is a Snippet? Snippet is a programming term for a small region of re-usable source code, machine code, or text (wikipedia, Snippet_(programming)). Snippets allow you to quickly insert re-usable code blocks to your code. This will save you time and reduce mistakes you could have if you were to manually type the snippet.
Add-in has been built with Add-In Manager, requires at minimum JMP16 and does support Windows (might work on OSX, but I cannot test that and supported host has been set as Win in add-in manager).
Download the add-in from this page and install as you would normally install JMP Add-Ins (double click). The add-in will (by default) use shortcut keybind Ctrl+Shift+Space . When the add-in first time run it will create folder to users $DOCUMENTS called jmp_script_editor_snippets which user can use to store custom snippets (full path is something like C:\Users\<USERNAME>\Documents\jmp_script_editor_snippets\). The snippet files are basically just .jsl files which are found from the add-ins' snippet folder or from user's documents snippet folder.
Write #snippet <optional search term> (optionally user can use #sni or #snip instead of writing the whole #snippet) into your script editor. #snippet is used as a lookup value and if you include optional search terms, those will be used to pre-fill the search bar. After you have #snippet in your code, press Ctrl+Shift+Space to launch JMP Script Editor Snippet window, search for correct snippet and press OK (you can sometimes also just press Enter / use Tab to get to Enter). #snippet line will be replaced with the snippet you selected. Below is image of the snippet window
Snippet window
If user runs the add-in and there is no #snippet found from the script box, nothing will happen. If you don't want to insert snippet, press Esc. If you by accident insert snippet, you can try to press Ctrl+Z to undo the change.
User can access this community page for help and open snippet folder from the add-in menu
Names of these snippets are kept short on purpose, so user can easily write the whole name as <optional search term> after #snippet. Using snippets this way allows user to immediately pressing enter to use the wanted snippet.
new_bg
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
new_bg_gb
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Variables(X(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(9)), Line Of Fit(X, Y, Legend(11)))
);
if
If(condition1,
//code1
, //else
//code2
);
elif
If(condition1,
//code1
, //condition2,
//code2
, //else
//code3
);
func
function1 = function({param1, param2, param3 = .}, {Default Local},
/*"""function1 which returns missing.
More description regarding the function
Args:
param1 (displaybox):
param2 (char):
param3 (num):
Returns:
num: missing
Raises:
exception_msg
"""*/
return(.);
);
new
/*"""One sentence description for this script
Author:
Creation Date:
Creation JMP Version:
Description:
Todo:
*
*
"""*/
Names Default To Here(1);
nw
nw = New Window("name",
V List Box(align("Center"),
)
, << Set Window Icon("JMP")
);
modal
nw = New Window("Modal Window", << modal, << return result,
H List Box(
Panel Box("Options",
lb = List Box({})
),
Panel Box("Actions",
Lineup Box(N Col(1),
Button Box("OK"),
Button Box("Cancel")
)
)
)
, << Set Window Icon("Warning")
);
If(nw["Button"] != 1,
Throw("Cancelled");
);
sql
dsn_string = "";
sql_template = "\[
select 1
from dual
]\";
dbc = Create Database Connection(dsn_string);
sql = Eval Insert(sql_template, "¤"); // use ¤ to avoid issues with regex when using ^
dt = Execute SQL(dbc, sql, "NewTable");
Close Database Connection(dbc);
try
Try(
Show(a);
, // Catch
show(exception_msg);
);
I also added community_template.jsl stored to my $DOCUMENTS snippet folder, which I use to store my scripting solutions from JMP Community
/*"""
author: jthi
date: YYYY-MM-DD
url: https://community.jmp.com/t5/Discussions/
keywords/tags: []
"""*/
Names Default To Here(1);
In this simple example I will create new script. The script will have one function which will perform an SQL query and then return the result table.
First I will start a new .jsl script file. I will start by writing
#snippet new
next I will run the add-in to replace that snippet. Because I have pre-written the whole snippet name to the #snippet line it will be pre-selected for me
and I can just press enter immediately after opening the add-in to use that snippet.
Next I will add a new function with func snippet
#snippet func
and then inside that I will add sql snippet
#snippet sql
My current code looks like this:
/*"""This Add-In provides Snippet functionality to JMP Script Editor.
Author:
Creation Date:
Creation JMP Version:
Description:
Todo:
*
*
"""*/
Names Default To Here(1);
function1 = function({param1, param2, param3 = .}, {Default Local},
/*"""function1 which returns missing.
More description regarding the function
Args:
param1 (displaybox):
param2 (char):
param3 (num):
Returns:
num: missing
Raises:
exception_msg
"""*/
sql_template = "\[
select 1
from dual
]\";
dbc = Create Database Connection(dsnstring);
sql = Eval Insert(sql_template, "¤"); // use ¤ to avoid issues with regex when using ^
dt = Execute SQL(dbc, sql, "NewTable");
Close Database Connection(dbc);
return(.);
);
I will clean it up by adding indentation inside the function and fill out the documentation strings and finally my script will look like this:
/*"""Example on the usage of JMP Script Editor Snippets
Author: jthi
Creation Date: 2022-12-19
Creation JMP Version: JMP Pro 16
"""*/
Names Default To Here(1);
get_data = function({duration = 1}, {Default Local},
/*"""Function to query data from sql
Args:
duration (num): days to query
Returns:
datatable: queried data table
"""*/
dsn_string = "DSN=dBASE Files;DBQ=C:/Program Files/SAS/JMPPRO/16/Samples/Import Data/;"
sql_template = "\[
select *
from tables
where
data > sysdate - ¤duration¤
]\";
dbc = Create Database Connection(dsn_string);
sql = Eval Insert(sql_template, "¤");
dt = Execute SQL(dbc, sql, "Query Result");
Close Database Connection(dbc);
return(dt);
);
Below is short video of the add-in usage with based on the example abow
Version 2.0 (20 December 2022)
Version 2.0.1 (22 December 2022)
Cool.
@jthi , thanks a lot for this Add-In. This can help a lot.
You could add a button to open the C:\Users\<USERNAME>\Documents\jmp_script_editor_snippets\ folder.
@jthi wrote:
- Possibility to append snippets to end of script window without the requirement of #snippet
... or at the current cursor position?
You could place a #snippet just there it the Add-In doesn't find it somewhere else in the code.
But good that it's just #snippet and not
#this is the place where my snippet should go to
perhaps: allow # snippet (with space) as well to make the functionality more robust against user "errors".
I'm not sure I can access user's cursor position in Scripting Box directly with JSL. I can do workarounds with powershell and windows dll but I won't (most likely) do those for this add-in as it is working well enough for me with the usage of keywords.
For some reason when I use this add-in, it does not create the user snippet directory. I looked through the code and although I see the function that will do this, the function is not called?
Function run_snippet_selector calls init_documents_path which should create the folder. And the run_snippet_selector function is basically the script the add-in runs. user_snippet_path variable is defined in the configuration file jses_config.jsl and by default seems to be
user_snippet_path = "$DOCUMENTS/jmp_script_editor_snippets/";
You should also be able to open it from the add-in menu
But it has been a long time when I made last updates to this, so there could be some changes I haven't published to community or just something which doesn't work as intended (has worked for me for a long time though). For example I have one "custom" snippet called "community_template"
and I think it is being loaded correctly