Hayden Hargreaves 7a7472fd12
All checks were successful
Run Test Suite / test (push) Successful in 17s
feat: implemtned H, M, L screen actions, tested
2026-04-06 21:04:51 -07:00
2026-04-03 14:38:08 -07:00
2026-02-08 23:05:59 -07:00
2026-04-04 11:08:33 -07:00
2026-04-03 15:20:47 -07:00


   ██████╗ ██╗███╗   ███╗
  ██╔════╝ ██║████╗ ████║
  ██║  ███╗██║██╔████╔██║
  ██║   ██║██║██║╚██╔╝██║
  ╚██████╔╝██║██║ ╚═╝ ██║
   ╚═════╝ ╚═╝╚═╝     ╚═╝
  

Go + Vim = Gim

A blazingly fast, terminal-based text editor with vim-style keybindings

FeaturesInstallationKeybindingsArchitectureRoadmap

Go Version BubbleTea Lipgloss License


What is Gim?

Gim is a modern, lightweight text editor written in Go that brings the power of vim-style modal editing to your terminal. Built on the excellent Charm stack, it combines the speed of Go with the elegance of functional UI patterns.

┌──────────────────────────────────────────────────────────────┐
│  Why Gim?                                                    │
├──────────────────────────────────────────────────────────────┤
│  🚀 Fast          - Native Go performance                    │
│  🎨 Beautiful     - Lipgloss-powered terminal styling        │
│  🧠 Vim-like      - Modal editing for efficiency             │
│  🧪 Well-tested   - Comprehensive integration test suite     │
│  📦 Single binary - No dependencies, just run                │
└──────────────────────────────────────────────────────────────┘

Trade Offs

Undo Tree vs. Undo Stack

While the undo tree method that vim uses is powerful, I rarely find myself using it. A stack terminal-based approach is more natural to "non-vim" users and much simpler to implement. Implementing a feature similar to Vims undo tree would many times longer than a simple stack.

Vim-like Replace vs. Custom Replace

The way that vim's replace mode is implemented is quite complex, keeping track of the previous line backspace can only delete newly replaced characters. This is a complex feature, one that I rarely use, and even find a bit un-intuitive. Implementing replace mode in a way where all actions function the same as insert mode (other than the actual character typing) allows for a much simpler implementation, as well as a more intuitive user experience.

Replace mode implements and replaces (no pun intended) the last inserted keys of insert mode. Due to the infrequent use of replace mode, and the '.' action for insert mode, this felt like a natural trade off.


TODO List

  • Ops like change, and substitute and such should add to paste reg
  • Delete op should also add to paste reg
  • Gap buffer implementation (this shouldn't be TOO hard)
  • Alternate buffer handling and implementation
  • Scroll in X direction

🎯 Features

🎭 Six Editor Modes

Mode Key Description
Normal Esc Navigate and command - your home base
Insert i/a/o Type and create
Visual v Select characters
Visual Line V Select whole lines
Visual Block Ctrl+V Select rectangular regions
Command : Execute commands (coming soon)

⌨️ Full Motion System

         gg
          ↑
    b ←── · ──→ w/e
          ↓
          G

      0 ──────── $
      │  _       │
      └──┴───────┘
         line
  • Character motions: h j k l - The classics
  • Word motions: w e b - Jump by word boundaries
  • Line motions: 0 $ _ - Start, end, first non-whitespace
  • File motions: gg G - Top and bottom of file

🔧 Powerful Operators

Operator Action Examples
d Delete dd dw d$ dG
x Delete char x 3x

Operators compose with motions and counts!

  3    d    2w
  ↓    ↓    ↓
count  op  motion

= Delete 6 words (3 × 2)

🎪 Visual Mode Magic

Select text visually, then operate on it:

┌─────────────────────────────────┐
│ Hello, [world! How] are you?   │  ← v + motion + d
│ Hello, are you?                │  ← Result
└─────────────────────────────────┘

┌─────────────────────────────────┐
│ [Line one                    ] │
│ [Line two                    ] │  ← V + j + d
│ [Line three                  ] │
│                                │  ← All lines deleted
└─────────────────────────────────┘

🔢 Count Everything

Prefix any command with a number:

Input Action
5j Move down 5 lines
3dd Delete 3 lines
10i=Esc Insert ==========
2d3w Delete 6 words

🪟 Smart Scrolling

  • Automatic viewport following
  • scrollOff margin keeps context visible
  • Smooth cursor tracking

📦 Installation

From Source

# Clone the repository
git clone https://git.gophernest.net/azpect/TextEditor.git
cd TextEditor

# Build
go build -o gim ./cmd/gim

# Run
./gim [filename]

Quick Run

go run ./cmd/gim [filename]

⌨️ Keybindings

Normal Mode

🧭 Navigation
Key Action
h Move left
j Move down
k Move up
l Move right
w Next word start
e Next word end
b Previous word start
0 Line start
$ Line end
_ First non-whitespace
gg File start
G File end
✏️ Entering Insert Mode
Key Action
i Insert before cursor
a Insert after cursor
I Insert at line start
A Insert at line end
o Open line below
O Open line above
🗑️ Deletion
Key Action
x Delete character
dd Delete line
d{motion} Delete to motion
D Delete to end of line
👁️ Visual Mode
Key Action
v Character visual
V Line visual
Ctrl+V Block visual

Insert Mode

Key Action
Esc Return to normal
Backspace Delete previous char
Delete Delete next char
Ctrl+W Delete previous word
Tab Insert tab (2 spaces)
Enter New line
↑↓←→ Navigate

Visual Mode

All normal mode navigation keys work, plus:

Key Action
d Delete selection
Esc Return to normal

🏗️ Architecture

Gim follows a clean, modular architecture inspired by the Elm Architecture (Model-Update-View):

┌─────────────────────────────────────────────────────────────┐
│                        cmd/gim/                             │
│                      Entry Point                            │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                     internal/editor/                        │
│              Model • Update • View • Style                  │
└─────────────────────────────────────────────────────────────┘
          │                   │                    │
          ▼                   ▼                    ▼
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│ internal/input/ │  │ internal/motion/│  │internal/operator│
│    Handler      │  │   h j k l w e   │  │    d (delete)   │
│    Keymap       │  │   b 0 $ gg G    │  │                 │
└─────────────────┘  └─────────────────┘  └─────────────────┘
          │                   │                    │
          └───────────────────┴────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                     internal/action/                        │
│         Action • Motion • Operator • Position               │
│                    (Core Interfaces)                        │
└─────────────────────────────────────────────────────────────┘

Key Design Patterns

  • 🔌 Interface-based: Actions/motions use a Model interface, enabling clean testing
  • 🎭 State Machine: Input handler manages mode transitions and pending operations
  • 📐 Motion Types: Linewise vs Charwise motions for proper operator behavior
  • 🔄 Composition: Operators compose with motions (e.g., d + w = delete word)

🧪 Testing

Gim has comprehensive integration tests using the teatest library:

# Run all tests
go test ./...

# Run with verbose output
go test -v ./internal/editor/

# Run specific test
go test -v -run TestDeleteOperator ./internal/editor/

Test Coverage Areas:

  • Basic motions (hjkl)
  • Jump motions (gg, G, 0, $, _)
  • Word motions (w, e, b)
  • Delete operator with all motions
  • Insert mode (all entry points, recording, replay)
  • Visual mode (all three types)
  • Scrolling behavior

🗺️ Roadmap

Implemented

  • Modal editing (Normal, Insert, Visual, Visual Line, Visual Block)
  • Basic motions (hjkl, word motions, line motions)
  • Delete operator with motion composition
  • Count prefixes for all commands
  • Insert mode with recording/replay
  • Visual selection with operators
  • Smart scrolling with scrollOff
  • Relative line numbers

🚧 In Progress

  • Command mode (: commands)
  • File I/O (save/load)

🔮 Future

  • Operators: y (yank), c (change), p (paste)
  • Motions: f/F/t/T (find char), //? (search), {/} (paragraph)
  • Features:
    • Undo/redo system
    • Multiple buffers/tabs
    • Syntax highlighting
    • Configuration file
    • Clipboard integration
    • Macros (q recording)
    • Marks (m and ')
    • Registers (")
    • Text objects (iw, a", etc.)
    • Plugins system

🎨 Built With

BubbleTea

  • BubbleTea - The fun, functional TUI framework
  • Lipgloss - Style definitions for terminal apps
  • Go - The language that makes it all possible

🤝 Contributing

Contributions are welcome! Whether it's:

  • 🐛 Bug fixes
  • New features
  • 📖 Documentation improvements
  • 🧪 Test coverage

Feel free to open issues and pull requests!


📜 License

This project is open source. See LICENSE for details.


Made with 💜 and lots of

"Because sometimes you just want to build your own vim"

Description
Vim-inspired text editor written in Go.
Readme 4.2 MiB
Languages
Go 99.8%
Nix 0.2%