Recently Written · git

sbm

dmenu bookmarks. Instantly fuzzy search thousands of bookmarks and plumb them. LOOKING FOR SUCKLESS SOFTWARE EDITION? GO TO sbm-suckless INSTEAD

git clone https://github.com/equwal/sbm

Log | Files | Refs


commit 497f1961ad921c08c381e53445d3361573065665
Spenser Truex <truex@equwal.com>
2026-09-21 00:26:03 -0700

Windows installer: Start menu entry, and bm-watch at each login

The installer makes a Start menu entry. Only the desktop shortcut has
the key Ctrl+Alt+Shift+F24, because Explorer can lose a key that two
shortcuts share. A Startup entry runs bm-watch in a hidden mintty at
each login, and the installer starts it at once, so the browser
bookmarks come into bm during the installation. The installer and the
uninstaller stop bm-watch before they change its files. The installer
warns when the jq package of Cygwin is missing.

 README                    | 13 +++++++++----
 contrib/windows/sbm-setup | 38 +++++++++++++++++++++++++++++-------
 contrib/windows/sbm.nsi   | 49 ++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 82 insertions(+), 18 deletions(-)
diff --git a/README b/README
index d0f37b9..9de38dd 100644
--- a/README
+++ b/README
@@ -224,10 +224,15 @@ Printing nothing means the user cancelled. test/fakemenu is a small example.
 == Windows ==
 bm runs under Cygwin. Get sbm-VERSION-setup.exe from a release on GitHub and
 start it. The installer puts bm and the bm-* tools in /usr/local/bin. It
-makes a desktop shortcut that opens bm in a mintty window, and Esc closes
-the window. The key of the shortcut is Ctrl+Alt+Shift+F24. Almost no keyboard
-has an F24 key, so keyboard firmware can use this key combination without
-conflicts.
+makes a Start menu entry and a desktop shortcut that open bm in a mintty
+window, and Esc closes the window. The key of the desktop shortcut is
+Ctrl+Alt+Shift+F24. Almost no keyboard has an F24 key, so keyboard firmware
+can use this key combination without conflicts.
+
+The installer imports the bookmarks of all profiles of the Chromium browsers
+(Brave, Chrome, Chromium, Edge and Vivaldi). A Startup entry, sbm-watch, runs
+bm-watch at each login, so new browser bookmarks come into bm a few seconds
+after you add them. The import needs the jq package of Cygwin.
 
 The installer also puts fzf.exe, the Windows build of fzf, in
 /usr/local/libexec/sbm. Do not use the fzf package of Cygwin. That package is
diff --git a/contrib/windows/sbm-setup b/contrib/windows/sbm-setup
index b33dead..370737c 100755
--- a/contrib/windows/sbm-setup
+++ b/contrib/windows/sbm-setup
@@ -1,10 +1,34 @@
 #!/bin/sh
 
-# sbm-setup: give the user the example tags and search keywords of sbm.
-# The installer runs this script. It keeps the files that the user has.
+# sbm-setup: tasks of the Windows installer.
+#
+#     sbm-setup data    give the user the example tags and search keywords,
+#                       and keep the files that the user has
+#     sbm-setup stop    stop the bm-watch that the installer started
 
-d=${XDG_DATA_HOME:-$HOME/.local/share}/sbm
-mkdir -p "$d"
-for f in engines usertags; do
-    [ -e "$d/$f" ] || cp "/usr/local/share/sbm/$f" "$d/"
-done
+case ${1-} in
+    data)
+        d=${XDG_DATA_HOME:-$HOME/.local/share}/sbm
+        mkdir -p "$d"
+        for f in engines usertags; do
+            [ -e "$d/$f" ] || cp "/usr/local/share/sbm/$f" "$d/"
+        done
+        ;;
+    stop)
+        # The hidden mintty of bm-watch has the class sbm-watch. When it
+        # stops, bm-watch gets SIGHUP and stops too. Cygwin shows the
+        # arguments of a process in /proc/PID/cmdline.
+        for f in /proc/[0-9]*/cmdline; do
+            case $(tr '\0' ' ' < "$f" 2>/dev/null) in
+                *'--class sbm-watch '*)
+                    pid=${f#/proc/}
+                    kill "${pid%/cmdline}" 2>/dev/null
+                    ;;
+            esac
+        done
+        ;;
+    *)
+        printf 'usage: sbm-setup data | stop\n' >&2
+        exit 2
+        ;;
+esac
diff --git a/contrib/windows/sbm.nsi b/contrib/windows/sbm.nsi
index 30b201c..25ba95e 100644
--- a/contrib/windows/sbm.nsi
+++ b/contrib/windows/sbm.nsi
@@ -3,12 +3,18 @@
 ;
 ; The installer needs Cygwin with mintty. It puts bm and the bm-* tools in
 ; /usr/local/bin, fzf.exe in /usr/local/libexec/sbm, and the settings in
-; /etc/profile.d/sbm.sh. It also makes a desktop shortcut that opens bm in a
-; mintty window. The key of the shortcut is Ctrl+Alt+Shift+F24. Almost no
-; keyboard has an F24 key, so keyboard firmware can use this key combination
-; without conflicts.
+; /etc/profile.d/sbm.sh. It makes a desktop shortcut and a Start menu entry
+; that open bm in a mintty window. The key of the desktop shortcut is
+; Ctrl+Alt+Shift+F24. Almost no keyboard has an F24 key, so keyboard firmware
+; can use this key combination without conflicts. Only one shortcut has the
+; key: when two shortcuts have the same key, Explorer can lose the key.
 ;
-; The uninstaller removes these files. It keeps the bookmarks of the user.
+; A Startup entry runs bm-watch in a hidden mintty at each login. bm-watch
+; brings the bookmarks of the Chromium browsers into bm, and then the new
+; bookmarks as you add them. The installer also starts bm-watch at once.
+;
+; The uninstaller stops bm-watch and removes these files. It keeps the
+; bookmarks of the user.
 
 Unicode true
 ManifestDPIAware true
@@ -29,6 +35,7 @@ ManifestDPIAware true
 
 !define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\sbm"
 !define MINTTYARGS "--class sbm -t sbm -s 120,32 -p center -o ConfirmExit=no -o Scrollbar=none /bin/bash -lc bm"
+!define WATCHARGS '--class sbm-watch -w hide /bin/bash -lc "exec bm-watch brave chrome chromium edge vivaldi"'
 
 Name "sbm ${VERSION}"
 OutFile "${OUTFILE}"
@@ -63,6 +70,12 @@ Function .onInit
 FunctionEnd
 
 Section
+  ; An earlier version can run bm-watch. Stop it before its files change.
+  ${If} ${FileExists} "$Cygwin\usr\local\libexec\sbm\sbm-setup"
+    nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup stop'
+    Pop $0
+  ${EndIf}
+
   SetOutPath "$Cygwin\usr\local\bin"
   File "${SRC}\bin\bm"
   File "${SRC}\bin\bm-check"
@@ -71,6 +84,7 @@ Section
   File "${SRC}\bin\bm-import"
   File "${SRC}\bin\bm-migrate"
   File "${SRC}\bin\bm-title"
+  File "${SRC}\bin\bm-watch"
   File "${SRC}\bin\fzf"
   SetOutPath "$Cygwin\usr\local\libexec\sbm"
   File "${SRC}\libexec\fzf.exe"
@@ -84,24 +98,39 @@ Section
 
   ; Cygwin does not see an execute permission on files that a Windows
   ; program makes. Cygwin chmod sets it.
-  nsExec::ExecToLog '"$Cygwin\bin\chmod.exe" 755 /usr/local/bin/bm /usr/local/bin/bm-check /usr/local/bin/bm-commit /usr/local/bin/bm-html /usr/local/bin/bm-import /usr/local/bin/bm-migrate /usr/local/bin/bm-title /usr/local/bin/fzf /usr/local/libexec/sbm/fzf.exe'
+  nsExec::ExecToLog '"$Cygwin\bin\chmod.exe" 755 /usr/local/bin/bm /usr/local/bin/bm-check /usr/local/bin/bm-commit /usr/local/bin/bm-html /usr/local/bin/bm-import /usr/local/bin/bm-migrate /usr/local/bin/bm-title /usr/local/bin/bm-watch /usr/local/bin/fzf /usr/local/libexec/sbm/fzf.exe'
   Pop $0
   ${If} $0 != 0
     Abort "chmod failed with exit status $0"
   ${EndIf}
 
-  nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup'
+  nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup data'
   Pop $0
   ${If} $0 != 0
     Abort "sbm-setup failed with exit status $0"
   ${EndIf}
 
+  ; bm-import reads the bookmarks of a browser with jq.
+  ${IfNot} ${FileExists} "$Cygwin\bin\jq.exe"
+    MessageBox MB_ICONEXCLAMATION|MB_OK "The browser import needs jq.$\r$\nInstall the jq package with Cygwin setup." /SD IDOK
+  ${EndIf}
+
   WriteUninstaller "$Cygwin\usr\local\libexec\sbm\uninstall.exe"
 
   SetShellVarContext current
   CreateShortcut /NoWorkingDir "$DESKTOP\sbm.lnk" "$Cygwin\bin\mintty.exe" \
     "${MINTTYARGS}" "$Cygwin\bin\mintty.exe" 0 SW_SHOWNORMAL \
     ALT|CONTROL|SHIFT|F24 "sbm: bookmarks in fzf"
+  CreateShortcut /NoWorkingDir "$SMPROGRAMS\sbm.lnk" "$Cygwin\bin\mintty.exe" \
+    "${MINTTYARGS}" "$Cygwin\bin\mintty.exe" 0 SW_SHOWNORMAL "" \
+    "sbm: bookmarks in fzf"
+  CreateShortcut /NoWorkingDir "$SMSTARTUP\sbm-watch.lnk" "$Cygwin\bin\mintty.exe" \
+    '${WATCHARGS}' "$Cygwin\bin\mintty.exe" 0 SW_SHOWMINIMIZED "" \
+    "sbm: bring new browser bookmarks into bm"
+
+  ; Start bm-watch now. Explorer starts it as the user, not as the
+  ; administrator that runs this installer.
+  Exec '"$WINDIR\explorer.exe" "$SMSTARTUP\sbm-watch.lnk"'
 
   WriteRegStr HKLM "${UNINSTKEY}" "DisplayName" "sbm"
   WriteRegStr HKLM "${UNINSTKEY}" "DisplayVersion" "${VERSION}"
@@ -123,6 +152,9 @@ Function un.onInit
 FunctionEnd
 
 Section Uninstall
+  nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup stop'
+  Pop $0
+
   Delete "$Cygwin\usr\local\bin\bm"
   Delete "$Cygwin\usr\local\bin\bm-check"
   Delete "$Cygwin\usr\local\bin\bm-commit"
@@ -130,6 +162,7 @@ Section Uninstall
   Delete "$Cygwin\usr\local\bin\bm-import"
   Delete "$Cygwin\usr\local\bin\bm-migrate"
   Delete "$Cygwin\usr\local\bin\bm-title"
+  Delete "$Cygwin\usr\local\bin\bm-watch"
   Delete "$Cygwin\usr\local\bin\fzf"
   Delete "$Cygwin\usr\local\libexec\sbm\fzf.exe"
   Delete "$Cygwin\usr\local\libexec\sbm\fzf-LICENSE.txt"
@@ -142,5 +175,7 @@ Section Uninstall
   Delete "$Cygwin\etc\profile.d\sbm.sh"
   SetShellVarContext current
   Delete "$DESKTOP\sbm.lnk"
+  Delete "$SMPROGRAMS\sbm.lnk"
+  Delete "$SMSTARTUP\sbm-watch.lnk"
   DeleteRegKey HKLM "${UNINSTKEY}"
 SectionEnd