Skip to content

Commit

Permalink
Atomically write speaker notes
Browse files Browse the repository at this point in the history
  • Loading branch information
jaspervdj committed Nov 26, 2024
1 parent 05f0a9b commit eb62801
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/Comments.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import qualified Data.Yaml as Yaml
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
import qualified Text.Pandoc as Pandoc

Expand Down Expand Up @@ -136,9 +137,20 @@ writeSpeakerNotes
:: SpeakerNotesHandle -> EncodingFallback -> SpeakerNotes -> IO ()
writeSpeakerNotes h encodingFallback sn = do
change <- IORef.atomicModifyIORef' (snhActive h) $ \old -> (sn, old /= sn)
when change $ IO.withFile (snsFile $ snhSettings h) IO.WriteMode $ \ioh ->
EncodingFallback.withHandle ioh encodingFallback $
T.hPutStr ioh $ speakerNotesToText 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 $ speakerNotesToText sn
renameFile speakerNotesTmpPath speakerNotesPath
where
speakerNotesPath = snsFile $ snhSettings 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


--------------------------------------------------------------------------------
Expand Down

0 comments on commit eb62801

Please sign in to comment.