From e75ef3deea78b627efbbff20b1907d3ad6e17e1f Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 22 Mar 2026 18:15:36 +0000 Subject: [PATCH] Initial upload: shell-history-semantic-search v0.1.0 --- src/shell_history_search/parsers/fish.py | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/shell_history_search/parsers/fish.py diff --git a/src/shell_history_search/parsers/fish.py b/src/shell_history_search/parsers/fish.py new file mode 100644 index 0000000..3434d11 --- /dev/null +++ b/src/shell_history_search/parsers/fish.py @@ -0,0 +1,72 @@ +from pathlib import Path +from typing import Iterator +import re + +from shell_history_search.parsers import HistoryEntry, HistoryParser + + +class FishHistoryParser(HistoryParser): + shell_type = "fish" + + def get_history_path(self) -> Path: + return Path.home() / ".local" / "share" / "fish" / "fish_history" + + def parse(self, history_path: Path) -> Iterator[HistoryEntry]: + timestamp_pattern = re.compile(r"^- (\d+)$") + cmd_pattern = re.compile(r"^cmd (\d+) \(.+?\)$") + + current_timestamp: int | None = None + current_cmd: str | None = None + + for line in self.read_history_file(history_path): + line = line.strip() + + if not line: + continue + + timestamp_match = timestamp_pattern.match(line) + if timestamp_match: + try: + current_timestamp = int(timestamp_match.group(1)) + except ValueError: + current_timestamp = None + continue + + cmd_match = cmd_pattern.match(line) + if cmd_match: + continue + + if line.startswith("cmd "): + if current_cmd is not None: + entry = HistoryEntry( + command=current_cmd, + shell_type=self.shell_type, + timestamp=current_timestamp, + hostname=None, + command_hash=HistoryEntry.create_hash(current_cmd), + ) + yield entry + + current_cmd = line[4:] + continue + + if line.startswith("status ") or line.startswith("when "): + continue + + if line.startswith(" begin") or line.startswith(" end"): + continue + + if current_cmd is None: + current_cmd = line + else: + current_cmd = current_cmd + "\n" + line + + if current_cmd is not None: + entry = HistoryEntry( + command=current_cmd, + shell_type=self.shell_type, + timestamp=current_timestamp, + hostname=None, + command_hash=HistoryEntry.create_hash(current_cmd), + ) + yield entry \ No newline at end of file