discovery-fast-text 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Discovery Open Source Foundation
4
+ ... (Standard MIT License text) ...
5
+
@@ -0,0 +1,31 @@
1
+ Metadata-Version: 2.4
2
+ Name: discovery-fast-text
3
+ Version: 1.0.0
4
+ Summary: Vim-speed CLI editor with Nano ease and Incognito mode.
5
+ Author: Discovery Open Source Foundation
6
+ Author-email: Discovery Open Source Foundation <discovery@fast-txt.com>
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: textual>=0.40.0
14
+ Requires-Dist: pygments>=2.15.0
15
+ Requires-Dist: cryptography>=41.0.0
16
+ Dynamic: author
17
+ Dynamic: license-file
18
+ Dynamic: requires-python
19
+
20
+ # Fast-Text Pro
21
+ A high-performance CLI editor by **Discovery Open Source Foundation**.
22
+
23
+ ## Features
24
+ - **Fast**: Vim-like navigation and lightweight.
25
+ - **Secure**: Incognito mode with AES encryption for backups.
26
+ - **Retro**: Classic MS-DOS Edit TUI.
27
+ - **Smart**: Syntax highlighting and Auto-complete.
28
+
29
+ ## Installation
30
+ ```bash
31
+ pip install .
@@ -0,0 +1,12 @@
1
+ # Fast-Text Pro
2
+ A high-performance CLI editor by **Discovery Open Source Foundation**.
3
+
4
+ ## Features
5
+ - **Fast**: Vim-like navigation and lightweight.
6
+ - **Secure**: Incognito mode with AES encryption for backups.
7
+ - **Retro**: Classic MS-DOS Edit TUI.
8
+ - **Smart**: Syntax highlighting and Auto-complete.
9
+
10
+ ## Installation
11
+ ```bash
12
+ pip install .
@@ -0,0 +1,31 @@
1
+ Metadata-Version: 2.4
2
+ Name: discovery-fast-text
3
+ Version: 1.0.0
4
+ Summary: Vim-speed CLI editor with Nano ease and Incognito mode.
5
+ Author: Discovery Open Source Foundation
6
+ Author-email: Discovery Open Source Foundation <discovery@fast-txt.com>
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: textual>=0.40.0
14
+ Requires-Dist: pygments>=2.15.0
15
+ Requires-Dist: cryptography>=41.0.0
16
+ Dynamic: author
17
+ Dynamic: license-file
18
+ Dynamic: requires-python
19
+
20
+ # Fast-Text Pro
21
+ A high-performance CLI editor by **Discovery Open Source Foundation**.
22
+
23
+ ## Features
24
+ - **Fast**: Vim-like navigation and lightweight.
25
+ - **Secure**: Incognito mode with AES encryption for backups.
26
+ - **Retro**: Classic MS-DOS Edit TUI.
27
+ - **Smart**: Syntax highlighting and Auto-complete.
28
+
29
+ ## Installation
30
+ ```bash
31
+ pip install .
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ discovery_fast_text.egg-info/PKG-INFO
6
+ discovery_fast_text.egg-info/SOURCES.txt
7
+ discovery_fast_text.egg-info/dependency_links.txt
8
+ discovery_fast_text.egg-info/entry_points.txt
9
+ discovery_fast_text.egg-info/requires.txt
10
+ discovery_fast_text.egg-info/top_level.txt
11
+ fast_text/__init__.py
12
+ fast_text/editor.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ft = fast_text.editor:main
@@ -0,0 +1,3 @@
1
+ textual>=0.40.0
2
+ pygments>=2.15.0
3
+ cryptography>=41.0.0
@@ -0,0 +1 @@
1
+ from .editor import main
@@ -0,0 +1,199 @@
1
+ import os
2
+ import sys
3
+ import json
4
+ from cryptography.fernet import Fernet
5
+ from textual.app import App, ComposeResult
6
+ from textual.widgets import TextArea, Footer, Header, TabbedContent, TabPane, Static, Input
7
+ from textual.binding import Binding
8
+ from textual.screen import ModalScreen
9
+ from textual.containers import Grid
10
+
11
+ # --- GLOBAL SETTINGS & PATHS ---
12
+ HOME = os.path.expanduser("~")
13
+ CONFIG_PATH = os.path.join(HOME, ".ftrc")
14
+ BACKUP_DIR = os.path.join(HOME, ".fast_text_backups")
15
+
16
+ # Ensure our backup folder exists
17
+ os.makedirs(BACKUP_DIR, exist_ok=True)
18
+
19
+ # Generate or load a key for Incognito mode
20
+ # In a real dev environment, we'd store this in a keychain, but this works for now!
21
+ KEY_FILE = os.path.join(HOME, ".ft_key")
22
+ if not os.path.exists(KEY_FILE):
23
+ with open(KEY_FILE, "wb") as kf:
24
+ kf.write(Fernet.generate_key())
25
+ with open(KEY_FILE, "rb") as kf:
26
+ CIPHER = Fernet(kf.read())
27
+
28
+ class AboutScreen(ModalScreen):
29
+ """The 'Easter Egg' screen for credits."""
30
+ def compose(self) -> ComposeResult:
31
+ yield Grid(
32
+ Static("🚀 FAST-TEXT PRO\n\n"
33
+ "A Discovery Open Source Foundation Project\n"
34
+ "Built for speed, security, and nostalgia.\n\n"
35
+ "[Press ESC to Return]", id="egg-content"),
36
+ id="egg-box"
37
+ )
38
+
39
+ class FastText(App):
40
+ """
41
+ Main Editor Class.
42
+ Design Goal: Combine Nano's UI, Vim's Speed, and MS-Edit's Look.
43
+ """
44
+
45
+ # Define our custom 'Discovery' blue theme
46
+ CSS = """
47
+ Screen { background: #0000AA; }
48
+ Header { background: #AAAAAA; color: #000000; }
49
+ Footer { background: #AAAAAA; color: #000000; }
50
+ #status-bar { background: #AAAAAA; color: #000000; height: 1; dock: bottom; padding: 0 1; }
51
+ TextArea { background: #0000AA; color: #FFFFFF; border: none; }
52
+ Input { dock: top; background: #0000AA; color: #FFFFFF; border: double #FFFFFF; display: none; }
53
+ .show-palette { display: block !important; }
54
+
55
+ #egg-box { align: center middle; }
56
+ #egg-content {
57
+ width: 50; height: 15;
58
+ background: #000088;
59
+ border: double #FFFF00;
60
+ color: #FFFF00;
61
+ padding: 2;
62
+ text-align: center;
63
+ }
64
+ """
65
+
66
+ BINDINGS = [
67
+ Binding("ctrl+s", "save", "Save"),
68
+ Binding("ctrl+p", "palette", "Cmd"),
69
+ Binding("ctrl+i", "toggle_incognito", "Incognito"),
70
+ Binding("ctrl+e", "credits", "About"),
71
+ Binding("ctrl+q", "quit", "Exit"),
72
+ ]
73
+
74
+ def __init__(self, target_files):
75
+ super().__init__()
76
+ self.target_files = target_files if target_files else ["untitled.txt"]
77
+ self.incognito = False
78
+ self.user_config = self.load_config()
79
+
80
+ def load_config(self):
81
+ """Load user preferences like theme or default language."""
82
+ if os.path.exists(CONFIG_PATH):
83
+ with open(CONFIG_PATH, "r") as f:
84
+ return json.load(f)
85
+ return {"theme": "monokai", "incognito_default": False}
86
+
87
+ def compose(self) -> ComposeResult:
88
+ yield Header(show_clock=True)
89
+ yield Input(placeholder="Commands: find <text> | replace <old> <new> | goto <line>")
90
+
91
+ with TabbedContent() as self.tabs:
92
+ for i, filename in enumerate(self.target_files):
93
+ with TabPane(filename, id=f"tab-{i}"):
94
+ # Initialize the editor for each file
95
+ editor = TextArea(id=f"editor-{i}", show_line_numbers=True)
96
+ editor.theme = self.user_config.get("theme", "monokai")
97
+
98
+ if os.path.exists(filename):
99
+ with open(filename, "r") as f:
100
+ editor.text = f.read()
101
+ yield editor
102
+
103
+ yield Static("Initializing...", id="status-bar")
104
+ yield Footer()
105
+
106
+ def on_mount(self) -> None:
107
+ # Every 30 seconds, run the background backup
108
+ self.set_interval(30, self.run_backup_cycle)
109
+ self.update_ui_state()
110
+
111
+ def run_backup_cycle(self):
112
+ """The 'Memory Protection' loop."""
113
+ for i, fname in enumerate(self.target_files):
114
+ try:
115
+ editor = self.query_one(f"#editor-{i}", TextArea)
116
+ content = editor.text.encode()
117
+
118
+ # If Incognito is ON, encrypt the disk backup
119
+ if self.incognito:
120
+ content = CIPHER.encrypt(content)
121
+
122
+ backup_name = f"{os.path.basename(fname)}.bak"
123
+ with open(os.path.join(BACKUP_DIR, backup_name), "wb") as f:
124
+ f.write(content)
125
+ except:
126
+ continue
127
+
128
+ def action_palette(self):
129
+ """Toggle the command bar."""
130
+ p = self.query_one(Input)
131
+ p.toggle_class("show-palette")
132
+ if "show-palette" in p.classes:
133
+ p.focus()
134
+
135
+ def on_input_submitted(self, event: Input.Submitted):
136
+ """Logic for the Command Palette."""
137
+ args = event.value.strip().split()
138
+ if not args: return
139
+
140
+ cmd = args[0].lower()
141
+ editor = self.tabs.active_pane.query_one(TextArea)
142
+
143
+ if cmd == "goto" and len(args) > 1:
144
+ line_idx = int(args[1]) - 1
145
+ editor.move_cursor((line_idx, 0))
146
+ editor.scroll_to_line(line_idx)
147
+
148
+ elif cmd == "replace" and len(args) > 2:
149
+ editor.text = editor.text.replace(args[1], args[2])
150
+ self.notify(f"Replaced all {args[1]} with {args[2]}")
151
+
152
+ event.input.remove_class("show-palette")
153
+ editor.focus()
154
+
155
+ def action_credits(self):
156
+ self.push_screen(AboutScreen())
157
+
158
+ def action_toggle_incognito(self):
159
+ self.incognito = not self.incognito
160
+ self.notify(f"Incognito Mode: {'ON' if self.incognito else 'OFF'}")
161
+
162
+ def update_ui_state(self):
163
+ """Keep our custom [line/total] and {tab/total} status current."""
164
+ active = self.tabs.active_pane
165
+ if active:
166
+ ed = active.query_one(TextArea)
167
+ y, x = ed.cursor_location
168
+ tab_num = int(self.tabs.active.split("-")[-1]) + 1
169
+ inc_status = "🔒" if self.incognito else ""
170
+
171
+ status_text = (
172
+ f" {inc_status} [{y+1}/{ed.document.line_count}] "
173
+ f"{{{tab_num}/{len(self.target_files)}}} | "
174
+ f"File: {active.label}"
175
+ )
176
+ self.query_one("#status-bar").update(status_text)
177
+
178
+ def on_text_area_selection_changed(self):
179
+ self.update_ui_state()
180
+
181
+ def action_save(self):
182
+ """Standard save with error handling."""
183
+ active = self.tabs.active_pane
184
+ fname = active.label.plain
185
+ content = active.query_one(TextArea).text
186
+ try:
187
+ with open(fname, "w") as f:
188
+ f.write(content)
189
+ self.notify(f"Saved: {fname}")
190
+ except Exception as e:
191
+ self.notify(f"Save failed: {e}", severity="error")
192
+
193
+ def main():
194
+ # Pass all command line args (files) to the App
195
+ app = FastText(sys.argv[1:])
196
+ app.run()
197
+
198
+ if __name__ == "__main__":
199
+ main()
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "discovery-fast-text"
7
+ version = "1.0.0"
8
+ authors = [
9
+ { name="Discovery Open Source Foundation", email="discovery@fast-txt.com" },
10
+ ]
11
+ description = "Vim-speed CLI editor with Nano ease and Incognito mode."
12
+ readme = "README.md"
13
+ requires-python = ">=3.8"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "textual>=0.40.0",
21
+ "pygments>=2.15.0",
22
+ "cryptography>=41.0.0",
23
+ ]
24
+
25
+ [project.scripts]
26
+ ft = "fast_text.editor:main"
27
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="fast-text-pro",
5
+ version="1.0.0",
6
+ author="Discovery Open Source Foundation",
7
+ description="Vim-speed CLI editor with Nano ease and Incognito mode.",
8
+ long_description=open("README.md").read(),
9
+ long_description_content_type="text/markdown",
10
+ packages=find_packages(),
11
+ install_requires=[
12
+ "textual>=0.40.0",
13
+ "pygments>=2.15.0",
14
+ "cryptography>=41.0.0",
15
+ ],
16
+ entry_points={
17
+ "console_scripts": [
18
+ "ft=fast_text.editor:main", # This creates the 'ft' command
19
+ ],
20
+ },
21
+ python_requires=">=3.8",
22
+ )