Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions en/clice/features/hover.md
Original file line number Diff line number Diff line change
Expand Up @@ -766,14 +766,16 @@ tests/snap/hover/macro_hover/06_preamble_define_hover.cpp

<!-- BEGIN GENERATED ITEMS: special_hover_targets -->

<!-- BEGIN CAPABILITY: partial clangd#959 -->
<!-- BEGIN CAPABILITY: supported clangd#959 -->

**Members on type hover**

Hovering an enum or struct type lists its members

The card names the type (and a struct's layout), but the member list is
not expanded — the body renders as `{}`.
A class lists its data members and member types, an enum its
enumerators with their values; member functions are left out. The
`max_members` option caps the list, 20 entries by default, and `0`
turns it off.

```snap
tests/snap/hover/special_hover_targets/01_type_members_on_hover.cpp
Expand Down
2 changes: 1 addition & 1 deletion en/clice/features/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Language Server Protocol features available when using clice as an editor backen
| Feature | Status |
| ----------------------------------------- | ------------------------------------------ |
| [Code Completion](./completion.md) | 57 supported |
| [Hover](./hover.md) | 37 supported · 20 partial · 10 unsupported |
| [Hover](./hover.md) | 38 supported · 19 partial · 10 unsupported |
| [Signature Help](./signature-help.md) | 14 supported |
| [Code Navigation](./navigation.md) | 71 supported · 12 partial · 26 unsupported |
| [Document Links](./document-links.md) | 7 supported · 1 partial · 1 unsupported |
Expand Down
10 changes: 10 additions & 0 deletions en/clice/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ Show the desugared form of a type, e.g. `vector<int>::size_type (aka unsigned lo

</div>

<div class="config-option">

| Option | Type | Default |
| ------------- | -------- | ------- |
| `max_members` | `uint32` | `20` |

Maximum number of members the definition of a hovered class or enum lists: data members and member types, or enumerators; member functions are left out. `0` shows the declaration alone.

</div>

<!-- END GENERATED CONFIG -->

## `[inlay_hints]`
Expand Down
10 changes: 9 additions & 1 deletion public/clice-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"description": "The [hover] section: hover rendering options.",
"default": {
"parse_comment_as_markdown": true,
"show_aka": true
"show_aka": true,
"max_members": 20
}
},
"inlay_hints": {
Expand Down Expand Up @@ -184,6 +185,13 @@
"type": "boolean",
"description": "Show the desugared form of a type, e.g. `vector<int>::size_type (aka unsigned long)`.",
"default": true
},
"max_members": {
"type": "integer",
"minimum": 0,
"maximum": 4294967295,
"description": "Maximum number of members the definition of a hovered class or enum lists: data members and member types, or enumerators; member functions are left out. `0` shows the declaration alone.",
"default": 20
}
},
"additionalProperties": false
Expand Down
35 changes: 35 additions & 0 deletions sources/clice/tests/snap/hover/c_records.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// - flags: ["-x", "c", "-std=c11"]

struct Point {
int x;
union {
int tag;
float weight;
};
struct {
int width, height;
} size;
enum { Small, Large } scale;
};

struct §(c_struct)Point point;

struct ops {
int (*open)(struct inode*, struct file*);
const struct item* first;
int count;
};

struct §(c_mentions)ops table;

struct Packed {
char raw[sizeof(struct { int a; long b; })];
__typeof__(struct { int t; }) typed;
void (*callback)(struct { int x; }* arg);
_Atomic struct {
int value;
} atomic;
int tail;
};

struct §(c_inner_tags)Packed packed;
51 changes: 51 additions & 0 deletions sources/clice/tests/snap/hover/c_records.snap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
created_at: 2026-10-09
input_file: c_records.cpp
---
c_inner_tags: { range: "34:7-34:13" }
### struct `Packed`

---
```cpp
struct Packed {
char raw[16];
typeof(struct(unnamed)) typed;
void (*callback)(struct(unnamed) *);
_Atomic(struct(unnamed)) atomic;
int tail;
}
```

c_mentions: { range: "22:7-22:10" }
### struct `ops`

---
```cpp
struct ops {
int (*open)(struct inode *, struct file *);
const struct item *first;
int count;
}
```

c_struct: { range: "14:7-14:12" }
### struct `Point`

---
\- flags: ["-x", "c", "-std=c11"]

---
```cpp
struct Point {
int x;
union {
int tag;
float weight;
};
struct {
int width;
int height;
} size;
enum { Small = 0, Large = 1 } scale;
}
```
34 changes: 34 additions & 0 deletions sources/clice/tests/snap/hover/enum_members.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// The enumerator summary of an enum: values as written, computed values for
// the rest.

namespace implicit_values {
enum Level { Low, Medium = 10, High };
§(implicit_values)Level level;
}

namespace written_values {
enum Permission : unsigned {
Read = 1 << 0,
Write = 1 << 1,
Execute = 1 << 2,
All = Read | Write | Execute,
};
§(written_values)Permission permission;
}

namespace scoped {
enum class Ordering : signed char { Less = -1, Equal, Greater };
§(scoped)Ordering ordering;
}

namespace empty {
enum class Tag : int {};
§(empty)Tag tag;
}

namespace dependent {
template <typename T> struct Holder {
enum Size { None, Bytes = sizeof(T), Twice };
§(dependent)Size size;
};
}
53 changes: 53 additions & 0 deletions sources/clice/tests/snap/hover/enum_members.snap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
created_at: 2026-10-09
input_file: enum_members.cpp
---
dependent: { range: "31:4-31:8" }
### enum `Size`

---
```cpp
// In Holder<T>
public: enum Size { None, Bytes = sizeof(T), Twice }
```

empty: { range: "25:0-25:3" }
### enum `Tag`

---
```cpp
// In namespace empty
enum class Tag : int {}
```

implicit_values: { range: "5:0-5:5" }
### enum `Level`

---
```cpp
// In namespace implicit_values
enum Level { Low = 0, Medium = 10, High = 11 }
```

scoped: { range: "20:0-20:8" }
### enum `Ordering`

---
```cpp
// In namespace scoped
enum class Ordering : signed char { Less = -1, Equal = 0, Greater = 1 }
```

written_values: { range: "15:0-15:10" }
### enum `Permission`

---
```cpp
// In namespace written_values
enum Permission : unsigned int {
Read = 1 << 0,
Write = 1 << 1,
Execute = 1 << 2,
All = Read | Write | Execute
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ struct_hover: { range: "12:7-12:13" }
---
```cpp
// In namespace ms
struct Widget {}
struct Widget {
int value;
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ Size: 16 bytes, alignment 8 bytes
---
```cpp
// In namespace layout
struct Widget {}
struct Widget {
int id;
double value;
}
```
60 changes: 60 additions & 0 deletions sources/clice/tests/snap/hover/member_truncation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Long member lists stop at the default limit of 20 entries, nested members
// included; huge initializers are left out of the summary.

namespace long_record {
struct Registers {
int r00, r01, r02, r03, r04, r05, r06, r07, r08, r09;
int r10, r11, r12, r13, r14, r15, r16, r17, r18, r19;
int r20;
};
§(long_record)Registers registers;
}

namespace exact_record {
struct Registers {
int r00, r01, r02, r03, r04, r05, r06, r07, r08, r09;
int r10, r11, r12, r13, r14, r15, r16, r17, r18, r19;
};
§(exact_record)Registers registers;
}

namespace long_enum {
enum Opcode {
Op00, Op01, Op02, Op03, Op04, Op05, Op06, Op07, Op08, Op09,
Op10, Op11, Op12, Op13, Op14, Op15, Op16, Op17, Op18, Op19,
Op20, Op21,
};
§(long_enum)Opcode opcode;
}

namespace nested_cut {
struct Packet {
int r00, r01, r02, r03, r04, r05, r06, r07, r08, r09;
int r10, r11, r12, r13, r14, r15, r16, r17;
union {
int word;
short half;
char byte;
};
int trailer;
};
§(nested_cut)Packet packet;
}

#define DUPLICATE_FOUR(x) x, x, x, x
#define DUPLICATE_256(x) DUPLICATE_FOUR(DUPLICATE_FOUR(DUPLICATE_FOUR(DUPLICATE_FOUR(x))))
#define SUM_FOUR(x) x + x + x + x
#define SUM_256(x) SUM_FOUR(SUM_FOUR(SUM_FOUR(SUM_FOUR(x))))

namespace huge_initializers {
struct Tables {
int large_field[256] = {DUPLICATE_256(0)};
inline static int large_static[256] = {DUPLICATE_256(0)};
int small_field = 1;
inline static int small_static = 2;
};
§(huge_record_initializers)Tables tables;

enum Sum { Small = 1, Large = SUM_256(1) };
§(huge_enumerator)Sum sum;
}
Loading
Loading