# C / C++ (clangd) language-server demo for xwpe

A tiny, deliberately-commented C++ project that exercises **every** xwpe
language-server action that clangd supports.  It is the fastest way to see (and
try) the IDE features in C/C++ -- clangd needs no JVM and no build server, so it
is ready a second or two after you open a file.

> Plain **C** works too: open a `.c` file and the same `Alt-Q` keys drive clangd.
> This demo is C++ so it can also show the class-only actions -- implementation
> (`Alt-Q I`) and the type hierarchy (`Alt-Q K`/`Alt-Q J`) -- which plain C has
> nothing for.

![C/C++ LSP tour](../../demos/gifs/c/tour.gif)

*A tour on this testbed: hover, inlay hints, highlight-all-uses, references, the
file outline, and a rename refactor (`total` &rarr; `tally`) with Undo -- all over
clangd.  The pressed keys are captioned along the bottom.*

## Requirements

- `clangd` -- the language server.  On Debian/Ubuntu: `sudo apt install clangd`.

clangd reads the **compile flags** so its analysis matches your build.  For a
single file it uses sensible defaults; for a real project give it either a
`compile_commands.json` (generated by `bear -- make`, or CMake with
`-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`) or a one-line `compile_flags.txt`.  This
demo ships a `compile_flags.txt` (`-std=c++17 -Wall -Wextra`) so the diagnostics
and the C++17 features resolve.

See the user-facing guide [`docs/LSP.md`](../../LSP.md), or the **Language
servers** chapter of the manual (`info xwpe`), for the full setup notes.

## Run it

```sh
cd docs/examples/c-lsp
wpe main.cpp              # programming mode (xwpe in X11; wpe in a terminal)
```

The **first** language-server action starts clangd; it is ready almost at once.
`Alt-Q ?` opens the action menu, `Alt-Q <letter>` runs one directly.

## What to try

Each line in `main.cpp`, `shapes.hpp` and `actions.cpp` carries an inline comment
telling you which action to try right there -- just read down the code.  For
reference, every action and where it lands:

| Key       | Action            | Where to try it                          |
|-----------|-------------------|------------------------------------------|
| `Alt-Q E` | Diagnostics       | anywhere (also marks problems inline)    |
| `Alt-Q D` | Definition        | on `Circle` (main) or `printf` -> `cstdio` |
| `Alt-Q I` | Implementation    | on `area` in `shapes.hpp` -> the overrides |
| `Alt-Q T` | Type              | on `shapes` in `main`                    |
| `Alt-Q H` | Hover             | on `M_PI` (`shapes.cpp`), any identifier |
| `Alt-Q C` | Complete          | after `shapes.`                          |
| `Alt-Q R` | References        | on `Shape` / on `total`                  |
| `Alt-Q B` | Incoming calls    | on `total` in `main.cpp`                 |
| `Alt-Q G` | Outgoing calls    | on `describe` in `main.cpp`              |
| `Alt-Q K` | Supertypes        | on `Circle` in `shapes.hpp`              |
| `Alt-Q J` | Subtypes          | on `Shape` in `shapes.hpp`               |
| `Alt-Q U` | Uses (highlight)  | on `name` in `shapes.hpp`                |
| `Alt-Q V` | Expand selection  | on a token in `main` (press again widens)|
| `Alt-Q Y` | Inlay hints       | toggle: the `auto` vars get `: T`, call args get param names |
| `Alt-Q M` | Semantic colours  | toggle, anywhere (server-driven highlight)|
| `Alt-Q O` | Outline           | any file                                 |
| `Alt-Q W` | Workspace symbol  | type `Shape` or `Circle`                 |
| `Alt-Q A` | code Actions      | `actions.cpp` -- see "Code actions" below|
| `Alt-Q S` | Signature help    | inside `total(...)` / `printf(...)`      |
| `Alt-Q N` | reName            | on `describe` (or any local)             |
| `Alt-Q F` | Format            | the whole file (clang-format)            |

`Alt-Q` opens the action menu; `Alt-Q <letter>` runs one directly.

## Compiling and debugging this demo

This testbed is a **three-file program** (`main.cpp` + `shapes.cpp` +
`actions.cpp`), built so the language-server actions have cross-file symbols to
work on.  That has one consequence for building:

> Pressing **`F9`** (or `Alt-C` / `Ctrl-G` step) on `main.cpp` **alone** will
> **not link**.  The compile succeeds (it writes `main.o`), but the linker
> reports `undefined reference to 'vtable for Circle'...` and
> `collect2: error: ld returned 1 exit status`, because `shapes.cpp` and
> `actions.cpp` are not in the build.  This is expected for a multi-file
> project, not an xwpe bug.

To build and run the whole thing, link all three sources together:

```sh
make            # builds ./clsp-demo from the three .cpp files
./clsp-demo
```

Inside xwpe, the Borland-style way is a **Project**, and this demo ships one:
open `c-lsp.prj` (`wpe c-lsp.prj`, or the *Project* menu -> Open Project) and
press `F9` -- it compiles and links all three sources into `clsp-demo`, and
`Ctrl-F9` runs it.  (Open the project from its own directory.)  To try
`F9`/`Ctrl-G` on a *single* self-contained file instead, use
`docs/examples/debug_test.cpp` or `debug_constructor.c`.

> If you press `F9` on `main.cpp` alone (no project) and a `Makefile` is present,
> xwpe now points this out -- it suggests opening a project or using
> `Run -> Execute Make (Alt-A)` instead of leaving you with a bare linker error.

> **`Alt-C` (Compile) vs `Alt-M` (Make):** `Alt-C` only compiles the current
> file to a `.o` (no link); if the `.o` is already up to date it now says so
> instead of appearing to do nothing.  `Alt-M` compiles **and** links -- that
> is where the single-file link error above shows up.

> **`Alt-Q L` (code lenses):** clangd does not publish code lenses by default
> (it surfaces that information as inlay hints instead), so this one is usually
> empty for C/C++ -- expected, not a bug.

## Go to definition into the standard library

`Alt-Q D` on `printf` (in `describe`, `main.cpp`) jumps into the system header
that declares it under `/usr/include` -- which xwpe opens **read-only**, marked
by a padlock at the left of the title bar and a dimmed name.  You can read and
copy the standard-library source, not edit it; language-server actions are not
offered inside such a header (run them from your own file).

## Code actions (Alt-Q A)

`actions.cpp` is a dedicated playground for clangd's quick-fixes and refactors.
Put the cursor on a marked spot, run `Alt-Q A`, pick an entry from the popup; the
buffer is rewritten in place (`F2` saves).  The rewrite is a single `Ctrl-U`
(Undo) away, and `Ctrl-R` redoes it -- like any edit.

- a **compiler fix-it** -- `Alt-Q A` on the unused `int unused = 42;` offers to
  remove it (the fix attached to the `-Wunused-variable` diagnostic).
- a **tweak refactor** -- `Alt-Q A` on the `if (n > 0)` offers "Add braces to
  'if'".
- **expand `auto`** -- `Alt-Q A` on `auto msg = ...` offers to write the deduced
  type (`std::string`) in place of `auto`.
