💥 MAJOR UPDATE: Windows compatibility fixes + executable + installer

This commit is contained in:
2025-09-24 11:14:24 +02:00
commit 8cd0c1fbd4
25 changed files with 5492 additions and 0 deletions

1
utils/__init__.py Normal file
View File

@@ -0,0 +1 @@
# OverCode Utils Package

351
utils/autocomplete.py Normal file
View File

@@ -0,0 +1,351 @@
#!/usr/bin/env python3
"""
OverCode Auto-completion System - Smart command suggestions and tab completion
"""
import os
import re
import difflib
from typing import List, Dict, Tuple
from colorama import Fore, Style, init
init(autoreset=True)
class AutoComplete:
"""Advanced auto-completion system for OverCode"""
def __init__(self):
# Core commands
self.commands = {
'help': 'Show available commands and help',
'new': 'Create a new file with templates',
'run': 'Execute an OverCode file',
'game': 'Launch the gaming center',
'theme': 'Change shell theme',
'clear': 'Clear the screen',
'ls': 'List directory contents',
'cd': 'Change directory',
'exit': 'Exit OverCode shell',
'stats': 'Show session statistics',
'fastfetch': 'Show system information',
'credits': 'Show project credits'
}
# Command arguments and subcommands
self.command_args = {
'new': {
'templates': ['hello', 'demo', 'games', 'web', 'ai', 'crypto'],
'extensions': ['.ovc'],
'syntax': 'new <filename>:<template>'
},
'game': {
'games': ['snake', 'tetris', '2048', 'life', 'adventure', 'mines',
'pong', 'breakout', 'memory', 'hangman', 'rps', 'quiz'],
'syntax': 'game [game_name]'
},
'theme': {
'themes': ['cyberpunk', 'matrix', 'ocean', 'sunset', 'hacker'],
'syntax': 'theme [theme_name]'
},
'run': {
'extensions': ['.ovc'],
'syntax': 'run <filename>'
}
}
# File patterns
self.file_patterns = {
'.ovc': 'OverCode polyglot files',
'.py': 'Python files',
'.js': 'JavaScript files',
'.php': 'PHP files',
'.go': 'Go files',
'.rs': 'Rust files',
'.java': 'Java files',
'.cpp': 'C++ files',
'.c': 'C files'
}
# Fuzzy matching threshold
self.fuzzy_threshold = 0.6
def complete(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
"""Main completion method"""
words = line.split()
if not words:
return list(self.commands.keys())
# First word - complete command names
if len(words) == 1 and not line.endswith(' '):
return self._complete_command(text)
# Command arguments
command = words[0]
if command in self.command_args:
return self._complete_args(command, text, words[1:])
# File completion
return self._complete_files(text)
def _complete_command(self, text: str) -> List[str]:
"""Complete command names"""
matches = []
for cmd in self.commands:
if cmd.startswith(text.lower()):
matches.append(cmd)
# Add fuzzy matches if no exact matches
if not matches:
matches = self._fuzzy_match(text, list(self.commands.keys()))
return sorted(matches)
def _complete_args(self, command: str, text: str, args: List[str]) -> List[str]:
"""Complete command arguments"""
cmd_info = self.command_args[command]
# Game completion
if command == 'game':
return self._fuzzy_match(text, cmd_info['games'])
# Theme completion
elif command == 'theme':
return self._fuzzy_match(text, cmd_info['themes'])
# New file template completion
elif command == 'new':
if ':' in text:
# Template completion after colon
filename, template_part = text.split(':', 1)
matches = self._fuzzy_match(template_part, cmd_info['templates'])
return [f"{filename}:{match}" for match in matches]
else:
# File completion or template suggestion
file_matches = self._complete_files(text, ['.ovc'])
if not file_matches:
return [f"{text}:{template}" for template in cmd_info['templates']]
return file_matches
# File completion for run command
elif command == 'run':
return self._complete_files(text, ['.ovc'])
return []
def _complete_files(self, text: str, extensions: List[str] = None) -> List[str]:
"""Complete file names"""
try:
# Get current directory files
current_dir = os.getcwd()
files = os.listdir(current_dir)
matches = []
for file in files:
# Filter by extensions if specified
if extensions:
if not any(file.endswith(ext) for ext in extensions):
continue
if file.startswith(text):
matches.append(file)
# Add directories
for item in files:
if os.path.isdir(os.path.join(current_dir, item)):
if item.startswith(text):
matches.append(item + '/')
return sorted(matches)
except (OSError, PermissionError):
return []
def _fuzzy_match(self, text: str, candidates: List[str]) -> List[str]:
"""Fuzzy string matching for suggestions"""
if not text:
return candidates
matches = difflib.get_close_matches(
text.lower(),
[c.lower() for c in candidates],
n=10,
cutoff=self.fuzzy_threshold
)
# Return original case versions
result = []
for match in matches:
for candidate in candidates:
if candidate.lower() == match:
result.append(candidate)
break
return result
def suggest_correction(self, command: str) -> str:
"""Suggest correction for mistyped commands"""
# Try fuzzy matching on commands
matches = self._fuzzy_match(command, list(self.commands.keys()))
if matches:
suggestion = matches[0]
return f"{Fore.YELLOW}Did you mean: {Fore.CYAN}{suggestion}{Fore.YELLOW}?"
return ""
def show_command_help(self, command: str) -> str:
"""Show help for specific command"""
if command in self.commands:
help_text = f"{Fore.CYAN}{command}{Fore.WHITE} - {self.commands[command]}"
if command in self.command_args:
cmd_info = self.command_args[command]
help_text += f"\n{Fore.YELLOW}Syntax: {cmd_info['syntax']}"
if 'games' in cmd_info:
help_text += f"\n{Fore.GREEN}Games: {', '.join(cmd_info['games'])}"
elif 'themes' in cmd_info:
help_text += f"\n{Fore.GREEN}Themes: {', '.join(cmd_info['themes'])}"
elif 'templates' in cmd_info:
help_text += f"\n{Fore.GREEN}Templates: {', '.join(cmd_info['templates'])}"
return help_text
return f"{Fore.RED}Command '{command}' not found"
def get_command_suggestions(self, partial_command: str) -> List[Tuple[str, str]]:
"""Get command suggestions with descriptions"""
matches = self._complete_command(partial_command)
return [(cmd, self.commands[cmd]) for cmd in matches[:5]]
def smart_suggest(self, line: str) -> str:
"""Provide smart suggestions based on context"""
words = line.strip().split()
if not words:
return f"{Fore.CYAN}💡 Try: help, new, game, theme, run"
command = words[0]
# Unknown command
if command not in self.commands:
correction = self.suggest_correction(command)
if correction:
return correction
return f"{Fore.RED}Unknown command. {Fore.CYAN}Type 'help' for available commands."
# Incomplete command
if len(words) == 1:
if command in self.command_args:
cmd_info = self.command_args[command]
return f"{Fore.YELLOW}💡 Syntax: {cmd_info['syntax']}"
# Command-specific suggestions
if command == 'new' and len(words) == 2:
arg = words[1]
if ':' not in arg:
templates = self.command_args['new']['templates']
return f"{Fore.YELLOW}💡 Add template: {Fore.CYAN}{arg}:<template> {Fore.WHITE}({', '.join(templates)})"
elif command == 'game' and len(words) == 1:
games = self.command_args['game']['games'][:5]
return f"{Fore.YELLOW}💡 Available games: {Fore.CYAN}{', '.join(games)}..."
elif command == 'theme' and len(words) == 1:
themes = self.command_args['theme']['themes']
return f"{Fore.YELLOW}💡 Available themes: {Fore.CYAN}{', '.join(themes)}"
return ""
class SmartPrompt:
"""Enhanced prompt with auto-completion hints"""
def __init__(self, autocomplete: AutoComplete):
self.autocomplete = autocomplete
self.history = []
self.history_index = -1
def get_input(self, prompt: str) -> str:
"""Get input with smart suggestions"""
try:
# Simple input for now - in real implementation would use readline
user_input = input(prompt).strip()
if user_input:
self.history.append(user_input)
self.history_index = len(self.history)
return user_input
except KeyboardInterrupt:
print("\n^C")
return ""
except EOFError:
return "exit"
def show_suggestions(self, partial_line: str):
"""Show contextual suggestions"""
suggestions = self.autocomplete.smart_suggest(partial_line)
if suggestions:
print(suggestions)
def show_completions(self, text: str, line: str):
"""Show available completions"""
completions = self.autocomplete.complete(text, line, 0, len(text))
if completions:
print(f"\n{Fore.CYAN}Suggestions:")
for i, comp in enumerate(completions[:8]): # Show max 8
print(f" {Fore.YELLOW}{i+1}.{Fore.WHITE} {comp}")
if len(completions) > 8:
print(f" {Fore.LIGHTBLACK_EX}... and {len(completions) - 8} more")
# Integration with the main shell
def setup_autocomplete(shell_instance):
"""Set up auto-completion for the shell"""
autocomplete = AutoComplete()
smart_prompt = SmartPrompt(autocomplete)
# Add completion method to shell
def complete_command(self, text, line, begidx, endidx):
return autocomplete.complete(text, line, begidx, endidx)
shell_instance.complete_command = complete_command
shell_instance.autocomplete = autocomplete
shell_instance.smart_prompt = smart_prompt
return autocomplete
# Demo and testing functions
def demo_autocomplete():
"""Demonstrate auto-completion features"""
print(Fore.CYAN + "🔍 OverCode Auto-completion Demo")
print("=" * 50)
ac = AutoComplete()
# Test command completion
print(f"\n{Fore.WHITE}Command completion for 'g':")
matches = ac._complete_command('g')
for match in matches:
print(f" {Fore.GREEN}{match}")
# Test fuzzy matching
print(f"\n{Fore.WHITE}Fuzzy matching for 'tem':")
matches = ac._fuzzy_match('tem', ac.command_args['theme']['themes'])
for match in matches:
print(f" {Fore.YELLOW}{match}")
# Test suggestions
print(f"\n{Fore.WHITE}Smart suggestions:")
test_commands = ['gam', 'new hello.ovc', 'theme', 'unknown_command']
for cmd in test_commands:
suggestion = ac.smart_suggest(cmd)
print(f" '{cmd}'{suggestion}")
print(f"\n{Fore.GREEN}✨ Auto-completion demo complete!")
if __name__ == "__main__":
demo_autocomplete()

315
utils/progress.py Normal file
View File

@@ -0,0 +1,315 @@
#!/usr/bin/env python3
"""
OverCode Progress Bars - Epic animated progress indicators
"""
import time
import sys
import threading
from colorama import Fore, Style, init
init(autoreset=True)
class ProgressBar:
"""Animated progress bar with multiple styles"""
def __init__(self, total=100, width=40, style='modern', color='cyan'):
self.total = total
self.current = 0
self.width = width
self.style = style
self.color = color
self.start_time = time.time()
self.is_running = False
self.animation_thread = None
# Color mapping
self.colors = {
'cyan': Fore.CYAN,
'green': Fore.GREEN,
'yellow': Fore.YELLOW,
'red': Fore.RED,
'magenta': Fore.MAGENTA,
'blue': Fore.BLUE
}
# Style configurations
self.styles = {
'modern': {
'filled': '',
'empty': '',
'prefix': '[',
'suffix': ']'
},
'classic': {
'filled': '=',
'empty': '-',
'prefix': '[',
'suffix': ']'
},
'dots': {
'filled': '',
'empty': '',
'prefix': '(',
'suffix': ')'
},
'arrows': {
'filled': '',
'empty': '',
'prefix': '',
'suffix': ''
},
'blocks': {
'filled': '',
'empty': '',
'prefix': '',
'suffix': ''
},
'fire': {
'filled': '🔥',
'empty': '💨',
'prefix': '🚀',
'suffix': ''
}
}
def update(self, value, message=""):
"""Update progress bar value"""
self.current = min(value, self.total)
self._render(message)
def increment(self, amount=1, message=""):
"""Increment progress by amount"""
self.current = min(self.current + amount, self.total)
self._render(message)
def _render(self, message=""):
"""Render the progress bar"""
if self.total == 0:
percentage = 100
else:
percentage = (self.current / self.total) * 100
filled_width = int((self.current / self.total) * self.width) if self.total > 0 else 0
empty_width = self.width - filled_width
style_config = self.styles.get(self.style, self.styles['modern'])
color = self.colors.get(self.color, Fore.CYAN)
# Build progress bar
filled = style_config['filled'] * filled_width
empty = style_config['empty'] * empty_width
prefix = style_config['prefix']
suffix = style_config['suffix']
# Calculate ETA
elapsed = time.time() - self.start_time
if self.current > 0:
eta = (elapsed / self.current) * (self.total - self.current)
eta_str = f" ETA: {eta:.1f}s"
else:
eta_str = ""
# Format the bar
bar = f"{color}{prefix}{filled}{Fore.LIGHTBLACK_EX}{empty}{color}{suffix}"
percentage_str = f" {percentage:6.1f}%"
if message:
message = f" {Fore.WHITE}{message}"
# Print with carriage return to overwrite
sys.stdout.write(f"\r{bar}{percentage_str}{eta_str}{message}")
sys.stdout.flush()
if self.current >= self.total:
print() # New line when complete
class SpinnerProgress:
"""Animated spinner for indefinite operations"""
def __init__(self, message="Loading", style='dots'):
self.message = message
self.style = style
self.is_running = False
self.thread = None
self.spinners = {
'dots': ['', '', '', '', '', '', '', '', '', ''],
'arrows': ['', '', '', '', '', '', '', ''],
'bars': ['|', '/', '-', '\\'],
'blocks': ['', '', '', '', '', '', '', '', '', '', '', ''],
'braille': ['', '', '', '', '', '', '', ''],
'fire': ['🔥', '🚀', '', '', '💫', '🌟']
}
def start(self):
"""Start the spinner animation"""
if self.is_running:
return
self.is_running = True
self.thread = threading.Thread(target=self._animate)
self.thread.daemon = True
self.thread.start()
def stop(self, final_message="Done"):
"""Stop the spinner"""
self.is_running = False
if self.thread:
self.thread.join()
# Clear the line and show final message
sys.stdout.write(f"\r{Fore.GREEN}{final_message}{' ' * 20}\n")
sys.stdout.flush()
def _animate(self):
"""Animation loop"""
frames = self.spinners.get(self.style, self.spinners['dots'])
i = 0
while self.is_running:
frame = frames[i % len(frames)]
sys.stdout.write(f"\r{Fore.CYAN}{frame} {Fore.WHITE}{self.message}")
sys.stdout.flush()
time.sleep(0.1)
i += 1
class MultiProgress:
"""Multiple progress bars for complex operations"""
def __init__(self):
self.bars = {}
self.order = []
def add_bar(self, name, total, style='modern', color='cyan'):
"""Add a new progress bar"""
self.bars[name] = {
'bar': ProgressBar(total, style=style, color=color),
'total': total,
'current': 0,
'message': ''
}
self.order.append(name)
def update(self, name, value, message=""):
"""Update a specific progress bar"""
if name in self.bars:
self.bars[name]['current'] = value
self.bars[name]['message'] = message
self._render_all()
def increment(self, name, amount=1, message=""):
"""Increment a specific progress bar"""
if name in self.bars:
self.bars[name]['current'] = min(
self.bars[name]['current'] + amount,
self.bars[name]['total']
)
self.bars[name]['message'] = message
self._render_all()
def _render_all(self):
"""Render all progress bars"""
# Move cursor up to overwrite previous output
if len(self.bars) > 1:
sys.stdout.write(f"\033[{len(self.bars)}A")
for name in self.order:
bar_data = self.bars[name]
bar_data['bar'].current = bar_data['current']
print(f"{Fore.YELLOW}{name:<15}", end=" ")
bar_data['bar']._render(bar_data['message'])
# Utility functions for easy use
def progress_bar(iterable, desc="Processing", style='modern', color='cyan'):
"""Wrapper for iterables with progress bar"""
total = len(iterable) if hasattr(iterable, '__len__') else 100
bar = ProgressBar(total, style=style, color=color)
for i, item in enumerate(iterable):
bar.update(i + 1, desc)
yield item
bar.update(total, f"{desc} - Complete!")
def simulate_progress(message="Processing", duration=3, style='modern', color='cyan'):
"""Simulate progress for demo purposes"""
bar = ProgressBar(100, style=style, color=color)
for i in range(101):
time.sleep(duration / 100)
bar.update(i, message)
def with_spinner(func, message="Loading", style='dots'):
"""Decorator to show spinner during function execution"""
def wrapper(*args, **kwargs):
spinner = SpinnerProgress(message, style)
spinner.start()
try:
result = func(*args, **kwargs)
spinner.stop("Complete!")
return result
except Exception as e:
spinner.stop(f"Error: {str(e)}")
raise
return wrapper
# Demo functions
def demo_progress_bars():
"""Demonstrate different progress bar styles"""
print(Fore.CYAN + "🚀 OverCode Progress Bar Demo")
print("=" * 50)
styles = ['modern', 'classic', 'dots', 'arrows', 'blocks', 'fire']
colors = ['cyan', 'green', 'yellow', 'magenta', 'blue']
for style in styles:
color = colors[styles.index(style) % len(colors)]
print(f"\n{Fore.WHITE}Style: {style.title()} ({color})")
bar = ProgressBar(50, style=style, color=color)
for i in range(51):
bar.update(i, f"Processing {style} style...")
time.sleep(0.02)
print(f"\n{Fore.GREEN}✨ All styles demonstrated!")
def demo_spinner():
"""Demonstrate spinner animations"""
print(Fore.CYAN + "\n🔄 Spinner Demo")
styles = ['dots', 'arrows', 'bars', 'blocks', 'braille', 'fire']
for style in styles:
spinner = SpinnerProgress(f"Loading with {style} style", style)
spinner.start()
time.sleep(2)
spinner.stop(f"{style.title()} complete!")
def demo_multi_progress():
"""Demonstrate multiple progress bars"""
print(Fore.CYAN + "\n📊 Multi-Progress Demo")
multi = MultiProgress()
multi.add_bar("Download", 100, 'modern', 'green')
multi.add_bar("Extract", 80, 'arrows', 'yellow')
multi.add_bar("Install", 60, 'dots', 'blue')
import random
for i in range(100):
if i < 80:
multi.increment("Download", 1, f"Downloading file {i+1}")
if i > 20 and i < 60:
multi.increment("Extract", random.randint(1, 2), "Extracting files...")
if i > 40:
multi.increment("Install", 1, "Installing packages...")
time.sleep(0.05)
print(f"\n{Fore.GREEN}🎉 All operations complete!")
if __name__ == "__main__":
demo_progress_bars()
demo_spinner()
demo_multi_progress()