Back to Home

PSA plugin for IntelliJ: custom autocomplete

PSA plugin implements custom autocomplete and navigation in IntelliJ based on project PSI context. Script analyzes JSON tree and returns completions/links. Suitable for frameworks without ready-made plugins.

Custom autocomplete PSA for IntelliJ IDEA
Advertisement 728x90

PSA: Custom Autocomplete and Navigation in IntelliJ Using PSI Context

The PSA plugin empowers developers to implement project-specific autocomplete, navigation, and code templates directly within IntelliJ IDEA. A script written in any language analyzes the current PSI tree and returns suggestions. This solves the challenge of supporting custom frameworks without installing separate plugins.

How PSI Context Works

The plugin activates when you specify the path to an executable script in settings. When autocomplete (Ctrl+Space) or GoTo is triggered, a PSA Context — a simplified PSI tree of the focused element — is generated. It’s JSON-encoded into a temporary file (due to command-line argument limits) and passed to the script via the PSA_CONTEXT environment variable.

Example for PHP:

Google AdInline article slot
<?php

function myFunc() {
    $l = '';
//        ^   cursor here
}

The generated JSON includes a hierarchical structure of elements:

{
  "elementType": "right single quote",
  "elementName": null,
  "elementFqn": null,
  "text": "'",
  "parent": {
    "elementType": "String",
    "text": "''",
    // ... nested structure up to file level
  }
}

Each PSI node includes elementType, elementName, elementFqn, text, textRange (startOffset/endOffset), parent/prev/next, and options.

Environment Variables for the Script

The script receives:

Google AdInline article slot
  • PSA_CONTEXT: Path to the JSON file containing the PSI tree.
  • PSA_TYPE: Either Completion or GoTo.
  • PSA_LANGUAGE: The programming language (PHP, JS, etc.).
  • PSA_DEBUG: Set to 1 when debugging is enabled.
  • PSA_OFFSET: Cursor position within the element.

The script parses the tree, analyzes context (element + parents), and determines suggestions. For Completion, it returns an array of options; for GoTo, one with a link.

Script Response Format

JSON response:

{
  "completions": [
    {
      "text": "insertion text",
      "link": "FileName.php:42:5", // only for GoTo
      "bold": true,
      "priority": 10
    }
  ],
  "notifications": ["debug message"],
  "gotoElementTypes": ["FUNCTION", "CLASS"] // performance filter
}

priority sorts results; bold highlights entries. gotoElementTypes restricts GoTo scope for faster performance.

Google AdInline article slot

Documentation and Swagger

The plugin generates Swagger UI from its API models for clarity. Methods are 'fake' but describe call structures. Use OpenAPI Generator to create DTO classes for your script.

PSI element structure:

  • elementType: Type (STRING, FUNCTION).
  • elementName/Fqn: Name or FQCN.
  • options: Dictionary of parameters.
  • text: Original source text.
  • textRange: Offsets.
  • Relationships: parent/prev/next.

Setup and Performance

Enable the plugin and point it to your script. Turn on PSA_DEBUG for troubleshooting. Use gotoElementTypes filters to reduce GoTo overhead.

Advantages over framework-specific plugins:

  • Project-level dependency, not global.
  • Supports custom APIs and templates.
  • Language-agnostic script support.

Example script (pseudocode):

#!/bin/bash
context=$(cat $PSA_CONTEXT | jq .)
if [[ $PSA_TYPE == "Completion" ]]; then
  # analysis logic
  echo '{"completions": [{"text": "customFunc()"}]}'
fi

Key Points

  • PSA passes the full PSI tree for precise contextual analysis.
  • Scripts return completions with priority and bold for custom ranking.
  • GoTo supports file:line:pos links and elementType filtering.
  • Swagger documentation speeds up DTO development.
  • Works with any project language (PHP, JS/TS, etc.).

— Editorial Team

Advertisement 728x90

Read Next