1
+ {-# LANGUAGE BangPatterns #-}
1
2
{-# LANGUAGE DataKinds #-}
2
3
{-# LANGUAGE OverloadedStrings #-}
3
4
{-# LANGUAGE ScopedTypeVariables #-}
4
-
5
5
{-# LANGUAGE TypeOperators #-}
6
6
7
7
module Server where
@@ -67,13 +67,16 @@ root (ToodlesState _ dPath) path =
67
67
68
68
showRawFile :: ToodlesState -> Integer -> Handler Html
69
69
showRawFile (ToodlesState ref _) eId = do
70
- (TodoListResult r _) <- liftIO $ readIORef ref
71
- let entry = find (\ t -> entryId t == eId) r
72
- liftIO $
73
- maybe
74
- (return " Not found" )
75
- (\ e -> addAnchors <$> readFile (sourceFile e))
76
- entry
70
+ storedResults <- liftIO $ readIORef ref
71
+ case storedResults of
72
+ (Just (TodoListResult r _)) -> do
73
+ let entry = find (\ t -> entryId t == eId) r
74
+ liftIO $
75
+ maybe
76
+ (return " Not found" )
77
+ (\ e -> addAnchors <$> readFile (sourceFile e))
78
+ entry
79
+ Nothing -> error " no files to show"
77
80
78
81
where
79
82
addAnchors :: String -> Html
@@ -87,17 +90,20 @@ showRawFile (ToodlesState ref _) eId = do
87
90
88
91
editTodos :: ToodlesState -> EditTodoRequest -> Handler Text
89
92
editTodos (ToodlesState ref _) req = do
90
- (TodoListResult r _) <- liftIO $ readIORef ref
91
- let editedList =
92
- map
93
- (\ t ->
94
- if willEditTodo req t
95
- then editTodo req t
96
- else t)
97
- r
98
- editedFilteredList = filter (willEditTodo req) editedList
99
- _ <- mapM_ recordUpdates editedFilteredList
100
- return " {}"
93
+ storedResults <- liftIO $ readIORef ref
94
+ case storedResults of
95
+ (Just (TodoListResult r _)) -> do
96
+ let editedList =
97
+ map
98
+ (\ t ->
99
+ if willEditTodo req t
100
+ then editTodo req t
101
+ else t)
102
+ r
103
+ editedFilteredList = filter (willEditTodo req) editedList
104
+ _ <- mapM_ recordUpdates editedFilteredList
105
+ return " {}"
106
+ Nothing -> error " no stored todos to edit"
101
107
where
102
108
willEditTodo :: EditTodoRequest -> TodoEntry -> Bool
103
109
willEditTodo editRequest entry = entryId entry `elem` editIds editRequest
@@ -189,14 +195,17 @@ updateTodoLinesInFile f todo = do
189
195
190
196
deleteTodos :: ToodlesState -> DeleteTodoRequest -> Handler Text
191
197
deleteTodos (ToodlesState ref _) req = do
192
- refVal@ (TodoListResult r _) <- liftIO $ readIORef ref
193
- let toDelete = filter (\ t -> entryId t `elem` ids req) r
194
- liftIO $ doUntilNull removeAndAdjust toDelete
195
- let remainingResults = filter (\ t -> entryId t `notElem` map entryId toDelete) r
196
- let updatedResults = foldl (flip adjustLinesAfterDeletionOf) remainingResults toDelete
197
- let remainingResultsRef = refVal { todos = updatedResults }
198
- _ <- liftIO $ atomicModifyIORef' ref (const (remainingResultsRef, remainingResultsRef))
199
- return " {}"
198
+ storedResults <- liftIO $ readIORef ref
199
+ case storedResults of
200
+ (Just refVal@ (TodoListResult r _)) -> do
201
+ let toDelete = filter (\ t -> entryId t `elem` ids req) r
202
+ liftIO $ doUntilNull removeAndAdjust toDelete
203
+ let remainingResults = filter (\ t -> entryId t `notElem` map entryId toDelete) r
204
+ let updatedResults = foldl (flip adjustLinesAfterDeletionOf) remainingResults toDelete
205
+ let remainingResultsRef = refVal { todos = updatedResults }
206
+ _ <- liftIO $ atomicModifyIORef' ref (const (Just remainingResultsRef, Just remainingResultsRef))
207
+ return " {}"
208
+ Nothing -> error " no stored todos"
200
209
201
210
where
202
211
@@ -239,14 +248,17 @@ setAbsolutePath args = do
239
248
return $ args {directory = absolute}
240
249
241
250
getFullSearchResults :: ToodlesState -> Bool -> IO TodoListResult
242
- getFullSearchResults (ToodlesState ref _) recompute =
243
- if recompute
251
+ getFullSearchResults (ToodlesState ref _) recompute = do
252
+ result <- readIORef ref
253
+ if recompute || isNothing result
244
254
then do
245
255
putStrLn " refreshing todo's"
246
256
userArgs <- toodlesArgs >>= setAbsolutePath
247
257
sResults <- runFullSearch userArgs
248
- atomicModifyIORef' ref (const (sResults, sResults))
249
- else putStrLn " cached read" >> readIORef ref
258
+ atomicModifyIORef' ref (const (Just sResults, sResults))
259
+ else do
260
+ putStrLn " cached read"
261
+ return $ fromMaybe (error " tried to read from the cache when there wasn't anything there" ) result
250
262
251
263
runFullSearch :: ToodlesArgs -> IO TodoListResult
252
264
runFullSearch userArgs = do
@@ -259,8 +271,8 @@ runFullSearch userArgs = do
259
271
$ putStrLn $ " [WARNING] Invalid .toodles.yaml: " ++ show config
260
272
let config' = fromRight (ToodlesConfig [] [] ) config
261
273
allFiles <- getAllFiles config' projectRoot
262
- let parsedTodos = concatMap (runTodoParser $ userFlag userArgs ++ flags config') allFiles
263
- filteredTodos = filter (filterSearch (assignee_search userArgs)) parsedTodos
274
+ parsedTodos <- concat <$> mapM (parseFileAndLog userArgs config') allFiles
275
+ let filteredTodos = filter (filterSearch (assignee_search userArgs)) parsedTodos
264
276
resultList = limitSearch filteredTodos $ limit_results userArgs
265
277
indexedResults = map (\ (i, r) -> r {entryId = i}) $ zip [1 .. ] resultList
266
278
return $ TodoListResult indexedResults " "
@@ -274,6 +286,14 @@ runFullSearch userArgs = do
274
286
limitSearch todoList 0 = todoList
275
287
limitSearch todoList n = take n todoList
276
288
289
+ parseFileAndLog :: ToodlesArgs -> ToodlesConfig -> SourceFile -> IO [TodoEntry ]
290
+ parseFileAndLog userArgs config f = do
291
+ -- the strictness is so we can print "done" when we're actually done
292
+ ! _ <- putStrLn $ fullPath f
293
+ ! result <- return (runTodoParser (userFlag userArgs ++ flags config) f)
294
+ ! _ <- putStrLn " done"
295
+ return result
296
+
277
297
getAllFiles :: ToodlesConfig -> FilePath -> IO [SourceFile ]
278
298
getAllFiles (ToodlesConfig ignoredPaths _) basePath =
279
299
E. catch
0 commit comments