Metadata-Version: 2.4
Name: tlex
Version: 1.0.1
Summary: A safe line editor and viewer for the terminal.
License-Expression: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# tlex

**A safe line editor and viewer for the terminal.**

tlex is built around one idea: you should never change a file by accident.
Opening a file is read-only viewing. A change only happens when you deliberately
open **one line** in a small popup, edit it, and confirm with Enter.
Everything is undoable, and nothing is written until you say so.

It looks like old vim: plain text, no colour clutter, a bar on the current line,
and `:wq` to save and quit. Pure Python, standard library only.

```
 alpha
 beta                                  <- current line (bar)
 gamma
 ~
                                        
 ┌─────────────────────────────────────────────────────────────┬──────┬───────────┐
 │ notes.txt [+]                                               │ VIEW │ Line: 2/3 │
 ├──────────────┬──────────────┬──────────────┬────────────────┴──────┴───────────┤
 │ edit     [e] │ insert   [i] │ delete   [d] │ copy      [y]  ...                │
 └──────────────┴──────────────┴──────────────┴───────────────────────────────────┘
```

## Features

- **Safe by design:** view mode is read-only; unknown keys do nothing.
- **One line at a time:** edit happens in a popup placed on the line itself.
- **Insert between lines:** `i` adds a new line below the current one and opens it for editing. Esc removes it again.
- **Undo** for every change; **delete and paste ask first** (`[y]` = yes, any other key = no).
- **Copy and paste:** copy a line to the system clipboard, put it back with `p`, or paste from the terminal (multi-line paste is detected as one block and asks before inserting).
- **Atomic saves:** written to a temp file and renamed, permissions kept. CRLF files and a missing final newline are preserved.
- **`:q` protects your work:** it refuses to quit with unsaved changes; `:q!` discards on purpose.
- **Configurable:** keys (several per operation), hint table, padding and popup colour are all set in one block at the top of the file.
- **Optional line numbers** (off by default), read-only mode, UTF-8 and wide characters.

## Install

### With pipx (from PyPI)
```bash
pipx install tlex
```

### With pipx (from GitHub)

```bash
pipx install git+https://github.com/datatalisman/tlex
```

### From a clone of the repo

```bash
git clone https://github.com/datatalisman/tlex
cd tlex
./install.sh
```

### Uninstall

```bash
./uninstall.sh          # from the repo directory
# or, if you used pipx directly:
pipx uninstall tlex
```

**Requirements:** Python 3 and a terminal on Linux or macOS (it uses `curses`; Windows is not supported).
For copying to the system clipboard it uses `wl-copy`, `xclip` or `xsel` if available, and falls back to the terminal's OSC 52 clipboard.

## Usage

```bash
tlex notes.txt        # edit (a missing file starts as a new file)
tlex -R notes.txt     # view only, no editing possible
```

### View mode keys

| Key | Action |
|---|---|
| `Up` `Down` `PageUp` `PageDown` | Move |
| `Home` / `g`, `End` / `G` | Top / bottom |
| `e`, `Enter` | Edit the current line (popup, cursor at the start) |
| `i` | Insert a new line below, then edit it |
| `d` | Delete the current line (asks first) |
| `y`, `c` | Copy the current line |
| `p` | Put the copied line below the current one |
| `u` | Undo |
| `n` | Toggle line numbers |
| `:` | Command line |

### Edit / insert popup

| Key | Action |
|---|---|
| `Enter` | Save the line |
| `Esc` | Discard (for `i`, the new line disappears) |
| `Left` `Right` `Home` `End` | Move inside the line |
| `Backspace` `Delete` | Erase |
| terminal paste | Insert at the cursor (multi-line text is joined with spaces) |

Up and Down are ignored in the popup on purpose, so you cannot leave the line by accident.

### Commands (press `:`)

| Command | Action |
|---|---|
| `:w` | Write |
| `:wq` | Write and quit |
| `:q` | Quit (refuses if there are unsaved changes) |
| `:q!` | Quit and discard changes |
| `:N` | Go to line N |

`Esc` followed by `:` works as in vim.

## Configuration

Everything is in the **CONFIG** block at the top of `tlex.py`:

- **`KEYS`:** operation → list of keys. Add as many keys as you like per operation, for example `"copy": ["y", "c"]`. Keys are characters (`"e"`, `":"`) or names (`Enter`, `Esc`, `Tab`, `Space`, `Backspace`, `Delete`, `Up`, `Down`, `Left`, `Right`, `PageUp`, `PageDown`, `Home`, `End`, `Ctrl-S`).
- **`HINTS`:** the cells of the hint table at the bottom. They are generated from `KEYS`, so they update when you change a key. `HINT_SHOW_ALL_KEYS = True` shows every key of an operation (`[y/c]`) instead of the first one.
- **`info_box_padding_top`, `_bottom`, `_left`, `_right`:** blank space around the info box.
- **`popup_theme`:** colour of the popup, chosen from `POPUP_THEMES` (traditional Japanese colours): `ruri`, `kikyo`, `suo`, `rokusho`, `shinbashi`, `botan`, `fujimurasaki`, `yamabuki`. Add your own as `name: (background hex, text hex, description)`.

After editing the config, reinstall (run `./install.sh` again) so the installed copy picks up the change.

## Safety notes

- tlex never modifies the file until you run `:w` or `:wq`.
- Writes go to a temporary file in the same directory and are renamed over the original, so a crash cannot leave a half-written file.
- The undo history lives only while the editor is open.
- Files with bytes that are not valid UTF-8 are kept byte for byte; those bytes are shown as `·`.
