Skip to content

Commit

Permalink
Merge branch 'main' into ast-align
Browse files Browse the repository at this point in the history
  • Loading branch information
jaspervdj committed Feb 5, 2025
2 parents d75c133 + eb62801 commit ebb8ce5
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## unreleased

* Use a temporary file to atomically write speaker notes.

We weren't writing the file all-at-once before, so if you were using a
simple tool like `tail -F` before, this could cause some speaker notes to
not be displayed.

## 0.13.0.0 (2024-10-30)

* Incrementally display output of `eval` commands (#132)
Expand Down
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,13 +791,11 @@ patat:
```

Then, you can display these in a second terminal (presumably on a second
monitor) by just displaying this file whenever it changes. [entr] is one
way to do that:

[entr]: http://eradman.com/entrproject/
monitor) by just displaying this file whenever it changes. `tail` is a primitive
way of doing that:

```bash
echo /tmp/notes.txt | entr -s 'clear; cat /tmp/notes.txt'
tail -F /tmp/notes.txt
```

Alternatively, just use a second `patat` instance with `--watch` enabled:
Expand Down
20 changes: 16 additions & 4 deletions lib/Patat/Presentation/SpeakerNotes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import qualified Data.Text.IO as T
import Patat.EncodingFallback (EncodingFallback)
import qualified Patat.EncodingFallback as EncodingFallback
import Patat.Presentation.Settings
import System.Directory (removeFile)
import System.Directory (removeFile, renameFile)
import System.FilePath (splitFileName, (</>))
import qualified System.IO as IO


Expand Down Expand Up @@ -56,6 +57,17 @@ write
:: Handle -> EncodingFallback -> SpeakerNotes -> IO ()
write h encodingFallback sn = do
change <- IORef.atomicModifyIORef' (hActive h) $ \old -> (sn, old /= sn)
when change $ IO.withFile (snsFile $ hSettings h) IO.WriteMode $ \ioh ->
EncodingFallback.withHandle ioh encodingFallback $
T.hPutStr ioh $ toText sn
when change $ do
-- Write the file and then rename it to get atomic replace.
IO.withFile speakerNotesTmpPath IO.WriteMode $ \ioh ->
EncodingFallback.withHandle ioh encodingFallback $
T.hPutStr ioh $ toText sn
renameFile speakerNotesTmpPath speakerNotesPath
where
speakerNotesPath = snsFile $ hSettings h
speakerNotesTmpPath =
-- We only get atomic rename if we're on the same filesystem. I think
-- we can assume that the directory the speaker notes are in is
-- | entr -s 'clear; cat /tmp/notes.txt'writable.
let (dir, name) = splitFileName speakerNotesPath in
dir </> ".tmp." <> name

0 comments on commit ebb8ce5

Please sign in to comment.