Brett Saviano · Mar 27, 2025 go to post

These new UIs are available in all IRIS-based products, including containers and the Community edition.

Brett Saviano · Mar 27, 2025 go to post

The regex Route is the correct way to do this:

Class User.REST Extends%CSP.REST
{

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
  <Route Url="/(.*)" Method="GET" Call="test" />
</Routes>
}

ClassMethod test(path As%String) As%Status
{
    Set%response.ContentType = ..#CONTENTTYPETEXT
    Write path
    Return$$$OK
}

}
Brett Saviano · Mar 27, 2025 go to post

The two new apps (Production Configuration and DTL Editor) are opt-in at this time. You must open a Production or DTL in the old app, and then click the "Try the new UI" button to launch the new one. There is currently no way to set the new ones as a default like the Rule Editor since these are still in the early stages, but you can always bookmark them through your browser.

Brett Saviano · Mar 21, 2025 go to post

VS Code supports editing a class that extends Ens.DataTransformDTL the same as any other. That error message is reporting that the contents of the DTL XData block are invalid. Did you make your edit the right place?

Brett Saviano · Mar 18, 2025 go to post

The /api/monitor/alerts endpoint was created to allow for text-based alerts to be consumed by the now-discontinued System Alerting & Monitoring tool. It does not map to any concept related to Prometheus. For more information, see this documentation page.

Brett Saviano · Mar 18, 2025 go to post

Thanks for the detailed explanation Mat. It makes sense that you would want to turn off VS Code's syncing since you've already implemented it via git hooks. I will think about the best way to implement these settings and will let you know when I have a proposal.

Brett Saviano · Mar 18, 2025 go to post

Hi Michael, can you pleas explain what your git hooks are doing in more detail? If you don't want to share that publicly, feel free to send me a direct message.

Brett Saviano · Mar 18, 2025 go to post

Hi Michael, I am convinced that a change should be made here. I'm going to always enable the code that fills in the ROUTINE and Class headers when a new file is created, because that scaffolding is valuable even if the user has to edit the generated name. However, I will leave the code that modifies existing files when they are moved guarded by the objectscript.autoAdjustName setting, which will remain false by default.

Brett Saviano · Mar 12, 2025 go to post

Hi Michael, thanks for the feedback! The intention of that change was to not update the name of the document when you move it to another file location. However, it may be desirable for the extension to fill in the ROUTINE and Class headers, even if the generated name needs to be updated by the user.

Brett Saviano · Feb 13, 2025 go to post

Of the three options presented already, concatenating with $LISTBUILD() is by far the most performant. Running the following method

ClassMethod ListTest(l = 100000)
{
    #; Concatenate with $LISTBUILDSet li="",zh=$ZHOROLOGFor i=1:1:lSet li=li_$LISTBUILD(i)
    Write"Creating a list with length of ",$LISTLENGTH(li)," using $LISTBUILD() took ",$ZHOROLOG-zh," seconds",!
    #; Set $LISTSet li="",zh=$ZHOROLOGFor i=1:1:lSet$LIST(li,i)=i
    Write"Creating a list with length of ",$LISTLENGTH(li)," using $LIST() took ",$ZHOROLOG-zh," seconds",!
    #; $LISTUPDATESet li="",zh=$ZHOROLOGFor i=1:1:lSet li=$LISTUPDATE(li,i,i)
    Write"Creating a list with length of ",$LISTLENGTH(li)," using $LISTUPDATE took ",$ZHOROLOG-zh," seconds"
}

on a recent version of IRIS produces these results:

USER>d##class(User.Test).ListTest()
Creating a list with length of 100000 using $LISTBUILD() took .007244 seconds
Creating a list with length of 100000 using $LIST() took 10.156168 seconds
Creating a list with length of 100000 using $LISTUPDATE took 10.954107 seconds
Brett Saviano · Feb 6, 2025 go to post

The issue is that I forgot to add the E/e flag to the list of flags for the Color() method, so empty lines were removed from the JSON output. I will edit the accepted answer.

Brett Saviano · Feb 5, 2025 go to post

I'm glad you find this useful! Instead of looping through ^ROUTINE or ^rMAC to build the stream, you can open a %Routine object and pass that in as the first argument. That class implements the Stream interface. You can get a list of languages and attributes per language from a %SyntaxColor object using the Languages() and Attributes() methods.

Brett Saviano · Feb 5, 2025 go to post

@Anna.GolitsynaIf you goal is to find all globals referenced in a document, you can use a modified version of the code I included in this comment. The code uses the %SyntaxColor class to get a JSON array of semantic tokens for a document, and then loops through them looking for global references. Note that this will only find literal references, not naked references or indirection.

ClassMethod WriteAllGrefs()
{
    Set syn = ##class(%SyntaxColor).%New(), in = ##class(%Stream.TmpCharacter).%New(), out = ##class(%Stream.TmpCharacter).%New()
    #; TODO Put your document's contents into "in"Do syn.Color(in,out,"COS"/* or "INT" or "CLS" */,"KE"/* K means JSON output, E means keep empty lines */)
    #; Format of the JSON output:
    #; [
    #;     #; One array for each source line
    #;     [
    #;         {
    #;             #; Language of the token. See Languages() in %Library.SyntaxColor.
    #;             "l": %Integer,
    #;             #; Attribute of the token. See Attributes() in %Library.SyntaxColor.
    #;             "s": %Integer,
    #;             #; Zero-indexed start position of the token on the line
    #;             "p": %Integer,
    #;             #; Length of the token in characters
    #;             "c": %Integer
    #;         }
    #;     ]
    #; ]Set json = ##class(%DynamicArray).%FromJSON(out), lineIter = json.%GetIterator()
    While lineIter.%GetNext(.lineNum,.lineTokens) {
        Set tokensIter = lineTokens.%GetIterator()
        While tokensIter.%GetNext(,.token) {
            If (
                #; COS
                (token.l = 1) &&
                #; Global reference
                (token.s = 18)
            ) {
                Write"Gref starting in column ",token.p + 1," of line ",lineNum + 1,!
            }
        }
    }
}

You can combine this with the %Library.RoutineMgr_StudioOpenDialog query to make an index of all globals referenced in a subset of documents.

Brett Saviano · Jan 31, 2025 go to post

@Marc.MundtCan you post your workspace configuration (the .code-workspace file if you're using server-side editing)? Do you see any errors in the ObjectScript Output channel? Does the package only contain system or generated classes? By default those are not shown.

Brett Saviano · Jan 27, 2025 go to post

Thank you for testing the beta! I will attempt to reproduce your issues and will report back.

EDIT: Before I start testing, do you see any errors in the ObjectScript Output channel (besides EMFILE)? Also, the "auto-generating name" on creation of a new class/routine has been intentionally removed. This change divorces file importing from the export settings' folder structure, so it didn't make sense to keep using those settings to generate a file name.

EDIT 2: The "auto-generating name" feature is still in the extension, it's just off by default. To turn it back on, use the objectscript.autoAdjustName setting.

Brett Saviano · Jan 23, 2025 go to post

The Pull Request that implements these changes has been merged. GitHub beta releases starting with v2.12.11-beta.3 contain these changes, so there is no more need to use the special build of the extension found in the post.

Brett Saviano · Jan 21, 2025 go to post

Hi @Luc Morningstar, if VS Code is not meeting your needs then I would be happy to hear about how we can improve it. We take bug reports and feature requests via GitHub issues. Please see these docs on how to report issues from VS Code and which types of issues go to which extension. I would also like to note that VS Code will fail to save a class if its name differs from another class name only in case.

Brett Saviano · Jan 21, 2025 go to post

Hi @Olivier Caudron, The InterSystems VS Code extensions do support editing files on your local file system that are tracked by Git. The documentation for the extensions can be found here. Note that we have some major enhancements to this workflow coming in the next month or so, see this DC post for more info.

Brett Saviano · Jan 16, 2025 go to post

Hi @Daniele Monti, if there's no error message in the ObjectScript Output channel then you will need to capture a network trace. This will capture all REST traffic between VS Code and IRIS, so we can see the whole response to that request. I suggest you use wireshark or the Web Gateway's HTTP Trace tool. With the tool enabled, reproduce your issue. The turn the tool off and find the request that corresponds to that action. It will be a PUT on a URL like /api/atelier/v6/doc/UITXXPIEPAAdm.mac. The find the corresponding response. It should be a 40X or 500 response. Copy the entire body and post it here (hiding any sensitive information). That should tell us what the issue is.

Brett Saviano · Jan 13, 2025 go to post

@Jeffrey.DrummThis is caused by a known IRIS bug. The fix is in IRIS 2022.1.4+, 2023.1.2+, and 2023.3+.

Brett Saviano · Jan 9, 2025 go to post

If possible, you should use VS Code on a developer laptop that can be kept up to date instead of the server that IRIS/Cache is running on. The extension versions you are using are well over a year old and you'll be missing out on major new features, like the one you requested in this post. VS Code can connect to servers that are on a different machine.

Brett Saviano · Jan 8, 2025 go to post

@David Hockenbroch 
I suggest you open a WRC case to request a different way to enable SMTP tracing if the subclass or IRISLIB mounting approaches don't work for your case.