cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar

Hyperlinks for Function and Expression calls in the script editor

In the script editor, would it be possible to make all calls of user-defined functions or expressions be hyperlinks?  For instance, I would like to be able to click on an instance of "myfunc" somewhere in my script, and have the editor immediately take me to the location in the script where myfunc is defined.  And of course, I'd like to have a "back" button as well to take me back to where I was initially in the script.  Same goes for expressions.

5 Comments
gzmorgan0
Super User (Alumni)

This is an FYI of what I use today:

  • highlight the text and press Ctrl+F or Edit>Search>Find and press Find, or 
  • the script below. It is a pre-cursor script from a JMP developer. He might have an updated version, I did not see it in the list of shared files and add-ins. I did not post his name, but will check if he has an updated version.  When run, this script creates a display of all currently open JSL scripts and lists the line number of the functions. Double clicking will take you there.
/*
	Author:  xxxxxx xxxxxxx
	
	Copyright (c) 2016 by SAS Institute Inc., Cary, NC 27513, USA. All rights reserved.
*/

Names Default To Here( 1 );

getRoots = Function({searchCriteria=""},
	wins = Window();

	roots = {};
	For( iWin = 1, iWin <= N Items( wins ), iWin++, 
		
		If( (wins[iWin] << window class name) == "Script",
			tmpNode = Tree Node( wins[iWin] << Get Window Title );
			tmpNode << Set Data( wins[iWin] );
			tmpNode << Set Icon( "ScriptFile" );
			
			If( searchCriteria != "",
				If( !Contains( wins[iWin][Script Box( 1 )] << get text, searchCriteria ), Continue() )
			);
			
			lines = wins[iWin][Script Box( 1 )] << Get Lines();
			
			For( iLine = 1, iLine <= N Items( lines ), iLine++,
				fName = Regex( lines[iLine], "([a-z\d_\s]+)[\s]*=\s*function\s*\(", "\1", IGNORECASE );
				/* ()      collect everything that matches this pattern [a-z alphabetical, \d digit, _ underscore, \s white space]
				    +      one or many, so there must be at least one of these items
				   [\s]*   this is white space, but * says 0 or many 
				   =       must occur, that is, it is a part of the pattern
				  function must occur
				  \s*      0 or many instances of white space ( tab, space, new line)
				  (        left parentheses is part of the pattern
				  If the pattern is found, \1 states to return the collection, that is the function name
				*/
				//"([a-z\d_=\s]+)[\s]*<<\s*xpath\s*\(", "\1", IGNORECASE );
				
				If( !Is Missing( fName ),
					tmpChildNode = Tree Node( Trim( fName ) || ":  " || Char( iLine ) );
					tmpChildNode << Set Data( iLine );
					tmpChildNode << Set Icon( "FunctionIndex" );
					tmpNode << Append( tmpChildNode );
				);
			);
			
			Insert Into( roots, tmpNode );
		)
	);
	Return(roots);
);

roots = getRoots();

goToLine = Function( {sb, lineNum},
	sb << Set Line text( lineNum, sb << get line text(lineNum) );
);

nw = New Window( "JSL Function Manager",
	H List Box(
		Button Box("",<<Set Icon("WinBrowserRefresh"), <<Set Function( tree << set roots( getRoots() ) ) ),
		Text Edit BOx( "",
			<<Set Width( 200 ),
			<<Set Text Changed(
				Function( {this, value},
					tree << set roots( getRoots( value ) )
				)
			)
		),
		Button Box( "", <<Set Icon( "WinHelpSearch" ) )
	),
	tree = Tree Box(
		roots,
		Size( 300, 600 ),
		<<Set Node Double CLick Script(
			Function( {tree, node},
				If( (tree << is root( node )),
					(node << get data) << bring window to front,
					win = (node << parent()) << get data;
					goToLine( win[ScriptBox(1)], node << get data );
					win << bring window to front();
				)
			)
		),
		<<set auto stretching( 1, 1 ),
		<<set min size( 5, 20 ),
		<<set max size( 100000, 10000 )
	)
);

 

Hi @gzmorgan0 and @nikles, I just published an updated version of the above script as the JSL Function List add-in. Check it out and let me know if you have any questions.

ih
Super User (Alumni)
Super User (Alumni)

Highlighting a user-defined function and pressing a function key to go to the definition would be handy.

Status changed to: Acknowledged

Hi @nikles, thank you for your suggestion! We have captured your request and will take it under consideration.

nikles
Level VI

Hi.  Hope it's not too late to do so, but I just wanted add more to my original wish list items: 

1. (already mentioned above) Double clicking on a user function or expression will take the user to the definition in the script.

2. (already mentioned above) A "Prev" button to return the user to the original location in the script.

3. (New) Single clicking on a user function, expression, or variable will automatically highlight all instances of that item in the script.

4. (New) A "Next" button.  Say if the user has double clicked on function A, then B, then C, and then presses "Prev" to return to function B, the "Next" button would take them back to function C.  

5. (New) If the script window has been split in two (e.g. right/left), I would like the above features to operate on whichever split is currently active, as opposed to always only the left side split.

6. (New) A drop-down in the script window showing all the user functions and expressions.  Selecting one will take the user to that item in the script.

Hope these make sense, and are reasonable.  Thanks!