Skip to content

Code editor: code completion (jedi optional) - #298

Open
enriquevelmai wants to merge 1 commit into
nxt-dev:devfrom
enriquevelmai:feature/code-completion
Open

enriquevelmai wants to merge 1 commit into
nxt-dev:devfrom
enriquevelmai:feature/code-completion

Conversation

@enriquevelmai

Copy link
Copy Markdown

Adds a completion popup to the code editor, as a small MVC package nxt_editor.completion:

  • Python code: via jedi when installed (new extra: pip install nxt-editor[completion]). Without jedi it falls back to keywords, builtins and identifiers already in the buffer, so nothing changes for existing installs.
  • nxt runtime globals: STAGE, self, nxt_path, ExitNode, ExitGraph… complete as they do inside a compute, and live STAGE/self are picked up from the runtime layer console after a run.
  • Host modules: cmds, mel, om, pm (Maya), pyfbsdk (MotionBuilder), pymxs (3ds Max), unreal complete before the import is typed. Host is detected from NXT_DCC or by probing imports; adding a DCC is one small subclass in hosts.py. Dynamically populated modules like maya.cmds use a runtime dir() since jedi only sees them statically.
  • ${} tokens: node paths and attribute names from the stage model, plus the file:: / path:: / contents:: prefixes.

Behaviour: pops while typing (debounced for the jedi path), Ctrl+Space forces it, Tab/Enter accept, Esc dismisses, arrows navigate. The popup is a plain child of the viewport so it never steals focus. Tab/Enter are only claimed while the popup is visible; the indent / new line actions are untouched otherwise.

Tokens are replaced by same-length string literals before handing the buffer to jedi so line/column positions stay valid. parso's on-disk cache is disabled because it collides across DCC python versions.

New nxt_editor.completion package (context / model / sources / hosts /
controller / popup). Completes Python code, the implicit nxt runtime
globals (STAGE, self, nxt_path, ...), host modules before they are
imported (maya.cmds, pyfbsdk, pymxs, unreal) and ${} tokens (node paths
and attribute names from the stage model). Uses jedi when installed
(pip install nxt-editor[completion]) and falls back to keywords,
builtins and buffer identifiers otherwise. Ctrl+Space requests it
explicitly; Tab/Enter accept, Esc dismisses.
@michaelharmonart

Copy link
Copy Markdown

I've been itching for code completion in NXT for a WHILE now.

I'll definitely give this a test today.

@enriquevelmai

Copy link
Copy Markdown
Author

Great, thanks for trying it. A few notes to get the most out of it:

Standalone

pip install -e .            # from this branch
pip install jedi            # optional, enables the rich completion
nxt ui

Without jedi it still works, but only offers keywords, builtins, nxt runtime globals and names already in the buffer.

In Maya
jedi has to be importable by Maya's python. Either install it into mayapy:

mayapy -m pip install jedi

or, if you use the module folder from the release zip, just drop the jedi and parso package folders (pure python, from a pip download jedi) next to nxt / nxt_editor in nxt_maya/scripts. That's how we run it here, so the plugin has completion out of the box with no pip step. If the maintainers like that I can look at adding both packages to the Maya zip in the release bot as a follow-up.

What to try

  • cmds. right away, before any import line: host modules (cmds, mel, om, oma, pm) are pre-populated when Maya is detected. Since maya.cmds is populated at runtime jedi can't see it, so those names come from a live dir() of the module.
  • STAGE., self., nxt_path.: the implicit compute globals. STAGE / self pick up the live objects from the runtime layer after a run.
  • ${ for node paths and ${/some/node. for attribute names of that node, plus the file:: / path:: / contents:: prefixes.
  • Ctrl+Space forces the popup, Tab / Enter accept, Esc closes, arrows / PageUp / PageDown move.

If it misbehaves, the interesting bits to report are the DCC + python version and whether import jedi works in that interpreter. One known limitation: a buffer that doesn't parse (unbalanced brackets above the cursor) makes jedi return nothing for that request, the popup just doesn't show.

@michaelharmonart

Copy link
Copy Markdown

works well so far! I have noticed a few things.

  1. Any imports done in the root STAGE node are not picked up by jedi in individual nodes. You've worked around this for common stuff like maya's cmds, however when working in a pipeline you'll usually have other modules available to you at all times, either imported in the stage node, or by the pipeline. It would be great if definitions in the stage were respected by jedi in other nodes.

  2. This is out of scope for this PR but I can't help think of how great it would be to have the ability to see the types of arguments and the docstring for functions/classes in the nxt editor somehow if possible.

Overall great work. We'll be cherry picking this for our pipeline's custom build of nxt-editor.
I'll let you know if we run into any other issues.

@wyoder

wyoder commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Thanks for the PR. We have a version of this functioning, so we will need to test this PR against the new release we plan on creating before we accept this PR. We will get back to this asap.

@wyoder
wyoder self-requested a review September 24, 2026 14:56

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants