EDITOR
VintLang Editor Module
The editor module provides a simple text editor component for terminal applications. It allows you to create and manipulate text editors within your VintLang applications, which is useful for note-taking apps, configuration editors, and other text-based tools.
Features
- Create and manage text editors
- Set and get text content
- Line-based operations (insert, delete, update, get)
- Vim-like modal editing (normal, insert, command modes)
- Syntax highlighting (basic)
- Line numbering
- File loading and saving
- Customizable dimensions and appearance
Usage
Basic Example
import editor import term // Create a new editor let ed = editor.newEditor({ width: 80, height: 20, showLineNum: true, syntax: "text" }) // Set some initial text editor.setText(ed, "Hello, world!\nThis is a simple text editor.\nTry it out!") // Render the editor let editorContent = editor.render(ed) print(editorContent) // Handle keypresses while (true) { let key = term.getKey() // Handle special keys if (key == "q") { break // Exit the loop } // Pass the key to the editor editor.handleKeypress(ed, key) // Re-render the editor editorContent = editor.render(ed) term.clear() print(editorContent) }
API Reference
newEditor(options)
Creates a new text editor.
Parameters:
options(dict, optional): Options for the editorfilename(string): Initial file to loadwidth(integer): Width of the editor in characters (default: 80)height(integer): Height of the editor in lines (default: 24)showLineNum(boolean): Whether to show line numbers (default: true)syntax(string): Syntax highlighting mode (default: "text")
Returns:
- An editor ID string that can be used with other functions
setText(editorId, text)
Sets the entire text content of the editor.
Parameters:
editorId(string): The editor IDtext(string): The text content to set
Returns:
trueif the text was set successfully
getText(editorId)
Gets the entire text content of the editor.
Parameters:
editorId(string): The editor ID
Returns:
- A string containing the editor's text content
insertLine(editorId, lineNumber, text)
Inserts a new line at the specified position.
Parameters:
editorId(string): The editor IDlineNumber(integer, optional): The line number where to insert the text. If not provided, inserts at the current cursor position.text(string): The text to insert
Returns:
trueif the line was inserted successfully
deleteLine(editorId, lineNumber)
Deletes a line at the specified position.
Parameters:
editorId(string): The editor IDlineNumber(integer, optional): The line number to delete. If not provided, deletes the line at the current cursor position.
Returns:
trueif the line was deleted successfully
updateLine(editorId, lineNumber, text)
Updates a line at the specified position.
Parameters:
editorId(string): The editor IDlineNumber(integer, optional): The line number to update. If not provided, updates the line at the current cursor position.text(string): The new text for the line
Returns:
trueif the line was updated successfully
getLine(editorId, lineNumber)
Gets a line at the specified position.
Parameters:
editorId(string): The editor IDlineNumber(integer, optional): The line number to get. If not provided, gets the line at the current cursor position.
Returns:
- A string containing the line's text
getLineCount(editorId)
Gets the number of lines in the editor.
Parameters:
editorId(string): The editor ID
Returns:
- An integer representing the number of lines
render(editorId)
Renders the editor content as a string.
Parameters:
editorId(string): The editor ID
Returns:
- A string containing the rendered editor content
handleKeypress(editorId, key)
Handles a keypress in the editor.
Parameters:
editorId(string): The editor IDkey(string): The key that was pressed
Returns:
trueif the keypress was handled successfully
save(editorId, filename)
Saves the editor content to a file.
Parameters:
editorId(string): The editor IDfilename(string, optional): The filename to save to. If not provided, uses the editor's current filename.
Returns:
trueif the file was saved successfully
load(editorId, filename)
Loads a file into the editor.
Parameters:
editorId(string): The editor IDfilename(string): The filename to load
Returns:
trueif the file was loaded successfully
Editor Modes
The editor supports three modes of operation, similar to Vim:
- Normal Mode: Default mode for navigation and commands
- Insert Mode: For inserting and editing text
- Command Mode: For executing commands like save and quit
Normal Mode Keys
h: Move cursor leftj: Move cursor downk: Move cursor upl: Move cursor right0: Move to beginning of line$: Move to end of lineG: Move to last linegg: Move to first linex: Delete character under cursordd: Delete current linei: Enter insert modeo: Insert new line below and enter insert modeO: Insert new line above and enter insert mode:: Enter command mode
Insert Mode Keys
Escape: Exit insert modeBackspace: Delete character before cursorEnter: Split line at cursorArrowLeft,ArrowRight,ArrowUp,ArrowDown: Move cursor- Any other key: Insert character at cursor
Command Mode Keys
Escape: Exit command modeEnter: Execute commandBackspace: Delete character before cursor- Any other key: Add character to command
Command Mode Commands
w: Write (save) the fileq: Quit (will warn if there are unsaved changes)q!: Force quit without savingwq: Write and quitset number: Show line numbersset nonumber: Hide line numbers
Examples
Simple Notepad Application
import editor import term import argparse // Parse command line arguments let parser = argparse.newParser("notepad", "A simple notepad application") argparse.addArgument(parser, "file", { description: "File to edit", required: false }) let args = argparse.parse(parser) // Create a new editor let ed = editor.newEditor({ filename: args["file"], width: term.getSize().width, height: term.getSize().height - 2 }) // Main loop term.clear() while (true) { // Render the editor let content = editor.render(ed) term.clear() print(content) // Get keypress let key = term.getKey() // Check for exit key (Ctrl+Q) if (key == "Ctrl+Q") { // Check if there are unsaved changes if (editor.isModified(ed)) { term.println("There are unsaved changes. Press Y to quit anyway, or any other key to cancel.") let confirm = term.getKey() if (confirm.toLowerCase() != "y") { continue } } break } // Check for save key (Ctrl+S) if (key == "Ctrl+S") { let filename = args["file"] if (!filename) { term.println("Enter filename to save: ") filename = term.input() args["file"] = filename } editor.save(ed, filename) continue } // Handle the keypress in the editor editor.handleKeypress(ed, key) } term.clear() term.println("Goodbye!")
Configuration Editor
import editor import term import os import json // Function to load a JSON configuration file let loadConfig = func(filename) { if (!os.exists(filename)) { return { "server": { "host": "localhost", "port": 8080 }, "database": { "host": "localhost", "port": 5432, "user": "admin", "password": "password" }, "logging": { "level": "info", "file": "app.log" } } } let content = open(filename) return JSON.parse(content) } // Function to save a JSON configuration file let saveConfig = func(filename, config) { let content = JSON.stringify(config, null, 2) os.writeFile(filename, content) } // Function to edit a configuration section let editSection = func(section, data) { // Convert the section data to a string let text = JSON.stringify(data, null, 2) // Create an editor let ed = editor.newEditor({ width: term.getSize().width, height: term.getSize().height - 4, syntax: "json" }) // Set the text editor.setText(ed, text) // Edit loop term.clear() while (true) { // Render the editor let content = editor.render(ed) term.clear() term.println("Editing " + section + " configuration", "#ffcc00") term.println("Press Ctrl+S to save, Ctrl+Q to cancel", "#88ff88") print(content) // Get keypress let key = term.getKey() // Check for exit key (Ctrl+Q) if (key == "Ctrl+Q") { return null } // Check for save key (Ctrl+S) if (key == "Ctrl+S") { let newText = editor.getText(ed) try { return JSON.parse(newText) } catch (e) { term.println("Error parsing JSON: " + e, "#ff5555") term.println("Press any key to continue", "#88ff88") term.getKey() continue } } // Handle the keypress in the editor editor.handleKeypress(ed, key) } } // Main function let main = func() { let configFile = "config.json" let config = loadConfig(configFile) while (true) { // Display menu term.clear() term.println("=== Configuration Editor ===", "#ffcc00") term.println("1. Edit Server Configuration", "#88ff88") term.println("2. Edit Database Configuration", "#88ff88") term.println("3. Edit Logging Configuration", "#88ff88") term.println("4. Save Configuration", "#88ff88") term.println("5. Exit", "#88ff88") term.println("===========================", "#ffcc00") term.print("Enter your choice: ") let choice = term.input() if (choice == "1") { let result = editSection("server", config.server) if (result) { config.server = result } } else if (choice == "2") { let result = editSection("database", config.database) if (result) { config.database = result } } else if (choice == "3") { let result = editSection("logging", config.logging) if (result) { config.logging = result } } else if (choice == "4") { saveConfig(configFile, config) term.println("Configuration saved to " + configFile, "#88ff88") term.println("Press any key to continue", "#88ff88") term.getKey() } else if (choice == "5") { break } } term.clear() term.println("Goodbye!", "#88ff88") } main()
Markdown Editor with Preview
import editor import term import os import markdown // Function to convert markdown to HTML let markdownToHtml = func(text) { // This is a simplified markdown converter let html = text // Convert headers html = html.replace(/^# (.+)$/gm, "<h1>$1</h1>") html = html.replace(/^## (.+)$/gm, "<h2>$1</h2>") html = html.replace(/^### (.+)$/gm, "<h3>$1</h3>") // Convert bold and italic html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>") html = html.replace(/\*(.+?)\*/g, "<em>$1</em>") // Convert lists html = html.replace(/^- (.+)$/gm, "<li>$1</li>") // Convert links html = html.replace(/\[(.+?)\]\((.+?)\)/g, "<a href=\"$2\">$1</a>") return html } // Function to display a preview of the markdown let previewMarkdown = func(text) { let html = markdownToHtml(text) // Display the HTML preview term.clear() term.println("=== Markdown Preview ===", "#ffcc00") term.println(html) term.println("========================", "#ffcc00") term.println("Press any key to return to editor", "#88ff88") term.getKey() } // Main function let main = func() { // Check command line arguments if (args.length < 2) { term.println("Usage: vint markdown_editor.vint <filename>", "#ff5555") exit(1) } let filename = args[1] // Create an editor let ed = editor.newEditor({ filename: filename, width: term.getSize().width, height: term.getSize().height - 2, syntax: "markdown" }) // Main loop term.clear() while (true) { // Render the editor let content = editor.render(ed) term.clear() term.println("Markdown Editor - " + filename, "#ffcc00") term.println("Ctrl+S: Save | Ctrl+P: Preview | Ctrl+Q: Quit", "#88ff88") print(content) // Get keypress let key = term.getKey() // Check for exit key (Ctrl+Q) if (key == "Ctrl+Q") { if (editor.isModified(ed)) { term.println("There are unsaved changes. Press Y to quit anyway, or any other key to cancel.") let confirm = term.getKey() if (confirm.toLowerCase() != "y") { continue } } break } // Check for save key (Ctrl+S) if (key == "Ctrl+S") { editor.save(ed, filename) continue } // Check for preview key (Ctrl+P) if (key == "Ctrl+P") { let text = editor.getText(ed) previewMarkdown(text) continue } // Handle the keypress in the editor editor.handleKeypress(ed, key) } term.clear() term.println("Goodbye!", "#88ff88") } main()