Skip to content

Instantly share code, notes, and snippets.

@digitalsignalperson
Last active January 18, 2024 02:21
Show Gist options
  • Save digitalsignalperson/e6828c55748d2ddf214ffa75c57ea5fa to your computer and use it in GitHub Desktop.
Save digitalsignalperson/e6828c55748d2ddf214ffa75c57ea5fa to your computer and use it in GitHub Desktop.
Merge multiple fish history files together using flock (untested)
#!/bin/python
import pathlib
import fnctl
import yaml
import time
# Watch for changes in other_history and merge them into local_history
local_history = pathlib.Path('~/.local/share/fish/fish_history').expanduser()
other_history = pathlib.Path('~/.local/share/fish/other_history').expanduser()
# Wait this many seconds between merges
merge_frequency_sec = 5.0
last_mtime = 0
while True:
# Read the other history file if it's changed since we've last merged it
last_mtime_now = other_history.stat().st_mtime
if last_mtime_now > last_mtime:
# Open and lock the other file (it might work nicely over sshfs)
with open(other_history, 'r') as f:
fd = f.fileno()
fnctl.flock(fd, fnctl.LOCK_EX)
try:
last_mtime_now = other_history.stat().st_mtime # Capture the actual mtime when we had the lock
other_history_entries = yaml.safe_load(f)
except:
fcntl.flock(fd, fcntl.LOCK_UN)
# Filter to new entries (TODO maybe this can start from a last_entry_index for less comparisons)
other_history_entries_new = [x for x in other_history_entries if int(x['when']) > last_mtime]
history_to_append = yaml.dump(filtered_entries, default_flow_style=False)
# Now open and lock the local file to append the other history
with open(local_history, 'a') as f:
fd = f.fileno()
fnctl.flock(fd, fnctl.LOCK_EX)
try:
f.write(history_to_append)
except:
fcntl.flock(fd, fcntl.LOCK_UN)
last_mtime = last_mtime_now
# last_mtime = max([int(entry['when']) for entry in other_history_enties_new]) # Would something like this be more robust?
time.sleep(merge_frequency_sec)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment