Skip to content

Code Action ​

clice offers code actions on a selection: refactorings that generate or reshape code from what the compiler knows about it, and quick fixes for names no header declares. Every action is computed to completion when it is offered, so applying one never waits on a second request; edits carry the document version they were computed for, and an editor refuses them once the buffer moved on. The same actions run headless through clice inspect code_action.

An action anchors on the innermost construct the selection covers — a method declaration, a class name, a switch, an auto — so the list stays short: a click on a method name offers what applies to that method, a click on the class name what applies to the class.

Defining Functions ​

Supportedclangd#445

Define a declared method

A method declaration offers an inline body and an out-of-line definition after its class

The out-of-line definition repeats the declaration with S:: before the name and drops what belongs to the declaration alone, such as default arguments.

Supported

Declaration-only specifiers dropped

virtual, static, explicit, override and final do not appear on the definition

Specifiers that must stay, such as constexpr and noexcept, are kept.

Supported

Definition-scope return type

A return type naming a nested type or another namespace is spelled so it resolves at the definition

Parameter types are looked up in the class scope like the declaration's and stay as written.

Supported

Class template member

The definition of a class template's member carries the template head and the template arguments in its qualifier

Default template arguments are not repeated on the head.

Supported

Member function template

A member template keeps its own template head, minus its default arguments, after the class's

Constrained templates keep their requires-clauses, which a definition must repeat.

Supported

Constructors, destructors and operators

Special member functions are defined under the class name they are spelled with

Conversion functions and operators keep their full spelling.

Supported

Free function declaration

A declared free function is defined right after its declaration, in the same namespace

The name needs no qualifier inside the namespace; the return type is spelled for that scope.

Supported

Placement after existing definitions

When the class already has out-of-line definitions in the file, the new one goes after the last of them

The qualifier follows the scope of that definition, not the class's.

Supportedclangd#445

Define all missing members

On the class name, every member function without a definition is defined at once, in declaration order

Members that already have a definition, pure virtuals and defaulted members are left alone.

Supported

Missing members from a definition

Inside an out-of-line definition, the class's remaining undefined members are offered too

This is how a source file completes a class declared elsewhere: the definitions join the ones already there.

Supportedclangd#445

Define in the host source

In a header, a member can also be defined in the source file the header is compiled with

The definition is fully qualified and joins the class's other definitions in that file; members already defined in some source file are not offered again. Templates, inline functions and functions other files cannot see stay in the header; any other function defined there out of the class is marked inline.

Supported

Nested class member

A nested class's member is defined after the outermost enclosing class, qualified through every level

Supported

Dependent return type

A return type naming the class template or one of its member types is qualified through the template's parameters

Supported

Declarations under a linkage specification

Functions declared with C linkage are defined like any other, inside the linkage block or after a single-declaration form

Implementing Interfaces ​

Supportedclangd#1037

Implement pure virtual methods

A class deriving from an abstract base receives an override declaration for each unimplemented pure virtual method

The declarations go at the end of the class body.

Supported

Pure virtuals through a chain

Only the methods no class in the chain implemented are declared, and a class gets a public: label for them

Supported

Types for the derived class

Parameter and return types written in the base's scope are qualified so they resolve in the derived class

Reference qualifiers and constness are carried over.

Supported

Conversion functions and pointer parameters

A conversion function has no return type to print, and a parameter whose type wraps its name keeps that shape

Supported

Bases sharing a signature

One declaration overrides the pure virtual methods of every base with that signature, noexcept when any of them is

Supported

Specifiers of the override

A C variadic parameter, consteval and whether the base's method is noexcept carry over to the override

A method whose exception specification depends on the arguments of a base class template gets no declaration.

Switch Cases ​

Supportedclangd#807

Missing enum cases

A switch over an enum receives the enumerators it does not handle, followed by a break

Enumerators sharing a handled value are considered covered.

Supported

Cases before the default

With a default present, the missing cases go right before it and fall through into it, keeping the behavior

The action is offered from anywhere inside the switch.

Supported

Unscoped enum in a namespace

Enumerators of an unscoped enum are qualified with the enum's namespace when the switch lies outside it

Supported

Complete switch offers nothing

A switch handling every enumerator, or one over a non-enum value, offers no action

Supported

Selection covering the switch

A selection spanning the whole statement offers the same action as a cursor inside it

Supported

Labels depending on templates

A switch with a label depending on template parameters offers no action, since only an instantiation knows which enumerators it covers

A switch in a template whose labels do not depend on its parameters is completed as anywhere else.

Supported

Sections declaring variables

Without a default, a switch declaring a variable at its own scope receives the missing cases before its first label, since a label after the declaration would jump past it

No section falls through into cases placed there.

Deduced Types ​

Supported

Expand auto in declarations

auto in a variable declaration is replaced by the type it deduced, leaving qualifiers and declarators in place

Supported

Deduced return type

A function's deduced auto return type expands to the deduced type, spelled for the function's scope

Supported

Expand decltype

A decltype specifier expands to the type it denotes

Supported

Unnameable types stay auto

Lambdas, dependent types and types the declaration cannot name are not expanded

A type cannot be named where it is local to another function, a member type the declaration has no access to, or the type of sizeof with no standard name for it declared yet (MSVC compatibility declares size_t implicitly).

Supported

Forwarding references and declarator types

auto&& bound to an lvalue takes the deduced reference in place of both tokens, and a type that wraps the name is left alone

Supported

Names spelled for the scope

A name drops the enclosing namespaces only as far as the shorter name still finds the same type

A name hidden by a declaration closer to the expansion keeps its qualifier, and one hidden even when fully qualified starts from the global scope.

Supported

Standard names of builtin types

The types of sizeof, a pointer difference and nullptr expand to their standard names where those are declared

Without a declaration of std::nullptr_t in sight, the type of nullptr is written decltype(nullptr).

Supported

Constant deduced pointers

A const written before an auto that deduced a pointer moves behind the *, keeping the pointer itself constant

When other specifiers stand between the const and the auto, the declaration is left as written.

Macros ​

Supportedclangd#820

Expand a macro invocation

A macro invocation is replaced by the tokens it expands to

Arguments are substituted; the action is offered from the macro name or anywhere inside its arguments.

Supported

Nested macros expand fully

A macro whose body invokes other macros expands to the final tokens

Supported

Directive references and empty macros

A macro named in a preprocessor condition, on any of its lines, is not an expansion to replace, while a macro expanding to nothing is deleted

Supported

Macros running pragmas

A macro whose expansion executes a _Pragma operator offers no expansion, since the pragma leaves no tokens behind to write in its place

Supported

Tokens stay apart

The expansion is spaced so its tokens merge neither with each other nor with the text written flush against the invocation

Missing Includes ​

Supportedclangd#1017

Standard library include

An unresolved standard library name offers the header declaring it, from the standard library mapping

The directive goes after the includes at the top of the file. An unqualified name also tries the std namespace.

Supported

Include for a project symbol

A name declared in a project header the file does not include offers that header, spelled relative to the file

The candidates come from the project index: lib.h is known because another source file includes it.

Supported

First include of a file

A file without includes receives the directive at its start, after a #pragma once when there is one

Supported

Includes under conditionals

An include nested in a feature condition is not where a directive that must always apply goes: it follows the last one at the file's own level, or the include guard

Supported

Embedded and trailing includes

An include inside extern "C" or a type body, or one following the code, is no place for a new directive: it joins the includes at the top of the file

Reordering Definitions ​

Supported

Reorder definitions by declaration

The out-of-line definitions of a class's members are reordered to follow the declaration order in the class

Each definition moves with the comment block directly above it.

Supported

Namespace blocks reorder separately

Definitions written in different namespace blocks are reordered within each block, never across

Supported

Free functions by declaration order

From a free function's definition, the definitions of the functions declared alongside it are reordered as declared

Supported

Trailing comments stay in place

A comment ending a definition's line moves with that definition, never with the one below it

Supported

Definitions using what lies between

A definition stays where it is when moving it would put it before something it uses, such as a variable or macro defined between the definitions; the others are reordered around it

Constructors ​

Supported

Memberwise constructor

A class receives a constructor taking every field in order, scalars by value and copyable classes by const reference

Supported

Existing constructor not duplicated

No constructor is generated when the class already declares one taking as many arguments as it has fields

Supported

Single field is explicit

A one-field class gets an explicit constructor, placed under a public: label when the class ends in another section

Supported

Declarator-shaped field types

A field whose type wraps the name, such as a function pointer, keeps that shape in the parameter

Supported

Base without a default constructor

No constructor is generated when a base class needs its own initializer, since the memberwise one initializes fields alone

Supported

Deleted base default constructor

A base whose default constructor is deleted explicitly, or implicitly by a reference member or a const member nothing initializes, blocks the memberwise constructor too

A const member of a class that initializes all its own fields leaves the base default-constructible.

Supported

Move-only fields

A field whose class moves but does not copy is taken by value and moved from, and an rvalue reference field binds its argument through std::move

The file gains #include <utility> when nothing declares std::move before the class. A class that neither copies nor moves gets no constructor.

Formatting ​

Generated text is formatted with the project's clang-format style when one applies to the file, so a definition or a block of case labels lands in the surrounding code's layout. Without a style, or with DisableFormat, the text keeps the layout shown in the examples above.

Known Limitations ​

  • A definition placed in the host source goes after the last definition of the class's members the index knows in that file, or at the end of the file when it holds none. Which source file hosts a header follows the header's compilation context.
  • Members already defined in another source file are left out of a "define missing members" action only when the project index knows that definition; with indexing disabled every undefined member is offered.
  • A return type naming a member of a dependent base class is copied as written into an out-of-line definition, where it may need typename and the base's qualifier.
  • Missing-include candidates come from the standard library mapping and from headers the project index has seen; a header no indexed source file includes is not suggested.

Not Implemented ​

Quick fixes from compiler and clang-tidy fix-it hints, extract function and variable, inline function and variable, moving a definition between header and source, converting an unscoped enum to a scoped one, and changing a function's signature across its callers.