# How to Reorganize Elements Within Documents Using OfficeCLI Move and Swap Commands

> Learn to reorganize document elements like paragraphs and tables using OfficeCLI move and swap commands. Efficiently manipulate content with this powerful tool.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-07-29

---

**OfficeCLI enables you to reorganize elements within documents using the `move` and `swap` commands, which manipulate paragraphs, tables, charts, and slides through a selector-positional model that translates operations into XML patches applied by the Office back-end.**

The iOfficeAI/OfficeCLI repository provides command-line tools for manipulating Office documents without launching the native UI. When you need to reorganize elements within documents using OfficeCLI, the `move` and `swap` commands offer precise control over document structure through positional selectors. These commands leverage a patch-based architecture that streams updates to the server and maintains UI synchronization via Server-Sent Events (SSE).

## Understanding the Selector-Positional Model

Both `move` and `swap` operate on a **selector-positional model** that resolves abstract selectors to concrete DOM nodes. A selector such as `p[3]` targets the third paragraph, while `slide[2]/chart[1]` addresses the first chart on the second slide. The CLI translates these selections into **patches**—discrete operations that the Office back-end applies to the underlying document XML. This architecture ensures atomic updates without corrupting document structure.

## Moving Elements with the `move` Command

The `move` command relocates a single element to a new index within the document hierarchy. According to the source code in [`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js) (approximately line 296), the client-side handler builds a patch of type `move` and transmits it to the server. The server-side `SelectorPositionalIndex` helper located in [`src/officecli/Core/SelectorPositionalIndex.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/SelectorPositionalIndex.cs) recalculates the positional indices and rewrites the underlying XML to reflect the new ordering. After the server applies the update, the SSE listener in [`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js) receives the `patch.op === 'move'` event and re-applies the selection to keep the UI synchronized without a full refresh.

### Syntax and Selector Patterns

The `move` command accepts source and destination selectors following the same grammar used by `get` and `set` verbs:

```bash

# Move the 5th paragraph to become the 2nd paragraph in a Word document

officecli move mydoc.docx "p[5]" "p[2]"

# Move a chart from slide 3 to slide 1 in PowerPoint

officecli move presentation.pptx "slide[3]/chart[1]" "slide[1]"

```

Valid selector patterns include:
- `p[n]` – nth paragraph
- `table[n]` – nth table
- `slide[n]` – nth slide (PowerPoint)
- `chart[n]` – nth chart on a slide
- `sheet[name]` – worksheet by name (Excel)

## Swapping Elements with the `swap` Command

The `swap` command exchanges the positions of two elements atomically. The client creates a patch of type `swap`, processed through the same overlay handler in [`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js). Before application, the validation layer in [`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs) and [`src/officecli/Handlers/ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/ExcelHandler.cs) checks element compatibility and ensures target indices remain within document limits. The [`SelectorPositionalIndex.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/SelectorPositionalIndex.cs) utility then performs the XML transformation, and the SSE core publishes a swap event that the overlay code consumes to update the DOM instantly.

### Cross-Document Type Examples

```bash

# Swap two tables inside a Word file

officecli swap mydoc.docx "table[1]" "table[3]"

# Swap two worksheets inside an Excel workbook

officecli swap report.xlsx "sheet[Finance]" "sheet[Summary]"

```

## Implementation Pipeline and Key Files

The move and swap functionality relies on a coordinated pipeline across multiple source files:

- **[`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js)** – Implements client-side patch generation for move and swap operations (line ~296)
- **[`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js)** – Listens for server patches and updates the DOM accordingly
- **[`src/officecli/Core/SelectorPositionalIndex.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/SelectorPositionalIndex.cs)** – Calculates new indices and rewrites underlying Office XML
- **[`src/officecli/Handlers/WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/WordHandler.cs)** – Validates operations for Word documents, checking bounds and compatibility
- **[`src/officecli/CommandBuilder.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.cs)** – Registers the `move` and `swap` verbs and maps them to handler implementations

## Summary

- The **`move`** command relocates single elements using patches generated in [`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js) and processed server-side by [`SelectorPositionalIndex.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/SelectorPositionalIndex.cs)
- The **`swap`** command exchanges element positions through the same pipeline with validation in [`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs) and [`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs)
- Both commands use **selector syntax** (e.g., `p[5]`, `slide[2]/chart[3]`) to target specific document nodes with path separator support for nested elements
- Changes stream back to the client via SSE through [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) to maintain UI synchronization without full document reloads

## Frequently Asked Questions

### What file types support the move and swap commands in OfficeCLI?

OfficeCLI supports these operations for Word documents (.docx), Excel workbooks (.xlsx), and PowerPoint presentations (.pptx). Each document type has specific handlers—such as [`WordHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.cs) and [`ExcelHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.cs)—that validate element compatibility and ensure the underlying XML structure supports the requested reorganization.

### How does OfficeCLI handle invalid selector indices during a move operation?

The validation layer in the document-specific handlers checks that target indices remain within document limits before applying patches. If a selector references a position beyond the document bounds or targets incompatible element types, the operation aborts before [`SelectorPositionalIndex.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/SelectorPositionalIndex.cs) attempts to rewrite the XML, preventing corruption.

### Can I move nested elements like charts within specific slides?

Yes, you can use combined selectors with path separators such as `slide[3]/chart[1]` to target nested elements. This allows you to move a chart from one slide to another or reorganize charts within the same presentation while maintaining their internal data and formatting.

### What happens if the server patch fails during a swap operation?

The SSE listener in [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) expects confirmation events from the server. If the patch fails validation during handler processing or XML transformation in [`SelectorPositionalIndex.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/SelectorPositionalIndex.cs), the server does not publish the success event, and the client-side DOM remains unchanged, preserving document integrity.