Printf Debug Inserter
Select a variable (or just put your cursor in/on it), press Ctrl+Shift+L
(Cmd+Shift+L on Mac), and get a debug line inserted right below —
in whatever language you're editing.
int count = 0;
→
int count = 0;
printf("count = %d\n", count);
count = 0
→
count = 0
print(f"{count=}")
let count = 0;
→
let count = 0;
console.log('count =', count);
Supported languages
C / C++ get the full treatment: real type resolution (scans the file
for the variable's declaration), correct printf format specifiers,
indexed access (arr[2]), struct/pointer member access (obj.field,
ptr->field), out-of-bounds warnings, and a for-loop mode for whole
arrays. See the details below.
Everything else — Python, JavaScript/TypeScript (+ JSX/TSX), Java, Go,
Rust, C#, PHP, Ruby, Swift, Kotlin, shell scripts, Lua — gets the correct
idiomatic debug-print line for that language. No type resolution is
needed there because these languages already auto-format any value
(f-strings, %v, {:?}, string interpolation, etc.), so the extension
just picks the right print/log call:
| Language |
Generated line |
| Python |
print(f"{count=}") |
| JS/TS |
console.log('count =', count); |
| Java |
System.out.println("count = " + count); |
| Go |
fmt.Printf("count = %v\n", count) |
| Rust |
println!("count = {:?}", count); |
| C# |
Console.WriteLine($"count = {count}"); |
| PHP |
error_log("count = " . print_r(count, true)); |
| Ruby |
puts "count = #{count}" |
| Swift |
print("count = \(count)") |
| Kotlin |
println("count = $count") |
| Shell |
echo "count = $count" |
| Lua |
print("count = " .. tostring(count)) |
Language is detected from the file's VS Code language mode
(editor.document.languageId), not the file extension, so it works in
any file VS Code recognizes. If your language isn't in the table, it
inserts a // TODO print debug: ... placeholder and shows a warning —
open an issue / edit GENERIC_LANGUAGES in extension.js to add it
(it's a one-line template function).
C/C++ details
It guesses the correct format specifier by scanning the file for the
variable's declaration: %c/%d/%u for char variants, %hd/%hu for
short, %ld/%lu for long, %lld/%llu for long long, %f for
float/double, %zu/%zd for size_t/ssize_t, correct widths for the
int8_t...uint64_t family, %s for char *, and %p for any other
pointer. Falls back to %d if no declaration is found.
Indexed access (arr[2]) and struct member access (obj.field,
ptr->field) are handled — the extension resolves the real element/field
type rather than defaulting to %d. If a constant index is out of bounds
for a known array size, you'll get a warning popup instead of a silently
broken printf.
Whole-array printing: select just the array name (e.g. arr, no
brackets) and it generates a for loop that prints every element instead
of a single line:
int arr[5] = {1, 2, 3, 4, 5};
for (size_t __i_arr = 0; __i_arr < 5; __i_arr++)
printf("arr[%zu] = %d\n", __i_arr, arr[__i_arr]);
How to install (no publishing needed)
- Install the packaging tool once:
npm install -g @vscode/vsce
- From this folder, package it:
vsce package
This produces printf-debug-0.0.1.vsix.
- In VS Code: Extensions view →
... menu (top right) →
"Install from VSIX..." → select that file.
Reload VS Code and the shortcut is live in any file.
Changing the shortcut
Edit the keybindings section in package.json, e.g. change
"key": "ctrl+Shift+l" to whatever you prefer, then repackage.
Notes / limitations
- Type detection is a lightweight regex scan, not a real C parser.
- Struct field resolution handles
struct Tag { ... }; and
typedef struct { ... } Alias; forms, one level deep — e.g. p.x or
ptr->x. Chains like a.b.c or a->b->c only resolve the last field
against a's type and will fall back to %d if that lookup fails.
A warning popup tells you when this happens.
- Whole-array loop mode only triggers when you select the bare array name
with no index or brackets.
- Works for both
.c and .cpp files (no language restriction).