Merge pull request #972 from qnikst/gh-912

Fix protocol communication with jupyter-lab.
This commit is contained in:
Vaibhav Sagar 2018-11-16 16:18:04 -05:00 committed by GitHub
commit 74ef9ac887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 18 additions and 14 deletions

View File

@ -148,7 +148,8 @@ executable ihaskell
strict >=0.3,
unix >= 2.6,
directory -any,
ipython-kernel >=0.7
ipython-kernel >=0.7,
unordered-containers -any
Test-Suite hspec
Type: exitcode-stdio-1.0

View File

@ -34,6 +34,7 @@ import Control.Concurrent (MVar, readChan, writeChan, newMVar, readMVa
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad (forever, when, void)
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
@ -123,7 +124,7 @@ createReplyHeader parent = do
let repType = fromMaybe err (replyType $ mhMsgType parent)
err = error $ "No reply for message " ++ show (mhMsgType parent)
return $ MessageHeader (mhIdentifiers parent) (Just parent) (Map.fromList [])
return $ MessageHeader (mhIdentifiers parent) (Just parent) (Metadata (HashMap.fromList []))
newMessageId (mhSessionId parent) (mhUsername parent) repType
@ -219,7 +220,7 @@ replyTo config _ _ req@CompleteRequest{} replyHeader = do
let start = pos - T.length matchedText
end = pos
reply = CompleteReply replyHeader completions start end Map.empty True
reply = CompleteReply replyHeader completions start end (Metadata HashMap.empty) True
return reply
replyTo config _ _ req@InspectRequest{} replyHeader = do

View File

@ -14,7 +14,6 @@ import Data.Aeson.Types (Parser, parse, parseEither)
import Data.ByteString hiding (unpack)
import qualified Data.ByteString.Lazy as Lazy
import Data.HashMap.Strict as HM
import Data.Map (Map)
import Data.Maybe (fromMaybe)
import Data.Text (Text, unpack)
import Debug.Trace
@ -59,7 +58,7 @@ parseHeader idents headerData parentHeader metadata =
return (messType, username, message, session)
-- Get metadata as a simple map.
Just metadataMap = decode $ Lazy.fromStrict metadata :: Maybe (Map Text Text)
Just metadataMap = fmap Metadata $ decode $ Lazy.fromStrict metadata
noHeader :: MessageHeader
noHeader = error "No header created"

View File

@ -1,4 +1,4 @@
{-# LANGUAGE OverloadedStrings, DeriveDataTypeable, DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings, DeriveDataTypeable, DeriveGeneric, GeneralizedNewtypeDeriving #-}
{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-name-shadowing -fno-warn-unused-matches #-}
-- | This module contains all types used to create an IPython language kernel.
@ -16,7 +16,6 @@ module IHaskell.IPython.Types (
Message(..),
MessageHeader(..),
Username,
Metadata,
MessageType(..),
CodeReview(..),
Width,
@ -27,6 +26,7 @@ module IHaskell.IPython.Types (
HistoryAccessType(..),
HistoryReplyElement(..),
LanguageInfo(..),
Metadata(..),
replyType,
showMessageType,
@ -169,7 +169,8 @@ instance ToJSON MessageHeader where
type Username = Text
-- | A metadata dictionary.
type Metadata = Map Text Text
newtype Metadata = Metadata Object
deriving (Show, Read, ToJSON, Monoid)
-- | The type of a message, corresponding to IPython message types.
data MessageType = KernelInfoReplyMessage

View File

@ -20,6 +20,7 @@ import System.Environment (getArgs)
import System.Environment (setEnv)
import System.Posix.Signals
import qualified Data.Map as Map
import qualified Data.HashMap.Strict as HashMap
import Data.List (break, last)
import Data.Version (showVersion)
@ -328,7 +329,7 @@ replyTo _ req@CompleteRequest{} replyHeader state = do
let start = pos - length matchedText
end = pos
reply = CompleteReply replyHeader (map T.pack completions) start end Map.empty True
reply = CompleteReply replyHeader (map T.pack completions) start end (Metadata HashMap.empty) True
return (state, reply)
replyTo _ req@InspectRequest{} replyHeader state = do

View File

@ -49,25 +49,26 @@ let
zeromq4-haskell = nixpkgs.haskell.lib.dontCheck super.zeromq4-haskell;
} // displays self);
ihaskellEnv = haskellPackages.ghcWithPackages (self: [ self.ihaskell ] ++ packages self);
notebook = nixpkgs.python3.withPackages (ps: [ ps.notebook ] ++ pythonPackages ps);
jupyterlab = nixpkgs.python3.withPackages (ps: [ ps.jupyterlab ] ++ pythonPackages ps);
ihaskellSh = cmd: extraArgs: nixpkgs.writeScriptBin "ihaskell-${cmd}" ''
#! ${nixpkgs.stdenv.shell}
export GHC_PACKAGE_PATH="$(echo ${ihaskellEnv}/lib/*/package.conf.d| tr ' ' ':'):$GHC_PACKAGE_PATH"
export PATH="${nixpkgs.stdenv.lib.makeBinPath ([ ihaskellEnv notebook ] ++ systemPackages nixpkgs)}:$PATH"
${ihaskellEnv}/bin/ihaskell install -l $(${ihaskellEnv}/bin/ghc --print-libdir) --use-rtsopts="${rtsopts}" && ${notebook}/bin/jupyter ${cmd} ${extraArgs} "$@"
export PATH="${nixpkgs.stdenv.lib.makeBinPath ([ ihaskellEnv jupyterlab ] ++ systemPackages nixpkgs)}:$PATH"
${ihaskellEnv}/bin/ihaskell install -l $(${ihaskellEnv}/bin/ghc --print-libdir) --use-rtsopts="${rtsopts}" && ${jupyterlab}/bin/jupyter ${cmd} ${extraArgs} "$@"
'';
in
nixpkgs.buildEnv {
name = "ihaskell-with-packages";
buildInputs = [ nixpkgs.makeWrapper ];
paths = [ ihaskellEnv notebook ];
paths = [ ihaskellEnv jupyterlab ];
postBuild = ''
ln -s ${ihaskellSh "lab" ""}/bin/ihaskell-lab $out/bin/
ln -s ${ihaskellSh "notebook" ""}/bin/ihaskell-notebook $out/bin/
ln -s ${ihaskellSh "nbconvert" ""}/bin/ihaskell-nbconvert $out/bin/
ln -s ${ihaskellSh "console" "--kernel=haskell"}/bin/ihaskell-console $out/bin/
for prg in $out/bin"/"*;do
if [[ -f $prg && -x $prg ]]; then
wrapProgram $prg --set PYTHONPATH "$(echo ${notebook}/lib/*/site-packages)"
wrapProgram $prg --set PYTHONPATH "$(echo ${jupyterlab}/lib/*/site-packages)"
fi
done
'';