# How witr Visualizes Process Trees Including Child Processes

> Learn how witr visualizes process trees with child processes using ASCII connectors and dynamic indentation. Explore the internals of witr's process hierarchy rendering.

- Repository: [Pranshu Parmar/witr](https://github.com/pranshuparmar/witr)
- Tags: how-to-guide
- Published: 2026-08-09

---

**witr renders process hierarchies by recursively collecting ancestry and child process data into structured slices, then printing them with ASCII tree connectors and dynamic indentation in [`internal/output/tree.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/tree.go).**

The `witr` command-line tool provides a clear, hierarchical view of running processes on Linux systems. According to the pranshuparmar/witr source code, it achieves this visualization by combining recursive process discovery with a specialized tree-rendering algorithm that displays both parent lineage and direct children in a single structured view.

## Process Discovery and Data Structure

The visualization pipeline begins in the **proc package**, where `witr` gathers process information for the target PID. It constructs a `model.Process` struct (defined in [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go)) and recursively discovers two critical relationships: the **ancestry** (the chain of parent processes leading to the target) and the **children** (direct descendants of the target).

The discovery layer returns two slices: `[]model.Process` for ancestry (ordered from system root to target) and another `[]model.Process` for immediate children. These data structures serve as the foundation for the visual tree.

## Rendering the Tree with PrintTree

In [`internal/app/app.go`](https://github.com/pranshuparmar/witr/blob/main/internal/app/app.go) at line 654, the application orchestrates the display by calling:

```go
output.PrintTree(outw, res.Ancestry, res.Children, colorEnabled)

```

This invocation passes four parameters to the output layer:
- `outw` – the `io.Writer` interface that streams to the terminal
- `res.Ancestry` – the parent chain slice
- `res.Children` – the direct descendants slice
- `colorEnabled` – a boolean flag toggling ANSI color codes

The `PrintTree` function in [`internal/output/tree.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/tree.go) implements the core rendering logic using nested iteration over these slices.

### Indentation and Visual Connectors

For each entry in the ancestry and children slices, the renderer calculates indentation using `strings.Repeat("  ", i)`, where `i` represents the depth level. This creates the visual hierarchy that distinguishes parent, target, and child processes.

The function employs Unicode box-drawing characters to create branching lines:
- `└─` indicates the final child in a branch
- `├─` indicates intermediate children with siblings

### Process Labeling

Each node displays its command name and PID using `ChainName(proc)`, a helper that extracts readable command identifiers from the process struct, paired with `proc.PID`. This combination appears at every indentation level to identify processes clearly.

## Child Process Limiting and Truncation

To maintain readable output, `witr` imposes a hard limit of **10 child processes** (`limit := 10` in the source code). When the target process has more than 10 children, the renderer truncates the list and appends a summary line formatted as `… and X more`.

This truncation logic resides in [`internal/output/children.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/children.go), which provides helper utilities for managing overflow scenarios while preserving the visual integrity of the tree structure.

## Colorized Output Support

When `colorEnabled` is true, the tree applies semantic coloring using constants defined in the output package:
- **ColorMagenta** highlights the branch connectors (`└─`, `├─`)
- **ColorGreen** emphasizes the target process name
- **ColorDim** grays out PID numbers for visual hierarchy
- **ColorReset** returns the terminal to default styling

These ANSI codes are applied conditionally throughout [`internal/output/tree.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/tree.go) (lines 16-28 and 59-64) to enhance readability without breaking the ASCII tree alignment.

## Practical Usage Examples

Display the process tree for a specific PID:

```bash
witr tree 1234

```

Enable colorized output for better visual distinction:

```bash
witr tree 1234 --color

```

Typical plain-text output resembles:

```

systemd (pid 1)
  └─ service-manager (pid 500)
    └─ my-app (pid 1234)
      ├─ worker-1 (pid 5678)
      ├─ worker-2 (pid 5679)
      └─ ... and 3 more

```

## Summary

- **Data Collection**: The proc package gathers `model.Process` structs for ancestry and children, storing them as ordered slices.
- **Rendering Engine**: `output.PrintTree` in [`internal/output/tree.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/tree.go) handles indentation via `strings.Repeat` and draws connectors using Unicode characters.
- **Display Limits**: Child processes are capped at 10 entries, with truncation handled by [`internal/output/children.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/children.go).
- **Color Support**: Optional ANSI coloring highlights branches in magenta, target names in green, and PIDs in dim gray.
- **Integration**: `internal/app/app.go:654` orchestrates the flow from data collection to terminal output.

## Frequently Asked Questions

### How does witr handle processes with hundreds of children?

`witr` limits the display to 10 child processes to prevent terminal flooding. If more children exist, it renders the first 10 and appends a `… and X more` line to indicate the total count. This logic is implemented in the children rendering utilities within the output package.

### What determines the indentation depth in the tree output?

The indentation depth corresponds to the process's position in the hierarchy. The renderer uses `strings.Repeat("  ", i)` where `i` increments for each level of ancestry or child depth, creating the visual nested structure in [`internal/output/tree.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/tree.go).

### Can I disable the colors in witr's tree view?

Yes. The `colorEnabled` parameter passed to `output.PrintTree` controls ANSI color codes. You can disable colors by running the command without the color flag or by ensuring your terminal environment doesn't support or request color output, resulting in plain ASCII characters.

### Where is the process name extracted from in the source code?

The readable command name is extracted using the `ChainName(proc)` helper function during the tree rendering phase. This function operates on the `model.Process` struct defined in [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go), which contains the command-line information collected during the initial process discovery phase.