Commit e4e026cb authored by Sumit Sahrawat's avatar Sumit Sahrawat

Fix #597: Implement is_complete_{request,reply}

These messages are used by console frontends to check whether the
current input is complete or not. If it is not complete, the next line
is treated as the continuation of the code, and a '...' prompt is used
to show that.

To provide support for qtconsole, I have made it such that IHaskell
always responds to an is_complete_request by saying that the code is
complete, which only allows for single line inputs.
parent 376c6dd0
...@@ -83,6 +83,7 @@ parser ExecuteReplyMessage = executeReplyParser ...@@ -83,6 +83,7 @@ parser ExecuteReplyMessage = executeReplyParser
parser ExecuteErrorMessage = executeErrorParser parser ExecuteErrorMessage = executeErrorParser
parser ExecuteResultMessage = executeResultParser parser ExecuteResultMessage = executeResultParser
parser DisplayDataMessage = displayDataParser parser DisplayDataMessage = displayDataParser
parser IsCompleteRequestMessage = isCompleteRequestParser
parser CompleteRequestMessage = completeRequestParser parser CompleteRequestMessage = completeRequestParser
parser InspectRequestMessage = inspectRequestParser parser InspectRequestMessage = inspectRequestParser
parser ShutdownRequestMessage = shutdownRequestParser parser ShutdownRequestMessage = shutdownRequestParser
...@@ -231,6 +232,11 @@ clearOutputMessageParser = requestParser $ \obj -> do ...@@ -231,6 +232,11 @@ clearOutputMessageParser = requestParser $ \obj -> do
wait <- obj .: "wait" wait <- obj .: "wait"
return $ ClearOutput noHeader wait return $ ClearOutput noHeader wait
isCompleteRequestParser :: LByteString -> Message
isCompleteRequestParser = requestParser $ \obj -> do
code <- obj .: "code"
return $ IsCompleteRequest noHeader code
completeRequestParser :: LByteString -> Message completeRequestParser :: LByteString -> Message
completeRequestParser = requestParser $ \obj -> do completeRequestParser = requestParser $ \obj -> do
code <- obj .: "code" code <- obj .: "code"
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
module IHaskell.IPython.Message.Writer (ToJSON(..)) where module IHaskell.IPython.Message.Writer (ToJSON(..)) where
import Data.Aeson import Data.Aeson
import Data.Aeson.Types (Pair)
import Data.Map (Map) import Data.Map (Map)
import Data.Monoid (mempty) import Data.Monoid (mempty)
import Data.Text (Text, pack) import Data.Text (Text, pack)
...@@ -130,6 +131,18 @@ instance ToJSON Message where ...@@ -130,6 +131,18 @@ instance ToJSON Message where
Left inp -> toJSON inp Left inp -> toJSON inp
Right (inp, out) -> toJSON out) Right (inp, out) -> toJSON out)
toJSON req@IsCompleteReply{} =
object pairs
where
pairs =
case reviewResult req of
CodeComplete -> status "complete"
CodeIncomplete ind -> status "incomplete" ++ indent ind
CodeInvalid -> status "invalid"
CodeUnknown -> status "unknown"
status x = ["status" .= pack x]
indent x = ["indent" .= pack x]
toJSON body = error $ "Do not know how to convert to JSON for message " ++ show body toJSON body = error $ "Do not know how to convert to JSON for message " ++ show body
-- | Print an execution state as "busy", "idle", or "starting". -- | Print an execution state as "busy", "idle", or "starting".
......
...@@ -18,6 +18,7 @@ module IHaskell.IPython.Types ( ...@@ -18,6 +18,7 @@ module IHaskell.IPython.Types (
Username(..), Username(..),
Metadata(..), Metadata(..),
MessageType(..), MessageType(..),
CodeReview(..),
Width(..), Width(..),
Height(..), Height(..),
StreamType(..), StreamType(..),
...@@ -179,6 +180,8 @@ data MessageType = KernelInfoReplyMessage ...@@ -179,6 +180,8 @@ data MessageType = KernelInfoReplyMessage
| DisplayDataMessage | DisplayDataMessage
| OutputMessage | OutputMessage
| InputMessage | InputMessage
| IsCompleteRequestMessage
| IsCompleteReplyMessage
| CompleteRequestMessage | CompleteRequestMessage
| CompleteReplyMessage | CompleteReplyMessage
| InspectRequestMessage | InspectRequestMessage
...@@ -208,6 +211,8 @@ showMessageType StreamMessage = "stream" ...@@ -208,6 +211,8 @@ showMessageType StreamMessage = "stream"
showMessageType DisplayDataMessage = "display_data" showMessageType DisplayDataMessage = "display_data"
showMessageType OutputMessage = "pyout" showMessageType OutputMessage = "pyout"
showMessageType InputMessage = "pyin" showMessageType InputMessage = "pyin"
showMessageType IsCompleteRequestMessage = "is_complete_request"
showMessageType IsCompleteReplyMessage = "is_complete_reply"
showMessageType CompleteRequestMessage = "complete_request" showMessageType CompleteRequestMessage = "complete_request"
showMessageType CompleteReplyMessage = "complete_reply" showMessageType CompleteReplyMessage = "complete_reply"
showMessageType InspectRequestMessage = "inspect_request" showMessageType InspectRequestMessage = "inspect_request"
...@@ -238,6 +243,8 @@ instance FromJSON MessageType where ...@@ -238,6 +243,8 @@ instance FromJSON MessageType where
"display_data" -> return DisplayDataMessage "display_data" -> return DisplayDataMessage
"pyout" -> return OutputMessage "pyout" -> return OutputMessage
"pyin" -> return InputMessage "pyin" -> return InputMessage
"is_complete_request" -> return IsCompleteRequestMessage
"is_complete_reply" -> return IsCompleteReplyMessage
"complete_request" -> return CompleteRequestMessage "complete_request" -> return CompleteRequestMessage
"complete_reply" -> return CompleteReplyMessage "complete_reply" -> return CompleteReplyMessage
"inspect_request" -> return InspectRequestMessage "inspect_request" -> return InspectRequestMessage
...@@ -266,6 +273,12 @@ data LanguageInfo = ...@@ -266,6 +273,12 @@ data LanguageInfo =
} }
deriving (Show, Eq) deriving (Show, Eq)
data CodeReview = CodeComplete
| CodeIncomplete String -- ^ String to be used to indent next line of input
| CodeInvalid
| CodeUnknown
deriving Show
-- | A message used to communicate with the IPython frontend. -- | A message used to communicate with the IPython frontend.
data Message = data Message =
-- | A request from a frontend for information about the kernel. -- | A request from a frontend for information about the kernel.
...@@ -352,6 +365,16 @@ data Message = ...@@ -352,6 +365,16 @@ data Message =
} }
| Input { header :: MessageHeader, getCode :: Text, executionCount :: Int } | Input { header :: MessageHeader, getCode :: Text, executionCount :: Int }
| Output { header :: MessageHeader, getText :: [DisplayData], executionCount :: Int } | Output { header :: MessageHeader, getText :: [DisplayData], executionCount :: Int }
|
IsCompleteRequest
{ header :: MessageHeader
, inputToReview :: String -- ^ The code entered in the repl.
}
|
IsCompleteReply
{ header :: MessageHeader
, reviewResult :: CodeReview -- ^ The result of reviewing the code.
}
| |
CompleteRequest CompleteRequest
{ header :: MessageHeader { header :: MessageHeader
...@@ -487,6 +510,7 @@ instance FromJSON StreamType where ...@@ -487,6 +510,7 @@ instance FromJSON StreamType where
replyType :: MessageType -> Maybe MessageType replyType :: MessageType -> Maybe MessageType
replyType KernelInfoRequestMessage = Just KernelInfoReplyMessage replyType KernelInfoRequestMessage = Just KernelInfoReplyMessage
replyType ExecuteRequestMessage = Just ExecuteReplyMessage replyType ExecuteRequestMessage = Just ExecuteReplyMessage
replyType IsCompleteRequestMessage = Just IsCompleteReplyMessage
replyType CompleteRequestMessage = Just CompleteReplyMessage replyType CompleteRequestMessage = Just CompleteReplyMessage
replyType InspectRequestMessage = Just InspectReplyMessage replyType InspectRequestMessage = Just InspectReplyMessage
replyType ShutdownRequestMessage = Just ShutdownReplyMessage replyType ShutdownRequestMessage = Just ShutdownReplyMessage
......
...@@ -306,6 +306,11 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do ...@@ -306,6 +306,11 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
, status = Ok , status = Ok
}) })
-- Always assume that the code is complete, which allows for only
-- single line inputs for now.
replyTo _ IsCompleteRequest{} replyHeader state = do
let reply = IsCompleteReply { header = replyHeader, reviewResult = CodeComplete }
return (state, reply)
replyTo _ req@CompleteRequest{} replyHeader state = do replyTo _ req@CompleteRequest{} replyHeader state = do
let code = getCode req let code = getCode req
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment