Redis IntelliSense built from the server's COMMAND DOCS
Redis completion that reads the server's COMMAND DOCS: fitting options, subcommands, key names, and hover cards with Write and Destructive badges.
The short version
Redis IntelliSense that asks the server what it knows.
A Redis query tab in SQLly now completes command names, the options that fit where the caret
is, subcommands and key names, and it shows each command's syntax on hover with a
Write, Destructive or Blocking badge. The vocabulary comes from the
connected server's own COMMAND DOCS and COMMAND INFO, so Redis Stack
modules and server-specific commands complete too. When the server can't answer, a bundled
Redis 7.4 snapshot takes over.
Why not a hard-coded list
The obvious way to build Redis completion is to ship a list of commands. It works until you
connect to something that isn't the Redis version the list was written for: a Stack server with
JSON.*, FT.* and TS.*, a Valkey build with its own
additions, a module you loaded yourself, or an older server that lacks commands the list
assumes. Then completion either offers commands that don't exist or misses the ones you came
for.
Redis 7 can describe itself. COMMAND DOCS returns each command's summary, the
version it appeared in, its complexity and a structured argument tree, with tokens, optional
blocks and mutually exclusive groups. COMMAND INFO returns its flags
(readonly, write, adminβ¦) and where its keys are. That is
enough to build completion, hover and signature help from the server you're actually on, so
that's what SQLly does.
Where the vocabulary comes from
On connect, SQLly runs a read-only virtual command, SQLLY.COMMANDS, which returns the
server's COMMAND DOCS and COMMAND INFO as rows, one per command. The
editor parses those rows into its vocabulary. Commands the server doesn't list aren't offered,
except SQLly's own SQLLY.* virtual commands, which are always included.
There are two cases where the server can't answer:
- An ACL user without
+commandis refusedCOMMAND. - A server older than Redis 7.0 has no
COMMAND DOCS.
For both, SQLly falls back to a bundled snapshot. The snapshot is generated by a script from the
live COMMAND DOCS and COMMAND INFO of Redis 7.4 and Redis Stack, and it
holds more than 400 commands, so completion always works.
The snapshot needed one hand-written supplement. RediSearch registers its commands without
documentation: they report only group=module, with no summary and no arguments. So
the generator merges hand-maintained entries for the FT.* family (and a few commands
no fixture serves, such as RedisGraph's and the deprecated FT.DROP) into the
snapshot. A test checks that FT.SEARCH has a summary and that its syntax starts
FT.SEARCH index query.
COMMAND DOCS, so on KeyDB completion uses the bundled Redis 7.4 snapshot.
A command KeyDB lacks can still be offered there; the server's own error tells you when you run
it.
What you get as you type
Command names
Start a line and the popup narrows as you type, with each command's one-line summary beside it. Commands you've accepted before in this session come first. Otherwise the data-structure commands (strings, hashes, lists, sets, sorted sets, streams) lead and the administrative ones follow.
HSE| β HSET, HSETNX
js| β JSON.ARRAPPEND, JSON.GET, JSON.SET, β¦ (on Redis Stack)
Press Ctrl+Space (Cmd+Space on macOS) on a blank line to browse every command.
Options in the right position
After the command, the popup follows the documented argument tree, so it knows what can come next, not just which words exist:
ZRANGE k 0 -1 | β BYSCORE, BYLEX, REV, LIMIT, WITHSCORES
ZRANGE k 0 -1 LIMIT | β (nothing: the next word is a number you type)
Options that can't be combined drop out once one is chosen. SET's expiry options are
one exclusive group, so after
SET k v EX 10 | β GET, NX, XX
That is the whole list. KEEPTTL, PX and the other expiry options are
gone, because EX already took that slot, and what's left is the condition
(NX / XX) and GET. The popup doesn't offer the option
that would turn the line into a syntax error. After a complete GET k, nothing is
offered at all.
Subcommands
Container commands offer their subcommands:
XINFO | β CONSUMERS, GROUPS, HELP, STREAM
CONFIG G| β GET
Key names, without scanning anything
Where a command takes a key, the popup offers key names the Server Explorer has already scanned for the tab's logical database, with each key's type. Expand a database or a key folder in the explorer, then:
GET us| β user:1, user:2, users:all (each with its type)
Names that need quoting (spaces, quotes) are inserted quoted. The popup never runs a
SCAN of its own. It only reuses what the explorer already listed. Typing should
never walk the keyspace of a busy production server, and with this design it can't.
redis-intellisense-zrange-options.webp β a Redis query tab with ZRANGE k 0 -1 typed and the completion popup listing BYSCORE, BYLEX, REV, LIMIT and WITHSCORES with their summariesZRANGE k 0 -1 the popup offers only the options that can come next.redis-intellisense-key-names.webp β a Redis query tab with GET us typed and the popup listing key names from the explorer's scan (user:1, user:2, users:all) with each key's type, the expanded explorer folder visible beside itHover cards that agree with the Run gate
Rest the pointer on a command and the card shows its documented syntax, summary, the version it appeared in and its complexity. The card also shows a safety verdict:
- Write for commands that change keys or state (
SET k v). - Destructive for
FLUSHALL,DEL,CONFIG SETand friends. - Blocking, with the reason, for a line that would never answer on a query connection, such as
SUBSCRIBE newsorBLPOP q 0.
These badges are not a second opinion. They come from the same safety classification the Run
gate applies, the one behind read-only connections and the production lock. The blocking verdict looks at
the arguments, not just the name: BLPOP q 0 waits forever and is badged Blocking,
while BLPOP q 5 returns within five seconds and only gets the Write badge. You find
out what a line will do before you press Run, and the answer is the one Run will give.
Hovering an option word such as WITHSCORES explains which argument it belongs to.
While the caret is on a command line, signature help shows the whole syntax above it, with the
argument you're typing highlighted:
ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
Esc hides it for that line. Both follow the editor's "Show hover info" and "Show signature help" preferences.
redis-intellisense-flushall-hover.webp β the hover card on FLUSHALL in a Redis query tab showing its syntax, summary, since-version, complexity and the Destructive badgeKeeping two lists honest
The safety classifier has its own lists: commands known to be read-only, and commands treated as destructive. The IntelliSense vocabulary is a third source of truth about the same commands. Two lists that describe the same thing drift apart unless something forces them to agree, so one test does:
- Every command on the safety classifier's read-only and destructive lists must exist in the bundled vocabulary. A command one side knows and the other doesn't fails the test.
- No command on the read-only list may carry the
writeflag in the server's ownCOMMAND INFO. If Redis says it writes, SQLly can't call it read-only.
A second test pins the badges to the classifier: FLUSHALL is Destructive,
SET k v is Write, GET k has no badge, and BLPOP q 0 and
SUBSCRIBE news are Blocking. If someone changes one side, the mismatch fails in CI
instead of showing up as a user staring at a "read-only" badge on a command that just deleted
something.
Fast on long scripts
Redis scripts are one command per line, so completion, hover and signature help only look at the
caret's line. A 5,000-line script costs about the same as a one-line one. A test builds a
5,000-line script of HSET lines and requires two completion passes (one in the
middle, one at the end), a hover and a signature lookup to finish in under 5 ms together.
HSET user:0 name "user 0" age 0
HSET user:1 name "user 1" age 1
β¦ (5,000 lines)
ZRANGE k 0 -1 |
Things that stay off
The SQL formatter, SQL validation and the SQL lints are off for Redis tabs. A command script
isn't SQL, and Validate checks the command lines instead. The F2 "improve IntelliSense" report
works on a Redis popup the same way it does on SQL, so a miss can become a test. The command-line
tool, sqlly-cli intellisense complete-enriched, accepts Redis scripts with dialect
redis and takes key names as objects of kind key.
Limits
- On servers that refuse
COMMAND, predate 7.0, or have noCOMMAND DOCS(KeyDB), you get the Redis 7.4 and Stack snapshot, not the server's own list. - Key names are only as fresh as the explorer's last scan of that database. Expand or refresh the folder to update them.
- Completion follows the server's command list, not your connection's topology. On a cluster connection, Run refuses cross-slot multi-key commands,
SELECTother than 0,KEYS,SCANandMULTI/EXECwith a message naming the rule.
The reference is on Redis command IntelliSense.
Download SQLly, open a query tab on a Redis or Valkey connection, and type
ZRANGE k 0 -1 to see it.