Update HIE
[lsp-test.git] / test / recordings / renamePass / client.log
index 2d854f4350013eb809baa1f63169d83b0321ff91..dfe4a48ba8091c30b12060517d247041771377c0 100644 (file)
@@ -1,17 +1,17 @@
-Content-Length: 400\r
+Content-Length: 380\r
 \r
-{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"textDocument":{"completion":{"completionItem":{"commitCharactersSupport":null,"documentationFormat":null,"snippetSupport":false},"dynamicRegistration":null}}},"initializationOptions":null,"processId":60645,"rootPath":"/Users/luke/Repos/haskell-lsp-client","rootUri":"file:///Users/luke/Repos/haskell-lsp-client","trace":"off"},"id":9}Content-Length: 52\r
+{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"textDocument":{"completion":{"completionItem":{"commitCharactersSupport":null,"documentationFormat":null,"snippetSupport":false},"dynamicRegistration":null}}},"initializationOptions":{"cacheDirectory":"/tmp/lspCache"},"processId":25669,"rootPath":"/Users/luke","rootUri":"file:///Users/luke","trace":"off"},"id":9}Content-Length: 52\r
 \r
-{"jsonrpc":"2.0","method":"initialized","params":{}}Content-Length: 5528\r
+{"jsonrpc":"2.0","method":"initialized","params":{}}Content-Length: 144\r
 \r
-{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"haskell","text":"{-# LANGUAGE OverloadedStrings #-}\n{-# LANGUAGE LambdaCase #-}\nmodule Main where\n\nimport qualified Language.Haskell.LSP.TH.DataTypesJSON as LSP\nimport qualified Language.Haskell.LSP.TH.ClientCapabilities as LSP\nimport qualified LSP.Client as Client\nimport Data.Proxy\nimport qualified Data.Text.IO as T\nimport Control.Concurrent\nimport System.Process\nimport Control.Lens\nimport System.IO\nimport System.Exit\nimport System.Environment\nimport System.Directory\nimport Control.Monad\n\nimport qualified Compat\n\nmain :: IO ()\nmain = do\n  progName <- getProgName\n  args <- getArgs\n\n  when (length args /= 1) $ do\n    hPutStrLn stderr (\"This program expects one argument: \" ++ progName ++ \" FILEPATH\")\n    exitFailure\n\n  let [path] = args\n\n  exists <- doesFileExist path\n  unless exists $ do\n    hPutStrLn stderr (\"File does not exist: \" ++ path)\n    exitFailure\n\n  file <- canonicalizePath path\n\n  pid <- Compat.getPID\n\n  let caps = LSP.ClientCapabilities (Just workspaceCaps) (Just textDocumentCaps) Nothing\n      workspaceCaps = LSP.WorkspaceClientCapabilities\n        (Just False)\n        (Just (LSP.WorkspaceEditClientCapabilities (Just False)))\n        (Just (LSP.DidChangeConfigurationClientCapabilities (Just False)))\n        (Just (LSP.DidChangeWatchedFilesClientCapabilities (Just False)))\n        (Just (LSP.SymbolClientCapabilities (Just False)))\n        (Just (LSP.ExecuteClientCapabilities (Just False)))\n      textDocumentCaps = LSP.TextDocumentClientCapabilities\n        (Just (LSP.SynchronizationTextDocumentClientCapabilities\n                 (Just False)\n                 (Just False)\n                 (Just False)\n                 (Just False)))\n        (Just (LSP.CompletionClientCapabilities\n                 (Just False)\n                 (Just (LSP.CompletionItemClientCapabilities (Just False)))))\n        (Just (LSP.HoverClientCapabilities (Just False)))\n        (Just (LSP.SignatureHelpClientCapabilities (Just False)))\n        (Just (LSP.ReferencesClientCapabilities (Just False)))\n        (Just (LSP.DocumentHighlightClientCapabilities (Just False)))\n        (Just (LSP.DocumentSymbolClientCapabilities (Just False)))\n        (Just (LSP.FormattingClientCapabilities (Just False)))\n        (Just (LSP.RangeFormattingClientCapabilities (Just False)))\n        (Just (LSP.OnTypeFormattingClientCapabilities (Just False)))\n        (Just (LSP.DefinitionClientCapabilities (Just False)))\n        (Just (LSP.CodeActionClientCapabilities (Just False)))\n        (Just (LSP.CodeLensClientCapabilities (Just False)))\n        (Just (LSP.DocumentLinkClientCapabilities (Just False)))\n        (Just (LSP.RenameClientCapabilities (Just False)))\n\n      initializeParams :: LSP.InitializeParams\n      initializeParams = LSP.InitializeParams (Just pid) Nothing Nothing Nothing caps Nothing\n\n\n  (Just inp, Just out, _, _) <- createProcess (proc \"hie\" [\"--lsp\", \"-l\", \"/tmp/hie.log\", \"--debug\"])\n    {std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe}\n\n  client <- Client.start (Client.Config inp out testNotificationMessageHandler testRequestMessageHandler)\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.InitializeRequest) LSP.Initialize initializeParams\n\n  Client.sendClientNotification client LSP.Initialized (Just LSP.InitializedParams)\n\n  txt <- T.readFile file\n\n  let uri = LSP.filePathToUri file\n\n  Client.sendClientNotification client LSP.TextDocumentDidOpen (Just (LSP.DidOpenTextDocumentParams (LSP.TextDocumentItem uri \"haskell\" 1 txt)))\n\n  Client.sendClientRequest\n    client\n    (Proxy :: Proxy LSP.DefinitionRequest)\n    LSP.TextDocumentDefinition\n    (LSP.TextDocumentPositionParams (LSP.TextDocumentIdentifier uri) (LSP.Position 88 36)) >>= \\case\n      Just (Right pos) -> print pos\n      _ -> putStrLn \"Server couldn't give us defnition position\"\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.DocumentSymbolRequest) LSP.TextDocumentDocumentSymbol (LSP.DocumentSymbolParams (LSP.TextDocumentIdentifier uri))\n    >>= \\case\n      Just (Right as) -> mapM_ T.putStrLn (as ^.. traverse . LSP.name)\n      _ -> putStrLn \"Server couldn't give us document symbol information\"\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.ShutdownRequest) LSP.Shutdown Nothing\n  Client.sendClientNotification client LSP.Exit (Just LSP.ExitParams)\n\n  Client.stop client\n\ntestRequestMessageHandler :: Client.RequestMessageHandler\ntestRequestMessageHandler = Client.RequestMessageHandler\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  where\n    toRspId (LSP.IdInt i) = LSP.IdRspInt i\n    toRspId (LSP.IdString t) = LSP.IdRspString t\n\n    emptyResponse :: LSP.RequestMessage m req resp -> LSP.ResponseMessage a\n    emptyResponse m = LSP.ResponseMessage (m ^. LSP.jsonrpc) (toRspId (m ^. LSP.id)) Nothing Nothing\n\ntestNotificationMessageHandler :: Client.NotificationMessageHandler\ntestNotificationMessageHandler = Client.NotificationMessageHandler\n  (T.putStrLn . view (LSP.params . LSP.message))\n  (T.putStrLn . view (LSP.params . LSP.message))\n  (print . view LSP.params)\n  (mapM_ T.putStrLn . (^.. LSP.params . LSP.diagnostics . traverse . LSP.message))\n","uri":"file:///Users/luke/Repos/haskell-lsp-client/example/Main.hs","version":0}}}Content-Length: 38\r
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"initializationOptions":{"cacheDirectory":"/tmp/lspCache"}}}}Content-Length: 2084\r
 \r
-{"jsonrpc":"2.0","result":null,"id":0}Content-Length: 5560\r
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"haskell","text":"module Main where\n\nmain :: IO ()\nmain = do\n  let initialList = []\n  interactWithUser initialList\n\ntype Item = String\ntype Items = [Item]\n\ndata Command = Quit\n             | DisplayItems\n             | AddItem String\n             | RemoveItem Int\n             | Help\n\ntype Error = String\n\nparseCommand :: String -> Either Error Command\nparseCommand line = case words line of\n  [\"quit\"] -> Right Quit\n  [\"items\"] -> Right DisplayItems\n  \"add\" : item -> Right $ AddItem $ unwords item\n  \"remove\" : i -> Right $ RemoveItem $ read $ unwords i\n  [\"help\"] -> Right Help\n  _ -> Left \"Unknown command\"\n\naddItem :: Item -> Items -> Items\naddItem = (:)\n\ndisplayItems :: Items -> String\ndisplayItems = unlines . map (\"- \" ++)\n\nremoveItem :: Int -> Items -> Either Error Items\nremoveItem i items\n  | i < 0 || i >= length items = Left \"Out of range\"\n  | otherwise = Right result\n  where (front, back) = splitAt (i + 1) items\n        result = init front ++ back\n\ninteractWithUser :: Items -> IO ()\ninteractWithUser items = do\n  line <- getLine\n  case parseCommand line of\n    Right DisplayItems -> do\n      putStrLn $ displayItems items\n      interactWithUser items\n\n    Right (AddItem item) -> do\n      let newItems = addItem item items\n      putStrLn \"Added\"\n      interactWithUser newItems\n\n    Right (RemoveItem i) ->\n      case removeItem i items of\n        Right newItems -> do\n          putStrLn $ \"Removed \" ++ items !! i\n          interactWithUser newItems\n        Left err -> do\n          putStrLn err\n          interactWithUser items\n\n\n    Right Quit -> return ()\n\n    Right Help -> do\n      putStrLn \"Commands:\"\n      putStrLn \"help\"\n      putStrLn \"items\"\n      putStrLn \"add\"\n      putStrLn \"quit\"\n      interactWithUser items\n\n    Left err -> do\n      putStrLn $ \"Error: \" ++ err\n      interactWithUser items\n","uri":"file:///Users/luke/Desktop/simple.hs","version":0}}}Content-Length: 137\r
 \r
-{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"range":null,"rangeLength":null,"text":"{-# LANGUAGE OverloadedStrings #-}\n{-# LANGUAGE LambdaCase #-}\nmodule Main where\n\nimport qualified Language.Haskell.LSP.TH.DataTypesJSON as LSP\nimport qualified Language.Haskell.LSP.TH.ClientCapabilities as LSP\nimport qualified LSP.Client as Client\nimport Data.Proxy\nimport qualified Data.Text.IO as T\nimport Control.Concurrent\nimport System.Process\nimport Control.Lens\nimport System.IO\nimport System.Exit\nimport System.Environment\nimport System.Directory\nimport Control.Monad\n\nimport qualified Compat\n\nmain :: IO ()\nmain = do\n  progName <- getProgName\n  args <- getArgs\n\n  when (length args /= 1) $ do\n    hPutStrLn stderr (\"This program expects one argument: \" ++ progName ++ \" FILEPATH\")\n    exitFailure\n\n  let [path] = args\n\n  exists <- doesFileExist path\n  unless exists $ do\n    hPutStrLn stderr (\"File does not exist: \" ++ path)\n    exitFailure\n\n  file <- canonicalizePath patj\n\n  pid <- Compat.getPID\n\n  let caps = LSP.ClientCapabilities (Just workspaceCaps) (Just textDocumentCaps) Nothing\n      workspaceCaps = LSP.WorkspaceClientCapabilities\n        (Just False)\n        (Just (LSP.WorkspaceEditClientCapabilities (Just False)))\n        (Just (LSP.DidChangeConfigurationClientCapabilities (Just False)))\n        (Just (LSP.DidChangeWatchedFilesClientCapabilities (Just False)))\n        (Just (LSP.SymbolClientCapabilities (Just False)))\n        (Just (LSP.ExecuteClientCapabilities (Just False)))\n      textDocumentCaps = LSP.TextDocumentClientCapabilities\n        (Just (LSP.SynchronizationTextDocumentClientCapabilities\n                 (Just False)\n                 (Just False)\n                 (Just False)\n                 (Just False)))\n        (Just (LSP.CompletionClientCapabilities\n                 (Just False)\n                 (Just (LSP.CompletionItemClientCapabilities (Just False)))))\n        (Just (LSP.HoverClientCapabilities (Just False)))\n        (Just (LSP.SignatureHelpClientCapabilities (Just False)))\n        (Just (LSP.ReferencesClientCapabilities (Just False)))\n        (Just (LSP.DocumentHighlightClientCapabilities (Just False)))\n        (Just (LSP.DocumentSymbolClientCapabilities (Just False)))\n        (Just (LSP.FormattingClientCapabilities (Just False)))\n        (Just (LSP.RangeFormattingClientCapabilities (Just False)))\n        (Just (LSP.OnTypeFormattingClientCapabilities (Just False)))\n        (Just (LSP.DefinitionClientCapabilities (Just False)))\n        (Just (LSP.CodeActionClientCapabilities (Just False)))\n        (Just (LSP.CodeLensClientCapabilities (Just False)))\n        (Just (LSP.DocumentLinkClientCapabilities (Just False)))\n        (Just (LSP.RenameClientCapabilities (Just False)))\n\n      initializeParams :: LSP.InitializeParams\n      initializeParams = LSP.InitializeParams (Just pid) Nothing Nothing Nothing caps Nothing\n\n\n  (Just inp, Just out, _, _) <- createProcess (proc \"hie\" [\"--lsp\", \"-l\", \"/tmp/hie.log\", \"--debug\"])\n    {std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe}\n\n  client <- Client.start (Client.Config inp out testNotificationMessageHandler testRequestMessageHandler)\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.InitializeRequest) LSP.Initialize initializeParams\n\n  Client.sendClientNotification client LSP.Initialized (Just LSP.InitializedParams)\n\n  txt <- T.readFile file\n\n  let uri = LSP.filePathToUri file\n\n  Client.sendClientNotification client LSP.TextDocumentDidOpen (Just (LSP.DidOpenTextDocumentParams (LSP.TextDocumentItem uri \"haskell\" 1 txt)))\n\n  Client.sendClientRequest\n    client\n    (Proxy :: Proxy LSP.DefinitionRequest)\n    LSP.TextDocumentDefinition\n    (LSP.TextDocumentPositionParams (LSP.TextDocumentIdentifier uri) (LSP.Position 88 36)) >>= \\case\n      Just (Right pos) -> print pos\n      _ -> putStrLn \"Server couldn't give us defnition position\"\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.DocumentSymbolRequest) LSP.TextDocumentDocumentSymbol (LSP.DocumentSymbolParams (LSP.TextDocumentIdentifier uri))\n    >>= \\case\n      Just (Right as) -> mapM_ T.putStrLn (as ^.. traverse . LSP.name)\n      _ -> putStrLn \"Server couldn't give us document symbol information\"\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.ShutdownRequest) LSP.Shutdown Nothing\n  Client.sendClientNotification client LSP.Exit (Just LSP.ExitParams)\n\n  Client.stop client\n\ntestRequestMessageHandler :: Client.RequestMessageHandler\ntestRequestMessageHandler = Client.RequestMessageHandler\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  where\n    toRspId (LSP.IdInt i) = LSP.IdRspInt i\n    toRspId (LSP.IdString t) = LSP.IdRspString t\n\n    emptyResponse :: LSP.RequestMessage m req resp -> LSP.ResponseMessage a\n    emptyResponse m = LSP.ResponseMessage (m ^. LSP.jsonrpc) (toRspId (m ^. LSP.id)) Nothing Nothing\n\ntestNotificationMessageHandler :: Client.NotificationMessageHandler\ntestNotificationMessageHandler = Client.NotificationMessageHandler\n  (T.putStrLn . view (LSP.params . LSP.message))\n  (T.putStrLn . view (LSP.params . LSP.message))\n  (print . view LSP.params)\n  (mapM_ T.putStrLn . (^.. LSP.params . LSP.diagnostics . traverse . LSP.message))\n"}],"textDocument":{"uri":"file:///Users/luke/Repos/haskell-lsp-client/example/Main.hs","version":1}}}Content-Length: 5560\r
+{"jsonrpc":"2.0","method":"textDocument/documentSymbol","params":{"textDocument":{"uri":"file:///Users/luke/Desktop/simple.hs"}},"id":16}Content-Length: 137\r
 \r
-{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"range":null,"rangeLength":null,"text":"{-# LANGUAGE OverloadedStrings #-}\n{-# LANGUAGE LambdaCase #-}\nmodule Main where\n\nimport qualified Language.Haskell.LSP.TH.DataTypesJSON as LSP\nimport qualified Language.Haskell.LSP.TH.ClientCapabilities as LSP\nimport qualified LSP.Client as Client\nimport Data.Proxy\nimport qualified Data.Text.IO as T\nimport Control.Concurrent\nimport System.Process\nimport Control.Lens\nimport System.IO\nimport System.Exit\nimport System.Environment\nimport System.Directory\nimport Control.Monad\n\nimport qualified Compat\n\nmain :: IO ()\nmain = do\n  progName <- getProgName\n  args <- getArgs\n\n  when (length args /= 1) $ do\n    hPutStrLn stderr (\"This program expects one argument: \" ++ progName ++ \" FILEPATH\")\n    exitFailure\n\n  let [path] = args\n\n  exists <- doesFileExist path\n  unless exists $ do\n    hPutStrLn stderr (\"File does not exist: \" ++ path)\n    exitFailure\n\n  file <- canonicalizePath path\n\n  pid <- Compat.getPID\n\n  let caps = LSP.ClientCapabilities (Just workspaceCaps) (Just textDocumentCaps) Nothing\n      workspaceCaps = LSP.WorkspaceClientCapabilities\n        (Just False)\n        (Just (LSP.WorkspaceEditClientCapabilities (Just False)))\n        (Just (LSP.DidChangeConfigurationClientCapabilities (Just False)))\n        (Just (LSP.DidChangeWatchedFilesClientCapabilities (Just False)))\n        (Just (LSP.SymbolClientCapabilities (Just False)))\n        (Just (LSP.ExecuteClientCapabilities (Just False)))\n      textDocumentCaps = LSP.TextDocumentClientCapabilities\n        (Just (LSP.SynchronizationTextDocumentClientCapabilities\n                 (Just False)\n                 (Just False)\n                 (Just False)\n                 (Just False)))\n        (Just (LSP.CompletionClientCapabilities\n                 (Just False)\n                 (Just (LSP.CompletionItemClientCapabilities (Just False)))))\n        (Just (LSP.HoverClientCapabilities (Just False)))\n        (Just (LSP.SignatureHelpClientCapabilities (Just False)))\n        (Just (LSP.ReferencesClientCapabilities (Just False)))\n        (Just (LSP.DocumentHighlightClientCapabilities (Just False)))\n        (Just (LSP.DocumentSymbolClientCapabilities (Just False)))\n        (Just (LSP.FormattingClientCapabilities (Just False)))\n        (Just (LSP.RangeFormattingClientCapabilities (Just False)))\n        (Just (LSP.OnTypeFormattingClientCapabilities (Just False)))\n        (Just (LSP.DefinitionClientCapabilities (Just False)))\n        (Just (LSP.CodeActionClientCapabilities (Just False)))\n        (Just (LSP.CodeLensClientCapabilities (Just False)))\n        (Just (LSP.DocumentLinkClientCapabilities (Just False)))\n        (Just (LSP.RenameClientCapabilities (Just False)))\n\n      initializeParams :: LSP.InitializeParams\n      initializeParams = LSP.InitializeParams (Just pid) Nothing Nothing Nothing caps Nothing\n\n\n  (Just inp, Just out, _, _) <- createProcess (proc \"hie\" [\"--lsp\", \"-l\", \"/tmp/hie.log\", \"--debug\"])\n    {std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe}\n\n  client <- Client.start (Client.Config inp out testNotificationMessageHandler testRequestMessageHandler)\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.InitializeRequest) LSP.Initialize initializeParams\n\n  Client.sendClientNotification client LSP.Initialized (Just LSP.InitializedParams)\n\n  txt <- T.readFile file\n\n  let uri = LSP.filePathToUri file\n\n  Client.sendClientNotification client LSP.TextDocumentDidOpen (Just (LSP.DidOpenTextDocumentParams (LSP.TextDocumentItem uri \"haskell\" 1 txt)))\n\n  Client.sendClientRequest\n    client\n    (Proxy :: Proxy LSP.DefinitionRequest)\n    LSP.TextDocumentDefinition\n    (LSP.TextDocumentPositionParams (LSP.TextDocumentIdentifier uri) (LSP.Position 88 36)) >>= \\case\n      Just (Right pos) -> print pos\n      _ -> putStrLn \"Server couldn't give us defnition position\"\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.DocumentSymbolRequest) LSP.TextDocumentDocumentSymbol (LSP.DocumentSymbolParams (LSP.TextDocumentIdentifier uri))\n    >>= \\case\n      Just (Right as) -> mapM_ T.putStrLn (as ^.. traverse . LSP.name)\n      _ -> putStrLn \"Server couldn't give us document symbol information\"\n\n  Client.sendClientRequest client (Proxy :: Proxy LSP.ShutdownRequest) LSP.Shutdown Nothing\n  Client.sendClientNotification client LSP.Exit (Just LSP.ExitParams)\n\n  Client.stop client\n\ntestRequestMessageHandler :: Client.RequestMessageHandler\ntestRequestMessageHandler = Client.RequestMessageHandler\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  (\\m -> emptyResponse m <$ print m)\n  where\n    toRspId (LSP.IdInt i) = LSP.IdRspInt i\n    toRspId (LSP.IdString t) = LSP.IdRspString t\n\n    emptyResponse :: LSP.RequestMessage m req resp -> LSP.ResponseMessage a\n    emptyResponse m = LSP.ResponseMessage (m ^. LSP.jsonrpc) (toRspId (m ^. LSP.id)) Nothing Nothing\n\ntestNotificationMessageHandler :: Client.NotificationMessageHandler\ntestNotificationMessageHandler = Client.NotificationMessageHandler\n  (T.putStrLn . view (LSP.params . LSP.message))\n  (T.putStrLn . view (LSP.params . LSP.message))\n  (print . view LSP.params)\n  (mapM_ T.putStrLn . (^.. LSP.params . LSP.diagnostics . traverse . LSP.message))\n"}],"textDocument":{"uri":"file:///Users/luke/Repos/haskell-lsp-client/example/Main.hs","version":2}}}Content-Length: 210\r
+{"jsonrpc":"2.0","method":"textDocument/documentSymbol","params":{"textDocument":{"uri":"file:///Users/luke/Desktop/simple.hs"}},"id":27}Content-Length: 190\r
 \r
-{"jsonrpc":"2.0","method":"textDocument/rename","params":{"newName":"notPath","position":{"character":30,"line":36},"textDocument":{"uri":"file:///Users/luke/Repos/haskell-lsp-client/example/Main.hs"}},"id":45}Content-Length: 47\r
+{"jsonrpc":"2.0","method":"textDocument/rename","params":{"newName":"arseCommand","position":{"character":0,"line":19},"textDocument":{"uri":"file:///Users/luke/Desktop/simple.hs"}},"id":34}Content-Length: 47\r
 \r
 {"jsonrpc":"2.0","method":"exit","params":null}
\ No newline at end of file