Hi Trey,
Unfortunately I think this is impossible for the current version of labscript. Due to the way labscript code injects the created device/channel instances into the Python builtins (so they are available everywhere), there is no way for Intellisense (or equivalent in other IDEs) to know the type of the variables used in the experiment logic. A similar problem occurs with the globals.
To be honest, I think we should seriously consider not injecting into builtins for the next major version of labscript (for a variety of reasons including hopefully getting Intellisense working). This would bring the project in line with other Python libraries. The main reason we injected into builtins is so that you didn't have to define a name twice. For example, this is overly verbose:
my_channel = DigitalOut("my_channel", ni_card, "port0/line1", ...)
But there are other ways to avoid defining the name twice. A possible way around this (in a future labscript version) would be to define the connection table in a class:
class Dev(labscript.ConnectionTable):
my_channel = labscript.DigitalOut(ni_card, "port0/line1", ...)
The reason this can work is you can configure a Python metaclass for labscript.ConnectionTable that detects attributes using labsccript device/channel classes, and have the metaclass tell the labscript objects the name of the attribute they are assigned to. That allows labscript to keep track of the name of devices/channels without needing it to be specified twice, in a way that things like Intellisense can also keep track of.
It would also allow you group (namespace) devices/channels based on their function, across multiple ConnectionTable classes:
class Dev(labscript.ConnectionTable):
ni_card = NIPCIe6363(...)
my_channel = labscript.DigitalOut(ni_card, "port0/line1", ...)
class MOT(labscript.ConnectionTable):
shutter = labscript.DigitalOut(Dev.ni_card, "port0/line3")
And then you use them like:
Dev.my_channel.go_high(t=4)
MOT.shutter.open(t=7)
Globals would be a bit harder, I suspect you'd have to (a) namespace them using classes like we'd do above for devices and (b) have runmanager write out something dynamically that Intellisense could process to understand what globals were available inside each class. I also don't see this as a bad thing, as I think it would make sense to namespace globals inside a labscript script in the same way they are grouped in runmanager already, and it would allow us to inject the globals units into the labscript file so they didn't have to be maintained in 2 places.
So I guess that is the way I'd see we could (and probably should) make it work in the future. It's a big, backwards incompatible change though, and would need some community consultation as to whether the added syntactic burden is worth it for the gains.