-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwarp-history.py
executable file
·177 lines (138 loc) · 5.44 KB
/
warp-history.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#!/usr/bin/env python3
from datetime import datetime
import shutil
import sqlite3
import os
import subprocess
import json
from collections import OrderedDict
import argparse
import tempfile
import platform
def get_warp_history(history: OrderedDict[str, datetime]) -> None:
db_path: str = ""
try:
# Define the paths
if platform.system() == "Linux":
db_path = os.path.expanduser("~/.local/share/warp-terminal/warp.sqlite")
elif platform.system() == "Darwin": # macOS
db_path = os.path.expanduser("~/Library/Application Support/dev.warp.Warp-Stable/warp.sqlite")
else:
print("Unsupported operating system.")
return
# Connect to the SQLite database
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Execute the query to select unique commands and their start timestamps
cursor.execute("SELECT DISTINCT command, start_ts FROM commands")
commands = cursor.fetchall()
# Close the database connection
conn.close()
except Exception as e:
print(f"Failed to read Warp history from {db_path}: {e}")
return
# Parse the start_ts and store in the history dictionary
for command, start_ts in commands:
try:
if start_ts is None:
start_ts = "1970-01-01 00:00:00.000000"
# Truncate nanoseconds to microseconds
start_ts = start_ts[:26]
start_ts_dt = datetime.strptime(start_ts, "%Y-%m-%d %H:%M:%S.%f")
history[command] = start_ts_dt
except Exception as e:
print(f"Failed to parse timestamp {start_ts}: {e}")
continue
def populate_mcfly_history(history_path: str) -> None:
# Check if the `mcfly` command is available
if not shutil.which("mcfly"):
# print("The `mcfly` command is not available.")
return
# set MCFLY_HISTFILE to the history file path
os.environ["MCFLY_HISTFILE"] = history_path
# Create a temporary file for McFly history
mcfly_history = os.getenv("MCFLY_HISTORY")
if not mcfly_history:
with tempfile.NamedTemporaryFile(
delete=False, prefix="mcfly.", dir="/tmp"
) as tmpfile:
mcfly_history = tmpfile.name
os.environ["MCFLY_HISTORY"] = mcfly_history
# Populate McFly's temporary history file from recent commands in the shell's primary HISTFILE
with open(history_path, "r") as histfile, open(mcfly_history, "w") as mcflyfile:
lines = histfile.readlines()[-100:] # Get the last 100 lines
mcflyfile.writelines(lines)
def get_mcfly_history(history_path: str, history: OrderedDict[str, datetime]) -> None:
# Check if the `mcfly` command is available
if not shutil.which("mcfly"):
# print("The `mcfly` command is not available.")
return
stdout: str = "[]"
try:
populate_mcfly_history(history_path)
# Run the `mcfly dump` command and capture the output
result = subprocess.run(
["mcfly", "dump"], stdout=subprocess.PIPE, text=True, check=True
)
stdout = result.stdout
except subprocess.CalledProcessError as e:
print(f"Failed to read McFly history: {e}")
return
# Parse the JSON output
commands_json = json.loads(stdout)
# Extract the `cmd` and `when_run` properties and store them in the given history dictionary
for command in commands_json:
when_run = datetime.fromisoformat(command["when_run"])
history[command["cmd"]] = when_run
def write_history_to_shell_history(
history_path: str, history: OrderedDict[str, datetime]
) -> None:
# Backup the existing shell history file
if os.path.exists(history_path):
os.rename(history_path, history_path + ".bak")
# Append the commands to the shell history file
with open(history_path, "a") as history_file:
for command in history.keys():
history_file.write(command)
history_file.write("\n")
def write_this_script_to_rc_file(shell: str) -> None:
# Define the path to the shell RC file
rc_path = os.path.expanduser(f"~/.{shell}rc")
# if the script is already appended, do not append it again
with open(rc_path, "r") as f:
if __file__ in f.read():
return
# Append this script to the shell RC file
with open(rc_path, "a") as rc_file:
rc_file.write("# Append Warp and McFly history to shell history\n")
rc_file.write(f"python3 {__file__}\n")
def parse_args():
# Parse command-line arguments
parser = argparse.ArgumentParser(
description="Write Warp and McFly history to shell history."
)
parser.add_argument(
"--shell",
type=str,
default="bash",
choices=["bash", "zsh"],
help="Specify the shell type (bash or zsh).",
)
return parser.parse_args()
def main():
# Parse command-line arguments
args = parse_args()
# History
history = OrderedDict()
# Define the path to the shell history file
history_path = os.path.expanduser(f"~/.{args.shell}_history")
# Get commands from Warp
get_warp_history(history)
# Get commands from McFly
get_mcfly_history(history_path, history)
# Write the combined history to the specified shell history
write_history_to_shell_history(history_path, history)
# Write this script to the shell RC file
write_this_script_to_rc_file(args.shell)
if __name__ == "__main__":
main()