Quick Debug PrintInsert debug print statements instantly — right where you need them. Select a variable or expression, or simply place your cursor on it, then press:
Quick Debug Print detects the language you're editing and inserts an idiomatic debug print statement directly below your code. No more manually typing repetitive Supported LanguagesQuick Debug Print supports: C · C++ · C# · Java · JavaScript · TypeScript · JSX · TSX · Python · Go · Rust · PHP · Ruby · Swift · Kotlin · Shell · Lua Language detection follows the current VS Code language mode, so the extension works with the language selected in your editor. Quick ExampleGiven:
Place your cursor on
The extension inserts:
The same workflow works across all supported languages. JavaScript / TypeScript
becomes:
Python
becomes:
Java
becomes:
Go
becomes:
Rust
becomes:
C — Type-Aware
|
| Type | Format |
|---|---|
char |
%c |
signed char |
%d |
unsigned char |
%u |
short |
%hd |
unsigned short |
%hu |
int |
%d |
unsigned int |
%u |
long |
%ld |
unsigned long |
%lu |
long long |
%lld |
unsigned long long |
%llu |
float / double |
%f |
size_t |
%zu |
ssize_t |
%zd |
int8_t … int64_t |
Appropriate width |
uint8_t … uint64_t |
Appropriate width |
char * |
%s |
| Other pointers | %p |
Pointer output uses an explicit (void *) cast where necessary to keep generated code warning-free with -Wformat.
Fixed-width 64-bit integer arguments also receive explicit casts where necessary to ensure portable printf usage across platforms.
C++ — cout
C++ uses std::cout instead of format specifiers.
int count = 0;
becomes:
int count = 0;
std::cout << "count = " << count << std::endl;
Because operator<< handles the value's type automatically, most values require no additional type information.
Character types
C++ normally prints char, signed char, unsigned char, int8_t, and uint8_t as characters.
For numeric debugging, the extension converts the appropriate types:
signed char sc = -5;
becomes:
signed char sc = -5;
std::cout << "sc = " << static_cast<int>(sc) << std::endl;
Plain char is left unchanged so it continues to print as a character.
Note:
#include <iostream>is not added automatically. Add it to your C++ file if needed.
Arrays
Select an entire array to generate a loop that prints every element.
For example:
int arr[5] = {10, 20, 30, 40, 50};
generates:
for (size_t __i_arr = 0; __i_arr < 5; __i_arr++)
std::cout << "arr[" << __i_arr << "] = "
<< arr[__i_arr] << std::endl;
The C version generates the equivalent printf loop.
Individual elements
You can also select a specific element:
arr[2]
The extension resolves the actual element type instead of assuming a default type.
Bounds checking
Constant out-of-bounds indexes are detected.
For example, selecting:
arr[5]
when the array contains five elements displays a warning instead of inserting an invalid debug statement.
Struct and Member Access
C and C++ member expressions are supported.
You can select:
object.field
or:
pointer->field
The extension resolves the actual field type before generating the debug statement.
Struct Dump
Select a bare struct or aggregate variable to generate debug output for its fields.
Scalar fields are printed directly, while nested by-value structs are traversed recursively.
For example:
typedef struct s_point {
int x;
int y;
} t_point;
typedef struct s_object {
int id;
t_point position;
} t_object;
t_object object;
Selecting object generates debug output for fields such as:
object.id
object.position.x
object.position.y
Dynamic Struct Arrays
The extension can detect dynamic arrays inside structs when a pointer to a known struct type has an associated size field.
Common size fields include:
sizecountlencapacity
When multiple fields are available, size is preferred over capacity.
For example:
typedef struct s_heap_node {
long long key;
int id;
} t_heap_node;
typedef struct s_heap {
t_heap_node *data;
int size;
int capacity;
} t_heap;
t_heap *heap = ...;
Selecting heap in C++ can generate:
for (size_t __i0_data = 0; __i0_data < (size_t)heap->size; __i0_data++)
{
std::cout << "heap->data[" << __i0_data << "].key = "
<< heap->data[__i0_data].key << std::endl;
std::cout << "heap->data[" << __i0_data << "].id = "
<< heap->data[__i0_data].id << std::endl;
}
std::cout << "heap->size = " << heap->size << std::endl;
std::cout << "heap->capacity = " << heap->capacity << std::endl;
Recursive structures are handled safely:
- Self-referential structures are detected.
- Infinite recursion is prevented.
- Nested traversal is limited to four levels.
Other Languages
Languages that don't require C/C++-style type resolution use their own idiomatic debug-print syntax.
| Language | Generated statement |
|---|---|
| Python | print(f"{count=}") |
| JavaScript / TypeScript | 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)) |
Unsupported languages receive a TODO debug placeholder and a warning rather than having potentially incorrect syntax guessed automatically.
Diagnostics
Quick Debug Print provides a Printf Debug output channel for troubleshooting.
Open:
View → Output → Printf Debug
The diagnostic output can include:
- Detected language
- Selected expression
- Detection branch
- Resolved type
- Generated debug statement
This can be useful when investigating unexpected output or reporting a bug.
Requirements
- Visual Studio Code
1.80.0or later
Feedback & Issues
Found a bug or have an idea?
When reporting an issue, include:
- The language you're using
- The code or expression you selected
- The generated output
- The expected output
This helps reproduce and fix issues quickly.
License
See the project's LICENSE file for license information.