72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
"""Fish history parser."""
|
|
|
|
import os
|
|
import json
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import List, Optional
|
|
|
|
from .base import HistoryParser, ParsedCommand
|
|
|
|
|
|
class FishHistoryParser(HistoryParser):
|
|
"""Parser for Fish shell history files."""
|
|
|
|
SHELL_NAME = "fish"
|
|
DEFAULT_HISTORY_DIR = os.path.expanduser("~/.config/fish/history")
|
|
|
|
def get_default_history_locations(self) -> List[str]:
|
|
"""Return default locations for fish history files."""
|
|
history_dir = Path(self.DEFAULT_HISTORY_DIR)
|
|
if history_dir.exists() and history_dir.is_dir():
|
|
return list(history_dir.glob("*.json"))
|
|
return []
|
|
|
|
def parse_file(self, filepath: str) -> List[ParsedCommand]:
|
|
"""Parse a fish history file."""
|
|
try:
|
|
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
|
|
content = f.read()
|
|
return self.parse_content(content)
|
|
except FileNotFoundError:
|
|
return []
|
|
except Exception:
|
|
return []
|
|
|
|
def parse_content(self, content: str) -> List[ParsedCommand]:
|
|
"""Parse fish history content from a string."""
|
|
commands = []
|
|
|
|
try:
|
|
data = json.loads(content)
|
|
if isinstance(data, list):
|
|
for line_num, item in enumerate(data, start=1):
|
|
if isinstance(item, dict) and 'text' in item:
|
|
timestamp = None
|
|
if 'timestamp' in item:
|
|
try:
|
|
timestamp = datetime.fromtimestamp(item['timestamp'])
|
|
except (ValueError, TypeError):
|
|
pass
|
|
|
|
cmd = ParsedCommand(
|
|
raw_command=item['text'],
|
|
timestamp=timestamp,
|
|
line_number=line_num
|
|
)
|
|
commands.append(cmd)
|
|
except json.JSONDecodeError:
|
|
pass
|
|
|
|
return commands
|
|
|
|
def parse_all_history_files(self) -> List[ParsedCommand]:
|
|
"""Parse all fish history files in the default directory."""
|
|
all_commands = []
|
|
locations = self.get_default_history_locations()
|
|
|
|
for filepath in locations:
|
|
all_commands.extend(self.parse_file(str(filepath)))
|
|
|
|
return all_commands
|