Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions dev/backlog.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
Website
16. everywhere in web page should use buffee

Model.end should return coordinate not just last line

Rename Mode to State

TODO: consolidate 182-220 on extensions.md

Arrow key with selection: VSCode moves additional row after collapse (e.g., up with selection → collapse to start → move up one more). Current behavior just collapses. Revisit if users expect VSCode behavior.
55 changes: 31 additions & 24 deletions samples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
<title>buffee - Examples</title>
<link rel="stylesheet" href="../assets/reset.css">
<link rel="stylesheet" href="../style.css">
<style>
table { border: none; margin-bottom: 2rem; margin-left: 1rem; }
td { padding: 0.25rem 0.5rem; text-align: left; border: none; }
td:first-child { white-space: nowrap; }
td:first-child::before { content: "•"; margin-right: 0.5rem; }
</style>
</head>
<body>
<nav id="nav"></nav>
Expand All @@ -18,32 +24,33 @@
<h1>Examples</h1>

<h2>Core</h2>
<ul>
<li><a href="sample-basic.html">sample-basic</a> - Simple editable text editor</li>
<li><a href="sample-gutter-status.html">sample-gutter-status</a> - Gutter and status bar options</li>
<li><a href="sample-sizing.html">sample-sizing</a> - Editor sizing with character units</li>
</ul>

<h2>Combinators</h2>
<ul>
<li><a href="sample-history.html">sample-history</a> - Undo/redo with history combinator</li>
<li><a href="sample-undotree.html">sample-undotree</a> - Tree-based undo with branch navigation</li>
<li><a href="sample-syntax.html">sample-syntax</a> - Regex-based syntax highlighting</li>
<li><a href="sample-elementals.html">sample-elementals</a> - Layer-based UI elements (DOM nodes)</li>
<li><a href="sample-tui.html">sample-tui</a> - TUI elements via text manipulation</li>
<li><a href="sample-loader.html">sample-loader</a> - Load files with millions/billions of lines</li>
<li><a href="sample-readonly.html">sample-readonly</a> - Read-only mode (TUI and UHC)</li>
<li><a href="sample-ios.html">sample-ios</a> - iOS touch and keyboard support</li>
<li><a href="sample-sanitize.html">sample-sanitize</a> - Tab and Unicode sanitization</li>
<li><a href="sample-vimmotion.html">sample-vimmotion</a> - Vim-style motion commands</li>
</ul>
<table>
<tr><td><a href="sample-recommended.html">recommended</a></td><td>Recommended setup with StatusLine and History</td></tr>
<tr><td><a href="sample-basic.html">basic</a></td><td>Simple editable text editor</td></tr>
<tr><td><a href="sample-gutter-status.html">gutter-status</a></td><td>Gutter and status bar options</td></tr>
<tr><td><a href="sample-sizing.html">sizing</a></td><td>Editor sizing with character units</td></tr>
</table>

<h2>Fun Examples</h2>
<ul>
<li><a href="sample-movie.html">sample-movie</a> - Star Wars ASCII animation player</li>
<li><a href="sample-matrix.html">sample-matrix</a> - Matrix digital rain effect</li>
<li><a href="sample-conway.html">sample-conway</a> - Conway's Game of Life</li>
</ul>
<table>
<tr><td><a href="sample-movie.html">movie</a></td><td>Star Wars ASCII animation player</td></tr>
<tr><td><a href="sample-matrix.html">matrix</a></td><td>Matrix digital rain effect</td></tr>
<tr><td><a href="sample-conway.html">conway</a></td><td>Conway's Game of Life</td></tr>
</table>

<h2>Combinators</h2>
<table>
<tr><td><a href="sample-history.html">history</a></td><td>Undo/redo with history combinator</td></tr>
<tr><td><a href="sample-undotree.html">undotree</a></td><td>Tree-based undo with branch navigation</td></tr>
<tr><td><a href="sample-syntax.html">syntax</a></td><td>Regex-based syntax highlighting</td></tr>
<tr><td><a href="sample-elementals.html">elementals</a></td><td>Layer-based UI elements (DOM nodes)</td></tr>
<tr><td><a href="sample-tui.html">tui</a></td><td>TUI elements via text manipulation</td></tr>
<tr><td><a href="sample-loader.html">loader</a></td><td>Load files with millions/billions of lines</td></tr>
<tr><td><a href="sample-readonly.html">readonly</a></td><td>Read-only mode (TUI and UHC)</td></tr>
<tr><td><a href="sample-ios.html">ios</a></td><td>iOS touch and keyboard support</td></tr>
<tr><td><a href="sample-sanitize.html">sanitize</a></td><td>Tab and Unicode sanitization</td></tr>
<tr><td><a href="sample-vimmotion.html">vimmotion</a></td><td>VimMotion combinator</td></tr>
</table>

</body>
</html>
7 changes: 7 additions & 0 deletions samples/sample-elementals.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / Elementals</p>

<h1>Elementals - Layer-based UI</h1>
<p><a href="../combinators/elementals.js">combinators/elementals.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/elementals.js"&gt;&lt;/script&gt;</pre>
<pre>const editor = BuffeeElementals(Buffee(container, config))
editor.Elementals.addButton({ row: 1, col: 5, label: 'OK' })
editor.Elementals.enabled = true</pre>
<p>Unlike tui-legacy which manipulates text content, Elementals creates actual DOM elements in a layer above the text.</p>
<p>Press <kbd>Tab</kbd> to navigate, <kbd>Enter</kbd> to activate</p>

Expand Down
8 changes: 8 additions & 0 deletions samples/sample-history.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / History Combinator</p>

<h1>History Combinator (Undo/Redo)</h1>
<p><a href="../combinators/history.js">combinators/history.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/history.js"&gt;&lt;/script&gt;</pre>
<pre>BuffeeHistory(editor)
editor.History.undo()
editor.History.redo()
editor.History.clear()</pre>
<p>History tracking is opt-in. By default, editors have no undo/redo.</p>

<h2>Without History</h2>
Expand Down
10 changes: 10 additions & 0 deletions samples/sample-ios.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / iOS Support</p>

<h1>iOS Support</h1>
<p><a href="../combinators/ios.js">combinators/ios.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/ios.js"&gt;&lt;/script&gt;</pre>
<pre>let editor = Buffee(container, config)
if (/iPad|iPhone|iPod/.test(navigator.userAgent)) {
editor = BuffeeIOS(editor)
}
editor.iOS.focus() // Show keyboard
editor.iOS.destroy() // Cleanup</pre>
<p>Touch interactions and on-screen keyboard input for iOS devices.</p>

<h2>JavaScript</h2>
Expand Down
15 changes: 15 additions & 0 deletions samples/sample-loader.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / Ultra High Capacity</p>

<h1>Ultra High Capacity</h1>
<p><a href="../combinators/fileloader.js">combinators/fileloader.js</a> | <a href="../combinators/ultrahighcapacity.js">combinators/ultrahighcapacity.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/fileloader.js"&gt;&lt;/script&gt;
&lt;script src="combinators/ultrahighcapacity.js"&gt;&lt;/script&gt;</pre>
<pre>// FileLoader - multiple loading strategies
const editor = BuffeeFileLoader(BuffeeSanitize(Buffee(container, config)))
await editor.FileLoader.naiveLoad(file) // &lt;10M lines
await editor.FileLoader.chunkedBlobLoad(file) // &lt;70M lines
await editor.FileLoader.streamLoad(file)

// UltraHighCapacity - gzip-compressed for 1B+ lines
const editor = BuffeeUltraHighCapacity(Buffee(container, config))
editor.UltraHighCapacity.activate(50000)
await editor.UltraHighCapacity.appendLines(lines)</pre>
<p>Load and display files with millions or billions of lines using various loading strategies.</p>

<div id="read-only-indicator" class="read-only-indicator hidden">
Expand Down
1 change: 1 addition & 0 deletions samples/sample-readonly.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / Read-Only Mode</p>

<h1>Read-Only Mode</h1>
<p><a href="../combinators/tui.js">combinators/tui.js</a> | <a href="../combinators/ultrahighcapacity.js">combinators/ultrahighcapacity.js</a></p>
<p>The following scenarios for the editor into various kinds of read-only mode.</p>

<h2>1. TUI </h2>
Expand Down
76 changes: 76 additions & 0 deletions samples/sample-recommended.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>buffee - Recommended Setup</title>
<script src="../buffe.js"></script>
<script src="../buffee.js"></script>
<script src="../combinators/statusline.js"></script>
<script src="../combinators/history.js"></script>
<link rel="stylesheet" href="../assets/reset.css">
<link rel="stylesheet" href="../style.css">
<link rel="stylesheet" href="../themes/theme-boring.css">
</head>
<body class="sample">
<nav id="nav"></nav>
<script>
fetch('../web/navigation.html')
.then(r => r.text())
.then(html => document.getElementById('nav').innerHTML = html);
</script>
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / Recommended Setup</p>

<h1>Recommended Setup</h1>
<p>The recommended configuration for most use cases: status bar and undo/redo.</p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/statusline.js"&gt;&lt;/script&gt;
&lt;script src="combinators/history.js"&gt;&lt;/script&gt;</pre>
<pre>const editor = BuffeeHistory(BuffeeStatusLine(new Buffee(el, { h: 20 })))</pre>

<div class="buffee buffee-themepack1-boring" id="editor">
<div class="no-select buffee-pane">
<div class="buffee-rail"></div>
<div class="buffee-lines" tabindex="0">
<div class="buffee-zsel"></div>
<blockquote class="buffee-ztxt"></blockquote>
<div class="buffee-layer-elements"></div>
<div class="buffee-caret"></div>
</div>
</div>
<div class="buffee-status">
<div class="buffee-status-left"><span class="buffee-linecount"></span></div>
<div class="buffee-status-right">
Ln <span class="buffee-head-row"></span>, Col <span class="buffee-head-col"></span>
<span class="buffee-status-divider">|</span>
<span class="buffee-spaces"></span>
</div>
</div>
</div>

<h2>Features</h2>
<ul>
<li><strong>StatusLine</strong> - Updates line count, cursor position in status bar</li>
<li><strong>History</strong> - Undo with <kbd>Cmd+Z</kbd>, redo with <kbd>Cmd+Shift+Z</kbd></li>
</ul>

<script>
const el = document.getElementById('editor');
const editor = BuffeeHistory(BuffeeStatusLine(new Buffee(el, { h: 15 })));

editor.Model._ = [
'// Recommended Buffee Setup',
'// Try typing and using Cmd+Z to undo',
'',
'function greet(name) {',
' return "Hello, " + name + "!";',
'}',
'',
'console.log(greet("World"));'
];
editor.View.render();

el.focus();
</script>
</body>
</html>
13 changes: 13 additions & 0 deletions samples/sample-sanitize.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / Sanitize Combinator</p>

<h1>Sanitize Combinator</h1>
<p><a href="../combinators/sanitize.js">combinators/sanitize.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/sanitize.js"&gt;&lt;/script&gt;</pre>
<pre>const editor = BuffeeSanitize(new Buffee(container, config))

// Automatic sanitization on Span.ins() calls
editor.Span.ins("text\twith\ttabs") // tabs become spaces

// Manual sanitization utilities
editor.Sanitize.line("hello\tworld") // "hello world"
editor.Sanitize.text("a\tb\nc\td") // sanitize multi-line string
editor.Sanitize.lines(["a\tb", "c\td"]) // sanitize array of lines</pre>
<p>Automatically converts tabs to spaces and normalizes problematic Unicode characters.</p>
<p><code>BuffeeSanitize(new Buffee(el, {}))</code></p>

Expand Down
7 changes: 7 additions & 0 deletions samples/sample-syntax.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / Syntax Highlighting</p>

<h1>Syntax Highlighting</h1>
<p><a href="../combinators/syntax.js">combinators/syntax.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/syntax.js"&gt;&lt;/script&gt;</pre>
<pre>const editor = BuffeeSyntax(Buffee(container, config))
editor.Syntax.setLanguage('javascript')
editor.Syntax.enabled = true</pre>
<p>Regex-based tokenizer with incremental state caching.</p>

<p>
Expand Down
7 changes: 7 additions & 0 deletions samples/sample-tui.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / TUI Elements</p>

<h1>TUI Elements</h1>
<p><a href="../combinators/tui.js">combinators/tui.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/tui.js"&gt;&lt;/script&gt;</pre>
<pre>const editor = BuffeeTUI(Buffee(container, config))
editor.TUI.addButton({ row: 1, col: 2, label: 'OK', border: true })
editor.TUI.enabled = true</pre>
<p>Press <kbd>Tab</kbd> to navigate, <kbd>Enter</kbd> to activate</p>

<h2>Buttons (no border)</h2>
Expand Down
11 changes: 11 additions & 0 deletions samples/sample-undotree.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / Undo Tree Combinator</p>

<h1>Undo Tree Combinator</h1>
<p><a href="../combinators/undotree.js">combinators/undotree.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/undotree.js"&gt;&lt;/script&gt;</pre>
<pre>BuffeeUndoTree(editor)
editor.UndoTree.undo()
editor.UndoTree.redo() // Follow most recent branch
editor.UndoTree.redo(0) // Follow specific branch
editor.UndoTree.branches() // Get available branches
editor.UndoTree.goToNode(id) // Jump to any node
editor.UndoTree.getTree() // Get tree for visualization</pre>
<p>Unlike linear history, undo tree preserves <strong>all branches</strong>. When you undo and make a new edit, you create a new branch instead of losing history.</p>

<div class="controls">
Expand Down
20 changes: 20 additions & 0 deletions samples/sample-vimmotion.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,26 @@
<p><a href="../index.html">home</a> / <a href="index.html">samples</a> / VimMotion Extension</p>

<h1>VimMotion Extension</h1>
<p><a href="../combinators/vimmotion.js">combinators/vimmotion.js</a></p>
<pre>&lt;script src="buffe.js"&gt;&lt;/script&gt;
&lt;script src="buffee.js"&gt;&lt;/script&gt;
&lt;script src="combinators/vimmotion.js"&gt;&lt;/script&gt;</pre>
<pre>const editor = BuffeeVimMotion(new Buffee(container, config))

// Basic motions
editor.VimMotion.move('h') // left
editor.VimMotion.move('j') // down
editor.VimMotion.move('5j') // down 5 lines

// Word motions
editor.VimMotion.move('w') // next word start
editor.VimMotion.move('b') // previous word start

// Line motions
editor.VimMotion.move('0') // start of line
editor.VimMotion.move('$') // end of line
editor.VimMotion.move('gg') // first line
editor.VimMotion.move('G') // last line</pre>
<p>Adds vim-style motion commands with count support to Buffee.</p>
<p><code>BuffeeVimMotion(new Buffee(el, { h: 15 }))</code></p>

Expand Down
Loading
Loading