This commit is contained in:
Matthew Ryan Dillon 2025-07-11 07:24:13 -04:00
parent d0930f097a
commit 92cb83258f
5 changed files with 330 additions and 9 deletions

View file

@ -0,0 +1,66 @@
#!/usr/bin/env bash
REPO_PATH="$1"
REMOTE_NAME="$2"
COMMIT_MESSAGE_TEMPLATE="$3"
cd "$REPO_PATH" || {
echo "Error: Cannot access repository at $REPO_PATH"
exit 1
}
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo "Error: Not a git repository"
exit 1
fi
sync_repo() {
echo "Starting git sync for $(pwd)"
# Check if there are any changes to commit
if [[ -n $(git status --porcelain) ]]; then
echo "Changes detected, committing..."
COMMIT_MESSAGE=$(eval echo "\"$COMMIT_MESSAGE_TEMPLATE\"")
git add .
git commit -m "$COMMIT_MESSAGE"
if [[ $? -eq 0 ]]; then
echo "Changes committed successfully"
else
echo "Error committing changes"
return 1
fi
else
echo "No changes to commit"
fi
# Fetch and pull from remote
echo "Fetching from remote..."
git fetch "$REMOTE_NAME"
if [[ $? -eq 0 ]]; then
echo "Pulling changes..."
git pull "$REMOTE_NAME" $(git branch --show-current) --rebase
if [[ $? -eq 0 ]]; then
echo "Pull completed successfully"
else
echo "Error during pull"
return 1
fi
else
echo "Error fetching from remote"
return 1
fi
# Push to remote
echo "Pushing to remote..."
git push "$REMOTE_NAME" $(git branch --show-current)
if [[ $? -eq 0 ]]; then
echo "Push completed successfully"
else
echo "Error during push"
return 1
fi
echo "Git sync completed successfully"
}
sync_repo

View file

@ -0,0 +1,156 @@
local preloadView = hs.webview.new({x=0, y=0, w=10, h=10}):html("<html></html>")
preloadView:hide()
hs.timer.doAfter(2, function() preloadView:delete() end) -- delete after 2 seconds
local GitSync = {}
GitSync.config = {
repoPath = "/Users/matthew.dillon/notebook",
remoteName = "pingo",
syncInterval = 60,
commitMessage = "Auto-sync: $(date +\"%Y-%m-%d %H:%M:%S\") from $(hostname)"
}
GitSync.scriptPath = os.getenv("HOME") .. "/.hammerspoon/git-sync.sh"
GitSync.timer = nil
GitSync.caffeineWatcher = nil
function GitSync.runSync(reason)
reason = reason or "periodic"
print("Git sync triggered: " .. reason)
local task = hs.task.new(GitSync.scriptPath, function(exitCode, stdOut, stdErr)
if exitCode == 0 then
print("Git sync completed successfully (" .. reason .. ")")
if stdOut and stdOut ~= "" then
print("Output: " .. stdOut)
end
else
print("Git sync failed (" .. reason .. ") with exit code: " .. exitCode)
if stdErr and stdErr ~= "" then
print("Error: " .. stdErr)
end
end
end, {
GitSync.config.repoPath,
GitSync.config.remoteName,
GitSync.config.commitMessage
})
task:start()
end
function GitSync.startPeriodicSync()
if GitSync.timer then
GitSync.timer:stop()
end
GitSync.timer = hs.timer.doEvery(GitSync.config.syncInterval, function()
GitSync.runSync("periodic")
end)
print("Git periodic sync started (interval: " .. GitSync.config.syncInterval .. " seconds)")
end
function GitSync.stopPeriodicSync()
if GitSync.timer then
GitSync.timer:stop()
GitSync.timer = nil
print("Git periodic sync stopped")
end
end
function GitSync.handlePowerEvent(eventType)
if eventType == hs.caffeinate.watcher.systemWillSleep then
print("System going to sleep, running git sync...")
GitSync.runSync("pre-sleep")
elseif eventType == hs.caffeinate.watcher.systemDidWake then
print("System woke up, running git sync...")
-- Add a small delay to ensure network is available
hs.timer.doAfter(5, function()
GitSync.runSync("post-wake")
end)
end
end
function GitSync.startPowerEventMonitoring()
GitSync.caffeineWatcher = hs.caffeinate.watcher.new(GitSync.handlePowerEvent)
GitSync.caffeineWatcher:start()
print("Git power event monitoring started")
end
function GitSync.stopPowerEventMonitoring()
if GitSync.caffeineWatcher then
GitSync.caffeineWatcher:stop()
GitSync.caffeineWatcher = nil
print("Git power event monitoring stopped")
end
end
function GitSync.start()
GitSync.startPeriodicSync()
GitSync.startPowerEventMonitoring()
GitSync.runSync("initial")
print("Git auto-sync initialized")
print("Repository: " .. GitSync.config.repoPath)
print("Remote: " .. GitSync.config.remoteName)
print("Sync interval: " .. GitSync.config.syncInterval .. " seconds")
end
function GitSync.stop()
GitSync.stopPeriodicSync()
GitSync.stopPowerEventMonitoring()
print("Git auto-sync stopped")
end
GitSync.start()
if hs.menubar then
GitSync.menubar = hs.menubar.new()
GitSync.menubar:setTitle("🦖")
GitSync.menubar:setTooltip("Git Auto-Sync")
GitSync.menubar:setMenu({
{ title = "Sync Now", fn = function() GitSync.runSync("manual") end },
{ title = "Start Auto-Sync", fn = GitSync.start },
{ title = "Stop Auto-Sync", fn = GitSync.stop },
{ title = "-" },
{ title = "Repository: " .. GitSync.config.repoPath, disabled = true }
})
end
-- Make GitSync available globally for console access
_G.GitSync = GitSync
local filePath = "/Users/matthew.dillon/notebook/inbox.md"
hs.hotkey.bind({"cmd", "shift"}, "J", function()
local button, text = hs.dialog.textPrompt(
"Add To-Do",
"Enter your tasks (one per line):",
"",
"OK",
"Cancel"
)
if button == "OK" and text ~= "" then
-- Split input into lines
local lines = {}
for line in text:gmatch("[^\r\n]+") do
table.insert(lines, "- [ ] " .. line)
end
-- Concatenate lines with newlines
local formatted = table.concat(lines, "\n") .. "\n"
-- Append to file
local file = io.open(filePath, "a")
if file then
file:write(formatted)
file:close()
hs.alert.show("Tasks added!")
else
hs.alert.show("Failed to open file.")
end
end
end)

View file

@ -65,8 +65,8 @@ alias devlog="cd ~/projects/personal/devlog && hx logs/$(date '+%Y-%m-%d').gmi &
eval "$(/opt/homebrew/bin/brew shellenv)"
eval "$(direnv hook zsh)"
eval "$(jj util completion zsh)"
export NVM_DIR="$HOME/.nvm"
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"
# export NVM_DIR="$HOME/.nvm"
# [ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"
[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"
function reldate() {
@ -83,3 +83,87 @@ export FZF_DEFAULT_OPTS=" \
--color=marker:#b4befe,fg+:#cdd6f4,prompt:#cba6f7,hl+:#f38ba8 \
--color=selected-bg:#45475a \
--color=border:#313244,label:#cdd6f4"
task_inbox_count_prompt() {
local count
count=$(task +inbox +PENDING count 2>/dev/null)
if [[ $count -gt 0 ]]; then
echo "%B%F{yellow}(inbox:$count)%f%b "
fi
}
select_project() {
local project_list result query selection project
project_list=$(task _unique project | grep -v '^$')
result=$(echo "$project_list" | fzf --prompt="select project: " --print-query --expect=enter)
query=$(echo "$result" | sed -n 1p)
key=$(echo "$result" | sed -n 2p)
selection=$(echo "$result" | sed -n 3p)
if [ -z "$selection" ]; then
project="$query"
else
project="$selection"
fi
if [ -z "$project" ] || [ "$project" = "enter" ]; then
return 1
fi
echo "$project"
}
work_on() {
if [ -z "$1" ]; then
echo "usage: work_on <task_id>"
return 1
fi
task "$1" start
description=$(task _get "$1".description)
klog switch -s "$description"
if [ $? -ne 0 ]; then
klog start -s "$description"
fi
}
task_file() {
if [ -z "$1" ]; then
echo "usage: task_file <task_id>"
return 1
fi
task "$1" modify -inbox project:"$(select_project)"
}
task_schedule() {
if [ -z "$1" ]; then
echo "usage: task_schedule <task_id> [<date>]"
return 1
fi
local id="$1"
local date="$2"
if [ -n "$date" ]; then
task "$id" modify scheduled:"$date"
return
fi
local current_scheduled
current_scheduled=$(task "$id" _get scheduled)
if [ -z "$current_scheduled" ]; then
task "$id" modify scheduled:today
else
task "$id" modify scheduled:
fi
}
export PS1='
$(task_inbox_count_prompt)%(!.%B%F{red}%n%f%b in .${SSH_TTY:+"%B%F{yellow}%n%f%b in "})${SSH_TTY:+"%B%F{green}%m%f%b in "}%B%F{cyan}%~%f%b${(e)git_info[prompt]}${VIRTUAL_ENV:+" via %B%F{yellow}${VIRTUAL_ENV:t}%f%b"}${duration_info}
%B%(1j.%F{blue}*%f .)%(?.%F{green}.%F{red}%? )$(_prompt_asciiship_vimode)%f%b '

View file

@ -3,9 +3,11 @@ name = {{ .name | quote }}
email = {{ .email_personal | quote }}
[git]
push-bookmark-prefix = "{{ .github_personal }}_jj_"
private-commits = "description(glob:'private:*') | bookmarks('merge')"
[templates]
git_push_bookmark = '"{{ .github_personal }}_jj_" ++ change_id.short()'
[colors]
"diff removed token" = { fg = "red", underline = false }
"diff added token" = { fg = "green", underline = false }
@ -22,5 +24,5 @@ diff-formatter = ":git"
--when.repositories = ["~/Klaviyo", "~/.klaviyocli"]
[--scope.user]
email = {{ .email_work | quote }}
[--scope.git]
push-bookmark-prefix = "2025_{{ .github_work }}_jj_"
[--scope.templates]
git_push_bookmark = '"2025_{{ .github_work }}_jj_" ++ change_id.short()'

View file

@ -1,18 +1,31 @@
data.location={{ .chezmoi.homeDir }}/.task
news.version=3.4.1
default.command=act
alias.next=next limit:1
alias.log=add +inbox
alias.inbox=list project: +inbox
# must be specified bc taskrc not in default ~/.taskrc location
data.location=~/.local/share/task
hooks.location=~/.config/task/hooks
include solarized-dark-256.theme
report.list.columns=id,start.age,depends.indicator,priority,project,tags,recur.indicator,scheduled.countdown,due,until.remaining,description.count
report.list.labels=id,active,d,p,project,tags,r,sch,due,until,description
report.list.columns=id,start.age,depends.indicator,priority,project,tags,recur.indicator,scheduled,due,until.remaining,description.count
report.list.labels=id,active,deps,pri,proj,tags,recur,sched,due,until,desc
report.next.columns=id,start.age,depends,priority,project,tags,recur,scheduled.countdown,due.relative,until.remaining,description
report.next.labels=id,active,deps,p,project,tag,recur,s,due,until,description
report.act.description=unblocked tasks
report.act.columns=id,start.age,depends,priority,project,tags,recur,scheduled,due,until.remaining,description.count
report.act.labels=id,active,deps,pri,proj,tags,recur,sched,due,until,desc
report.act.filter=status:pending -WAITING -BLOCKED -inbox
report.act.sort=project+/,due+,entry+
sync.server.url={{ .task_url }}
sync.server.client_id={{ .task_client_id }}
sync.encryption_secret={{ .task_encryption_secret }}
uda.estimate.type=numeric
uda.estimate.label=estimated_hrs
context.work.read=-personal