Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gargantext-ihaskell
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
gargantext-ihaskell
Commits
f43b9129
Commit
f43b9129
authored
Sep 01, 2018
by
Erik de Castro Lopo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch warnings to -Wall and fix the rest
parent
4c0b3d24
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
314 additions
and
319 deletions
+314
-319
ihaskell.cabal
ihaskell.cabal
+3
-5
Main.hs
main/Main.hs
+24
-24
IpynbToLhs.hs
src/IHaskell/Convert/IpynbToLhs.hs
+4
-4
LhsToIpynb.hs
src/IHaskell/Convert/LhsToIpynb.hs
+5
-5
Display.hs
src/IHaskell/Display.hs
+1
-23
Completion.hs
src/IHaskell/Eval/Completion.hs
+13
-17
Evaluate.hs
src/IHaskell/Eval/Evaluate.hs
+71
-69
Hoogle.hs
src/IHaskell/Eval/Hoogle.hs
+14
-15
Lint.hs
src/IHaskell/Eval/Lint.hs
+28
-31
ParseShell.hs
src/IHaskell/Eval/ParseShell.hs
+1
-1
Parser.hs
src/IHaskell/Eval/Parser.hs
+28
-28
Util.hs
src/IHaskell/Eval/Util.hs
+11
-11
Widgets.hs
src/IHaskell/Eval/Widgets.hs
+16
-16
Flags.hs
src/IHaskell/Flags.hs
+14
-17
IPython.hs
src/IHaskell/IPython.hs
+10
-10
Stdin.hs
src/IHaskell/IPython/Stdin.hs
+11
-11
Publish.hs
src/IHaskell/Publish.hs
+10
-10
Types.hs
src/IHaskell/Types.hs
+29
-7
Completion.hs
src/tests/IHaskell/Test/Completion.hs
+8
-2
Eval.hs
src/tests/IHaskell/Test/Eval.hs
+13
-13
No files found.
ihaskell.cabal
View file @
f43b9129
...
...
@@ -49,7 +49,7 @@ data-files:
library
hs-source-dirs: src
default-language: Haskell2010
ghc-options: -W
incomplete-patterns -Wmissing-signatures -Wunused-do-bind -Wunused-local-binds -Wunused-top-binds -Wunused-matches -Wunused-imports
ghc-options: -W
all
build-depends:
aeson >=1.0,
base >=4.9,
...
...
@@ -121,11 +121,10 @@ executable ihaskell
other-modules:
IHaskellPrelude
Paths_ihaskell
ghc-options: -threaded -rtsopts
ghc-options: -threaded -rtsopts
-Wall
-- Other library packages from which modules are imported.
default-language: Haskell2010
ghc-options: -Wincomplete-patterns -Wmissing-signatures -Wunused-do-bind -Wunused-local-binds -Wunused-top-binds -Wunused-matches -Wunused-imports
build-depends:
ihaskell -any,
base >=4.9 && < 4.13,
...
...
@@ -143,7 +142,7 @@ executable ihaskell
Test-Suite hspec
Type: exitcode-stdio-1.0
Ghc-Options: -threaded
Ghc-Options: -threaded
-Wall
Main-Is: Hspec.hs
hs-source-dirs: src/tests
other-modules:
...
...
@@ -152,7 +151,6 @@ Test-Suite hspec
IHaskell.Test.Util
IHaskell.Test.Parser
default-language: Haskell2010
ghc-options: -Wincomplete-patterns -Wmissing-signatures -Wunused-do-bind -Wunused-local-binds -Wunused-top-binds -Wunused-matches -Wunused-imports
build-depends:
base,
ihaskell,
...
...
main/Main.hs
View file @
f43b9129
...
...
@@ -47,7 +47,7 @@ main = do
args
<-
parseFlags
<$>
getArgs
case
args
of
Left
errorMessage
->
hPutStrLn
stderr
errorMessage
Right
args
->
ihaskell
arg
s
Right
xs
->
ihaskell
x
s
ihaskell
::
Args
->
IO
()
ihaskell
(
Args
(
ShowDefault
helpStr
)
args
)
=
showDefault
helpStr
args
...
...
@@ -101,10 +101,10 @@ parseKernelArgs = foldl' addFlag defaultKernelSpecOptions
runKernel
::
KernelSpecOptions
-- ^ Various options from when the kernel was installed.
->
String
-- ^ File with kernel profile JSON (ports, etc).
->
IO
()
runKernel
k
ernel
Opts
profileSrc
=
do
let
debug
=
kernelSpecDebug
k
ernel
Opts
libdir
=
kernelSpecGhcLibdir
k
ernel
Opts
useStack
=
kernelSpecUseStack
k
ernel
Opts
runKernel
kOpts
profileSrc
=
do
let
debug
=
kernelSpecDebug
kOpts
libdir
=
kernelSpecGhcLibdir
kOpts
useStack
=
kernelSpecUseStack
kOpts
-- Parse the profile file.
let
profileErr
=
error
$
"ihaskell: "
++
profileSrc
++
": Failed to parse profile file"
...
...
@@ -155,10 +155,10 @@ runKernel kernelOpts profileSrc = do
evaluator
line
=
void
$
do
-- Create a new state each time.
stateVar
<-
liftIO
initialKernelState
st
ate
<-
liftIO
$
takeMVar
stateVar
evaluate
st
ate
line
noPublish
noWidget
st
<-
liftIO
$
takeMVar
stateVar
evaluate
st
line
noPublish
noWidget
confFile
<-
liftIO
$
kernelSpecConfFile
k
ernel
Opts
confFile
<-
liftIO
$
kernelSpecConfFile
kOpts
case
confFile
of
Just
filename
->
liftIO
(
readFile
filename
)
>>=
evaluator
Nothing
->
return
()
...
...
@@ -259,8 +259,8 @@ replyTo _ CommInfoRequest{} replyHeader state =
-- Reply to a shutdown request by exiting the main thread. Before shutdown, reply to the request to
-- let the frontend know shutdown is happening.
replyTo
interface
ShutdownRequest
{
restartPending
=
restartP
ending
}
replyHeader
_
=
liftIO
$
do
writeChan
(
shellReplyChannel
interface
)
$
ShutdownReply
replyHeader
restartP
ending
replyTo
interface
ShutdownRequest
{
restartPending
=
p
ending
}
replyHeader
_
=
liftIO
$
do
writeChan
(
shellReplyChannel
interface
)
$
ShutdownReply
replyHeader
p
ending
exitSuccess
-- Reply to an execution request. The reply itself does not require computation, but this causes
...
...
@@ -285,7 +285,7 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
-- re-display with the updated output.
displayed
<-
liftIO
$
newMVar
[]
updateNeeded
<-
liftIO
$
newMVar
False
p
agerOutp
ut
<-
liftIO
$
newMVar
[]
p
O
ut
<-
liftIO
$
newMVar
[]
let
execCount
=
getExecutionCounter
state
-- Let all frontends know the execution count and code that's about to run
...
...
@@ -294,7 +294,7 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
-- Run code and publish to the frontend as we go.
let
widgetMessageHandler
=
widgetHandler
send
replyHeader
publish
=
publishResult
send
replyHeader
displayed
updateNeeded
p
agerOutp
ut
(
usePager
state
)
publish
=
publishResult
send
replyHeader
displayed
updateNeeded
p
O
ut
(
usePager
state
)
updatedState
<-
evaluate
state
(
T
.
unpack
code
)
publish
widgetMessageHandler
-- Notify the frontend that we're done computing.
...
...
@@ -303,7 +303,7 @@ replyTo interface req@ExecuteRequest { getCode = code } replyHeader state = do
-- Take pager output if we're using the pager.
pager
<-
if
usePager
state
then
liftIO
$
readMVar
p
agerOutp
ut
then
liftIO
$
readMVar
p
O
ut
else
return
[]
return
(
updatedState
,
ExecuteReply
...
...
@@ -371,14 +371,14 @@ replyTo _ HistoryRequest{} replyHeader state = do
--
-- Sending the message only on the shell_reply channel doesn't work, so we send it as a comm message
-- on the iopub channel and return the SendNothing message.
replyTo
interface
o
pen
@
CommOpen
{}
replyHeader
state
=
do
let
send
msg
=
liftIO
$
writeChan
(
iopubChannel
interface
)
msg
replyTo
interface
o
comm
@
CommOpen
{}
replyHeader
state
=
do
let
send
=
liftIO
.
writeChan
(
iopubChannel
interface
)
incomingUuid
=
commUuid
o
pen
target
=
commTargetName
o
pen
incomingUuid
=
commUuid
o
comm
target
=
commTargetName
o
comm
targetMatches
=
target
==
"ipython.widget"
valueMatches
=
commData
o
pen
==
object
[
"widget_class"
.=
"ipywidgets.CommInfo"
]
valueMatches
=
commData
o
comm
==
object
[
"widget_class"
.=
(
"ipywidgets.CommInfo"
::
Text
)
]
commMap
=
openComms
state
uuidTargetPairs
=
map
(
second
targetName
)
$
Map
.
toList
commMap
...
...
@@ -387,11 +387,11 @@ replyTo interface open@CommOpen{} replyHeader state = do
currentComms
=
object
$
map
pairProcessor
$
(
incomingUuid
,
"comm"
)
:
uuidTargetPairs
replyValue
=
object
[
"method"
.=
"custom"
replyValue
=
object
[
"method"
.=
(
"custom"
::
Text
)
,
"content"
.=
object
[
"comms"
.=
currentComms
]
]
msg
=
CommData
replyHeader
(
commUuid
o
pen
)
replyValue
msg
=
CommData
replyHeader
(
commUuid
o
comm
)
replyValue
-- To the iopub channel you go
when
(
targetMatches
&&
valueMatches
)
$
send
msg
...
...
@@ -409,7 +409,7 @@ handleComm send kernelState req replyHeader = do
-- MVars to hold intermediate data during publishing
displayed
<-
liftIO
$
newMVar
[]
updateNeeded
<-
liftIO
$
newMVar
False
p
agerOutp
ut
<-
liftIO
$
newMVar
[]
p
O
ut
<-
liftIO
$
newMVar
[]
let
widgets
=
openComms
kernelState
uuid
=
commUuid
req
...
...
@@ -423,7 +423,7 @@ handleComm send kernelState req replyHeader = do
-- a function that executes an IO action and publishes the output to
-- the frontend simultaneously.
let
run
=
capturedIO
publish
kernelState
publish
=
publishResult
send
replyHeader
displayed
updateNeeded
p
agerOutp
ut
toUsePager
publish
=
publishResult
send
replyHeader
displayed
updateNeeded
p
O
ut
toUsePager
-- Notify the frontend that the kernel is busy
busyHeader
<-
liftIO
$
dupHeader
replyHeader
StatusMessage
...
...
@@ -435,12 +435,12 @@ handleComm send kernelState req replyHeader = do
case
msgType
$
header
req
of
CommDataMessage
->
do
disp
<-
run
$
comm
widget
dat
communicate
pgrOut
<-
liftIO
$
readMVar
p
agerOutp
ut
pgrOut
<-
liftIO
$
readMVar
p
O
ut
liftIO
$
publish
$
FinalResult
disp
(
if
toUsePager
then
pgrOut
else
[]
)
[]
return
kernelState
CommCloseMessage
->
do
disp
<-
run
$
close
widget
dat
pgrOut
<-
liftIO
$
readMVar
p
agerOutp
ut
pgrOut
<-
liftIO
$
readMVar
p
O
ut
liftIO
$
publish
$
FinalResult
disp
(
if
toUsePager
then
pgrOut
else
[]
)
[]
return
kernelState
{
openComms
=
Map
.
delete
uuid
widgets
}
_
->
...
...
src/IHaskell/Convert/IpynbToLhs.hs
View file @
f43b9129
...
...
@@ -46,12 +46,12 @@ convCell _sty object
=
s
convCell
sty
object
|
Just
(
String
"code"
)
<-
lookup
"cell_type"
object
,
Just
(
Array
i
)
<-
lookup
"source"
object
,
Just
(
Array
a
)
<-
lookup
"source"
object
,
Just
(
Array
o
)
<-
lookup
"outputs"
object
,
~
(
Just
i
)
<-
concatWithPrefix
(
lhsCodePrefix
sty
)
i
,
o
<-
fromMaybe
mempty
(
convOutputs
sty
o
)
~
(
Just
i
)
<-
concatWithPrefix
(
lhsCodePrefix
sty
)
a
,
o
2
<-
fromMaybe
mempty
(
convOutputs
sty
o
)
=
"
\n
"
<>
lhsBeginCode
sty
<>
i
<>
lhsEndCode
sty
<>
"
\n
"
<>
o
<>
"
\n
"
lhsBeginCode
sty
<>
i
<>
lhsEndCode
sty
<>
"
\n
"
<>
o
2
<>
"
\n
"
convCell
_
_
=
"IHaskell.Convert.convCell: unknown cell"
convOutputs
::
LhsStyle
LT
.
Text
...
...
src/IHaskell/Convert/LhsToIpynb.hs
View file @
f43b9129
...
...
@@ -95,12 +95,12 @@ boilerplate =
groupClassified
::
[
CellLine
LText
]
->
[
Cell
[
LText
]]
groupClassified
(
CodeLine
a
:
x
)
|
(
c
,
x
)
<-
List
.
span
isCode
x
,
(
_
,
x
)
<-
List
.
span
isEmptyMD
x
,
(
o
,
x
)
<-
List
.
span
isOutput
x
=
Code
(
a
:
map
untag
c
)
(
map
untag
o
)
:
groupClassified
x
|
(
c
,
x
1
)
<-
List
.
span
isCode
x
,
(
_
,
x
2
)
<-
List
.
span
isEmptyMD
x1
,
(
o
,
x
3
)
<-
List
.
span
isOutput
x2
=
Code
(
a
:
map
untag
c
)
(
map
untag
o
)
:
groupClassified
x
3
groupClassified
(
MarkdownLine
a
:
x
)
|
(
m
,
x
)
<-
List
.
span
isMD
x
=
Markdown
(
a
:
map
untag
m
)
:
groupClassified
x
|
(
m
,
x
1
)
<-
List
.
span
isMD
x
=
Markdown
(
a
:
map
untag
m
)
:
groupClassified
x1
groupClassified
(
OutputLine
a
:
x
)
=
Markdown
[
a
]
:
groupClassified
x
groupClassified
[]
=
[]
...
...
src/IHaskell/Display.hs
View file @
f43b9129
...
...
@@ -42,7 +42,7 @@ module IHaskell.Display (
-- ** Image and data encoding functions
Width
,
Height
,
Base64
(
..
)
,
Base64
,
encode64
,
base64
,
...
...
@@ -76,28 +76,6 @@ import StringUtils (rstrip)
type
Base64
=
Text
-- | these instances cause the image, html etc. which look like:
--
-- > Display
-- > [Display]
-- > IO [Display]
-- > IO (IO Display)
--
-- be run the IO and get rendered (if the frontend allows it) in the pretty form.
instance
IHaskellDisplay
a
=>
IHaskellDisplay
(
IO
a
)
where
display
=
(
display
=<<
)
instance
IHaskellDisplay
Display
where
display
=
return
instance
IHaskellDisplay
DisplayData
where
display
disp
=
return
$
Display
[
disp
]
instance
IHaskellDisplay
a
=>
IHaskellDisplay
[
a
]
where
display
disps
=
do
displays
<-
mapM
display
disps
return
$
ManyDisplay
displays
-- | Encode many displays into a single one. All will be output.
many
::
[
Display
]
->
Display
many
=
ManyDisplay
...
...
src/IHaskell/Eval/Completion.hs
View file @
f43b9129
...
...
@@ -21,12 +21,8 @@ import qualified Data.List.Split as Split
import
qualified
Data.List.Split.Internals
as
Split
import
System.Environment
(
getEnv
)
import
GHC
hiding
(
Qualified
)
#
if
MIN_VERSION_ghc
(
8
,
2
,
0
)
import
GHC
import
GHC.PackageDb
#
else
import
GHC.PackageDb
(
ExposedModule
(
exposedName
))
#
endif
import
DynFlags
import
GhcMonad
import
Outputable
(
showPpr
)
...
...
@@ -57,7 +53,7 @@ exposedName :: (a, b) -> a
exposedName
=
fst
#
endif
extName
(
FlagSpec
{
flagSpecName
=
name
})
=
name
extName
::
FlagSpec
flag
->
String
extName
(
FlagSpec
{
flagSpecName
=
name
})
=
name
complete
::
String
->
Int
->
Interpreter
(
String
,
[
String
])
...
...
@@ -97,8 +93,8 @@ complete code posOffset = do
Identifier
candidate
->
return
$
filter
(
candidate
`
isPrefixOf
`)
unqualNames
Qualified
m
odule
Name
candidate
->
do
let
prefix
=
intercalate
"."
[
m
odule
Name
,
candidate
]
Qualified
mName
candidate
->
do
let
prefix
=
intercalate
"."
[
mName
,
candidate
]
completions
=
filter
(
prefix
`
isPrefixOf
`)
qualNames
return
completions
...
...
@@ -200,7 +196,7 @@ completionType line loc target
else
[]
Left
_
->
Empty
cursorInString
str
l
oc
=
nquotes
(
take
loc
str
)
`
mod
`
2
/=
0
cursorInString
str
l
cn
=
nquotes
(
take
lcn
str
)
`
mod
`
2
/=
(
0
::
Int
)
nquotes
(
'
\\
'
:
'"'
:
xs
)
=
nquotes
xs
nquotes
(
'"'
:
xs
)
=
1
+
nquotes
xs
...
...
@@ -214,12 +210,12 @@ completionType line loc target
where
go
acc
rest
=
case
rest
of
'"'
:
'
\\
'
:
rem
->
go
(
'"'
:
acc
)
rem
'"'
:
_
->
acc
' '
:
'
\\
'
:
rem
->
go
(
' '
:
acc
)
rem
' '
:
_
->
acc
x
:
rem
->
go
(
x
:
acc
)
rem
[]
->
acc
'"'
:
'
\\
'
:
xs
->
go
(
'"'
:
acc
)
xs
'"'
:
_
->
acc
' '
:
'
\\
'
:
xs
->
go
(
' '
:
acc
)
xs
' '
:
_
->
acc
x
:
xs
->
go
(
x
:
acc
)
xs
[]
->
acc
-- | Get the word under a given cursor location.
completionTarget
::
String
->
Int
->
[
String
]
...
...
@@ -277,8 +273,8 @@ completePath line = completePathFilter acceptAll acceptAll line ""
acceptAll
=
const
True
completePathWithExtensions
::
[
String
]
->
String
->
Interpreter
[
String
]
completePathWithExtensions
ext
ensio
ns
line
=
completePathFilter
(
extensionIsOneOf
ext
ensio
ns
)
acceptAll
line
""
completePathWithExtensions
extns
line
=
completePathFilter
(
extensionIsOneOf
extns
)
acceptAll
line
""
where
acceptAll
=
const
True
extensionIsOneOf
exts
str
=
any
correctEnding
exts
...
...
src/IHaskell/Eval/Evaluate.hs
View file @
f43b9129
This diff is collapsed.
Click to expand it.
src/IHaskell/Eval/Hoogle.hs
View file @
f43b9129
...
...
@@ -92,8 +92,8 @@ search string = do
return
$
case
response
of
Left
err
->
[
NoResult
err
]
Right
js
o
n
->
case
eitherDecode
$
LBS
.
fromStrict
$
CBS
.
pack
js
o
n
of
Right
jsn
->
case
eitherDecode
$
LBS
.
fromStrict
$
CBS
.
pack
jsn
of
Left
err
->
[
NoResult
err
]
Right
results
->
case
map
SearchResult
$
(
\
(
HoogleResponseList
l
)
->
l
)
results
of
...
...
@@ -159,7 +159,7 @@ renderSelf string loc
|
"module"
`
isPrefixOf
`
string
=
let
package
=
extractPackageName
loc
in
m
od
++
" "
++
in
m
dl
++
" "
++
span
"hoogle-module"
(
link
loc
$
extractModule
string
)
++
packageSub
package
...
...
@@ -198,7 +198,7 @@ renderSelf string loc
extractData
=
strip
.
replace
"data"
""
extractNewtype
=
strip
.
replace
"newtype"
""
pkg
=
span
"hoogle-head"
"package"
m
od
=
span
"hoogle-head"
"module"
m
dl
=
span
"hoogle-head"
"module"
cls
=
span
"hoogle-head"
"class"
dat
=
span
"hoogle-head"
"data"
nwt
=
span
"hoogle-head"
"newtype"
...
...
@@ -220,7 +220,7 @@ renderSelf string loc
packageAndModuleSub
(
Just
package
)
(
Just
modname
)
=
span
"hoogle-sub"
$
"("
++
pkg
++
" "
++
span
"hoogle-package"
package
++
", "
++
m
od
++
" "
++
span
"hoogle-module"
modname
++
")"
", "
++
m
dl
++
" "
++
span
"hoogle-module"
modname
++
")"
renderDocs
::
String
->
String
renderDocs
doc
=
...
...
@@ -233,27 +233,26 @@ renderDocs doc =
case
xs
of
[]
->
False
(
s
:
_
)
->
isPrefixOf
">"
$
strip
s
makeBlock
line
s
=
if
isCode
line
s
then
div'
"hoogle-code"
$
unlines
$
nonull
line
s
else
div'
"hoogle-text"
$
unlines
$
nonull
line
s
makeBlock
x
s
=
if
isCode
x
s
then
div'
"hoogle-code"
$
unlines
$
nonull
x
s
else
div'
"hoogle-text"
$
unlines
$
nonull
x
s
in
div'
"hoogle-doc"
$
unlines
$
map
makeBlock
groups
extractPackageName
::
String
->
Maybe
String
extractPackageName
l
i
nk
=
do
let
pieces
=
split
"/"
l
i
nk
extractPackageName
lnk
=
do
let
pieces
=
split
"/"
lnk
archiveLoc
<-
List
.
elemIndex
"archive"
pieces
latestLoc
<-
List
.
elemIndex
"latest"
pieces
guard
$
latestLoc
-
archiveLoc
==
2
return
$
pieces
List
.!!
(
latestLoc
-
1
)
extractModuleName
::
String
->
Maybe
String
extractModuleName
l
i
nk
=
do
let
pieces
=
split
"/"
l
i
nk
extractModuleName
lnk
=
do
let
pieces
=
split
"/"
lnk
guard
$
not
$
null
pieces
let
html
=
fromJust
$
lastMay
pieces
mod
=
replace
"-"
"."
$
takeWhile
(
/=
'.'
)
html
return
mod
return
$
replace
"-"
"."
$
takeWhile
(
/=
'.'
)
html
div'
::
String
->
String
->
String
div'
=
printf
"<div class='%s'>%s</div>"
...
...
src/IHaskell/Eval/Lint.hs
View file @
f43b9129
...
...
@@ -53,10 +53,9 @@ lint blocks = do
-- Get hlint settings
(
flags
,
classify
,
hint
)
<-
readMVar
hlintSettings
let
mode
=
hseFlags
flags
-- create 'suggestions'
let
modules
=
mapMaybe
(
createModule
mode
)
blocks
let
modules
=
mapMaybe
(
createModule
(
hseFlags
flags
)
)
blocks
ideas
=
applyHints
classify
hint
(
map
(
\
m
->
(
m
,
[]
))
modules
)
suggestions
=
mapMaybe
showIdea
$
filter
(
not
.
ignoredIdea
)
ideas
...
...
@@ -66,33 +65,33 @@ lint blocks = do
else
[
plain
$
concatMap
plainSuggestion
suggestions
,
html
$
htmlSuggestions
suggestions
]
where
autoSettings'
=
do
(
fix
itie
s
,
classify
,
hints
)
<-
autoSettings
(
fix
t
s
,
classify
,
hints
)
<-
autoSettings
let
hidingIgnore
=
Classify
Ignore
"Unnecessary hiding"
""
""
return
(
fix
itie
s
,
hidingIgnore
:
classify
,
hints
)
return
(
fix
t
s
,
hidingIgnore
:
classify
,
hints
)
ignoredIdea
idea
=
ideaSeverity
idea
==
Ignore
showIdea
::
Idea
->
Maybe
LintSuggestion
showIdea
idea
=
case
ideaTo
idea
of
Nothing
->
Nothing
Just
w
hyNot
->
Just
w
n
->
Just
Suggest
{
line
=
srcSpanStartLine
$
ideaSpan
idea
,
found
=
showSuggestion
$
ideaFrom
idea
,
whyNot
=
showSuggestion
w
hyNot
,
whyNot
=
showSuggestion
w
n
,
severity
=
ideaSeverity
idea
,
suggestion
=
ideaHint
idea
}
createModule
::
ParseMode
->
Located
CodeBlock
->
Maybe
ExtsModule
createModule
m
ode
(
Located
line
block
)
=
createModule
m
d
(
Located
ln
block
)
=
case
block
of
Expression
expr
->
unparse
$
exprToModule
expr
Declaration
decl
->
unparse
$
declToModule
decl
Statement
stmt
->
unparse
$
stmtToModule
stmt
Import
impt
->
unparse
$
imptToModule
impt
Module
m
od
->
unparse
$
parseModule
mod
Module
m
dl
->
unparse
$
pModule
mdl
_
->
Nothing
where
blockStr
=
...
...
@@ -101,7 +100,7 @@ createModule mode (Located line block) =
Declaration
decl
->
decl
Statement
stmt
->
stmt
Import
impt
->
impt
Module
m
od
->
mod
Module
m
dl
->
mdl
-- TODO: Properly handle the other constructors
_
->
[]
...
...
@@ -113,49 +112,47 @@ createModule mode (Located line block) =
srcSpan
::
SrcSpan
srcSpan
=
SrcSpan
{
srcSpanFilename
=
"<interactive>"
,
srcSpanStartLine
=
l
ine
,
srcSpanStartLine
=
l
n
,
srcSpanStartColumn
=
0
,
srcSpanEndLine
=
l
ine
+
length
(
lines
blockStr
)
,
srcSpanEndLine
=
l
n
+
length
(
lines
blockStr
)
,
srcSpanEndColumn
=
length
$
last
$
lines
blockStr
}
l
oc
::
SrcSpanInfo
l
oc
=
SrcSpanInfo
srcSpan
[]
l
cn
::
SrcSpanInfo
l
cn
=
SrcSpanInfo
srcSpan
[]
moduleWithDecls
::
Decl
SrcSpanInfo
->
ExtsModule
moduleWithDecls
decl
=
SrcExts
.
Module
l
oc
Nothing
[]
[]
[
decl
]
moduleWithDecls
decl
=
SrcExts
.
Module
l
cn
Nothing
[]
[]
[
decl
]
p
arse
Module
::
String
->
ParseResult
ExtsModule
p
arseModule
=
parseFileContentsWithMode
mode
pModule
::
String
->
ParseResult
ExtsModule
p
Module
=
parseFileContentsWithMode
md
declToModule
::
String
->
ParseResult
ExtsModule
declToModule
decl
=
moduleWithDecls
<$>
parseDeclWithMode
m
ode
decl
declToModule
decl
=
moduleWithDecls
<$>
parseDeclWithMode
m
d
decl
exprToModule
::
String
->
ParseResult
ExtsModule
exprToModule
exp
=
moduleWithDecls
<$>
SpliceDecl
l
oc
<$>
parseExpWithMode
mode
exp
exprToModule
exp
=
moduleWithDecls
<$>
SpliceDecl
l
cn
<$>
parseExpWithMode
md
exp
stmtToModule
::
String
->
ParseResult
ExtsModule
stmtToModule
stmtStr
=
case
parseStmtWithMode
m
ode
stmtStr
of
ParseOk
_
->
ParseOk
mod
case
parseStmtWithMode
m
d
stmtStr
of
ParseOk
_
->
ParseOk
$
moduleWithDecls
decl
ParseFailed
a
b
->
ParseFailed
a
b
where
mod
=
moduleWithDecls
decl
decl
::
Decl
SrcSpanInfo
decl
=
SpliceDecl
l
oc
expr
decl
=
SpliceDecl
l
cn
expr
expr
::
Exp
SrcSpanInfo
expr
=
Do
l
oc
[
stmt
,
ret
]
expr
=
Do
l
cn
[
stmt
,
ret
]
stmt
::
Stmt
SrcSpanInfo
ParseOk
stmt
=
parseStmtWithMode
m
ode
stmtStr
ParseOk
stmt
=
parseStmtWithMode
m
d
stmtStr
ret
::
Stmt
SrcSpanInfo
ParseOk
ret
=
Qualifier
l
oc
<$>
parseExp
lintIdent
ParseOk
ret
=
Qualifier
l
cn
<$>
parseExp
lintIdent
imptToModule
::
String
->
ParseResult
ExtsModule
imptToModule
=
parseFileContentsWithMode
m
ode
imptToModule
=
parseFileContentsWithMode
m
d
plainSuggestion
::
LintSuggestion
->
String
plainSuggestion
suggest
=
...
...
@@ -168,10 +165,10 @@ htmlSuggestions = concatMap toHtml
toHtml
::
LintSuggestion
->
String
toHtml
suggest
=
concat
[
named
$
suggestion
suggest
,
floating
"left"
$
styl
e
severityClass
"Found:"
++
,
floating
"left"
$
styl
severityClass
"Found:"
++
-- Things that look like this get highlighted.
styleId
"highlight-code"
"haskell"
(
found
suggest
)
,
floating
"left"
$
styl
e
severityClass
"Why Not:"
++
,
floating
"left"
$
styl
severityClass
"Why Not:"
++
-- Things that look like this get highlighted.
styleId
"highlight-code"
"haskell"
(
whyNot
suggest
)
]
...
...
@@ -184,8 +181,8 @@ htmlSuggestions = concatMap toHtml
-- Should not occur
_
->
"warning"
styl
e
::
String
->
String
->
String
styl
e
=
printf
"<div class=
\"
suggestion-%s
\"
>%s</div>"
styl
::
String
->
String
->
String
styl
=
printf
"<div class=
\"
suggestion-%s
\"
>%s</div>"
named
::
String
->
String
named
=
printf
"<div class=
\"
suggestion-name
\"
style=
\"
clear:both;
\"
>%s</div>"
...
...
src/IHaskell/Eval/ParseShell.hs
View file @
f43b9129
...
...
@@ -63,4 +63,4 @@ shellWords = try (eof *> return []) <|> do
return
$
x
:
xs
parseShell
::
String
->
Either
ParseError
[
String
]
parseShell
str
ing
=
parse
shellWords
"shell"
(
string
++
"
\n
"
)
parseShell
str
=
parse
shellWords
"shell"
(
str
++
"
\n
"
)
src/IHaskell/Eval/Parser.hs
View file @
f43b9129
...
...
@@ -78,8 +78,8 @@ parseString codeString = do
flags
<-
getSessionDynFlags
let
output
=
runParser
flags
parserModule
codeString
case
output
of
Parsed
m
od
|
Just
_
<-
hsmodName
(
unLoc
m
od
)
->
return
[
Located
1
$
Module
codeString
]
Parsed
m
dl
|
Just
_
<-
hsmodName
(
unLoc
m
dl
)
->
return
[
Located
1
$
Module
codeString
]
_
->
do
-- Split input into chunks based on indentation.
let
chunks
=
layoutChunks
$
removeComments
codeString
...
...
@@ -92,12 +92,12 @@ parseString codeString = do
where
parseChunk
::
GhcMonad
m
=>
String
->
LineNumber
->
m
(
Located
CodeBlock
)
parseChunk
chunk
l
ine
=
Located
line
<$>
handleChunk
chunk
line
parseChunk
chunk
l
n
=
Located
ln
<$>
handleChunk
where
handleChunk
chunk
line
|
isDirective
chunk
=
return
$
parseDirective
chunk
l
ine
|
isPragma
chunk
=
return
$
parsePragma
chunk
l
ine
|
otherwise
=
parseCodeChunk
chunk
l
ine
handleChunk
|
isDirective
chunk
=
return
$
parseDirective
chunk
l
n
|
isPragma
chunk
=
return
$
parsePragma
chunk
l
n
|
otherwise
=
parseCodeChunk
chunk
l
n
processChunks
::
GhcMonad
m
=>
[
Located
CodeBlock
]
->
[
Located
String
]
->
m
[
Located
CodeBlock
]
processChunks
accum
remaining
=
...
...
@@ -106,10 +106,10 @@ parseString codeString = do
[]
->
return
$
reverse
accum
-- If we have more remaining, parse the current chunk and recurse.
Located
l
ine
chunk
:
remaining
->
do
block
<-
parseChunk
chunk
l
ine
Located
l
n
chunk
:
remain
->
do
block
<-
parseChunk
chunk
l
n
activateExtensions
$
unloc
block
processChunks
(
block
:
accum
)
remain
ing
processChunks
(
block
:
accum
)
remain
-- Test whether a given chunk is a directive.
isDirective
::
String
->
Bool
...
...
@@ -125,11 +125,11 @@ activateExtensions (Directive SetDynFlag flags) =
case
stripPrefix
"-X"
flags
of
Just
ext
->
void
$
setExtension
ext
Nothing
->
return
()
activateExtensions
(
Pragma
PragmaLanguage
ext
ensions
)
=
void
$
setAll
extension
s
activateExtensions
(
Pragma
PragmaLanguage
ext
s
)
=
void
$
setAll
ext
s
where
setAll
::
GhcMonad
m
=>
[
String
]
->
m
(
Maybe
String
)
setAll
exts
=
do
errs
<-
mapM
setExtension
exts
setAll
exts
'
=
do
errs
<-
mapM
setExtension
exts
'
return
$
msum
errs
activateExtensions
_
=
return
()
...
...
@@ -159,13 +159,13 @@ parseCodeChunk code startLine = do
failures
::
[
ParseOutput
a
]
->
[(
ErrMsg
,
LineNumber
,
ColumnNumber
)]
failures
[]
=
[]
failures
(
Failure
msg
(
Loc
l
ine
col
)
:
rest
)
=
(
msg
,
line
,
col
)
:
failures
rest
failures
(
Failure
msg
(
Loc
l
n
col
)
:
rest
)
=
(
msg
,
ln
,
col
)
:
failures
rest
failures
(
_
:
rest
)
=
failures
rest
bestError
::
[(
ErrMsg
,
LineNumber
,
ColumnNumber
)]
->
CodeBlock
bestError
errors
=
ParseError
(
Loc
(
l
ine
+
startLine
-
1
)
col
)
msg
bestError
errors
=
ParseError
(
Loc
(
l
n
+
startLine
-
1
)
col
)
msg
where
(
msg
,
l
ine
,
col
)
=
maximumBy
compareLoc
errors
(
msg
,
l
n
,
col
)
=
maximumBy
compareLoc
errors
compareLoc
(
_
,
line1
,
col1
)
(
_
,
line2
,
col2
)
=
compare
line1
line2
<>
compare
col1
col2
statementToExpression
::
DynFlags
->
ParseOutput
CodeBlock
->
ParseOutput
CodeBlock
...
...
@@ -184,8 +184,8 @@ parseCodeChunk code startLine = do
_
->
False
tryParser
::
String
->
(
String
->
CodeBlock
,
String
->
ParseOutput
String
)
->
ParseOutput
CodeBlock
tryParser
string
(
blockType
,
p
arse
r
)
=
case
p
arse
r
string
of
tryParser
string
(
blockType
,
p
s
r
)
=
case
p
s
r
string
of
Parsed
res
->
Parsed
(
blockType
res
)
Failure
err
loc
->
Failure
err
loc
_
->
error
"tryParser failed, output was neither Parsed nor Failure"
...
...
@@ -199,10 +199,10 @@ parseCodeChunk code startLine = do
]
where
unparser
::
Parser
a
->
String
->
ParseOutput
String
unparser
p
arser
code
=
case
runParser
flags
p
arser
code
of
Parsed
_
->
Parsed
c
ode
Partial
_
strs
->
Partial
c
ode
strs
unparser
p
sr
cd
=
case
runParser
flags
p
sr
cd
of
Parsed
_
->
Parsed
c
d
Partial
_
strs
->
Partial
c
d
strs
Failure
err
loc
->
Failure
err
loc
-- | Find consecutive declarations of the same function and join them into a single declaration.
...
...
@@ -234,7 +234,7 @@ joinFunctions blocks =
parsePragma
::
String
-- ^ Pragma string.
->
Int
-- ^ Line number at which the directive appears.
->
CodeBlock
-- ^ Pragma code block or a parse error.
parsePragma
pragma
_l
ine
=
parsePragma
pragma
_l
n
=
let
commaToSpace
::
Char
->
Char
commaToSpace
','
=
' '
commaToSpace
x
=
x
...
...
@@ -251,8 +251,8 @@ parsePragma pragma _line =
parseDirective
::
String
-- ^ Directive string.
->
Int
-- ^ Line number at which the directive appears.
->
CodeBlock
-- ^ Directive code block or a parse error.
parseDirective
(
':'
:
'!'
:
directive
)
_l
ine
=
Directive
ShellCmd
$
'!'
:
directive
parseDirective
(
':'
:
directive
)
l
ine
=
parseDirective
(
':'
:
'!'
:
directive
)
_l
n
=
Directive
ShellCmd
$
'!'
:
directive
parseDirective
(
':'
:
directive
)
l
n
=
case
find
rightDirective
directives
of
Just
(
directiveType
,
_
)
->
Directive
directiveType
arg
where
arg
=
unwords
restLine
...
...
@@ -262,7 +262,7 @@ parseDirective (':':directive) line =
case
words
directive
of
[]
->
""
first
:
_
->
first
in
ParseError
(
Loc
l
ine
1
)
$
"Unknown directive: '"
++
directiveStart
++
"'."
in
ParseError
(
Loc
l
n
1
)
$
"Unknown directive: '"
++
directiveStart
++
"'."
where
rightDirective
(
_
,
dirname
)
=
case
words
directive
of
...
...
@@ -293,8 +293,8 @@ getModuleName moduleSrc = do
let
output
=
runParser
flags
parserModule
moduleSrc
case
output
of
Failure
{}
->
error
"Module parsing failed."
Parsed
m
od
->
case
unLoc
<$>
hsmodName
(
unLoc
m
od
)
of
Parsed
m
dl
->
case
unLoc
<$>
hsmodName
(
unLoc
m
dl
)
of
Nothing
->
error
"Module must have a name."
Just
name
->
return
$
split
"."
$
moduleNameString
name
_
->
error
"getModuleName failed, output was neither Parsed nor Failure"
src/IHaskell/Eval/Util.hs
View file @
f43b9129
...
...
@@ -75,10 +75,10 @@ extensionFlag ext =
Nothing
->
Nothing
where
-- Check if a FlagSpec matches an extension name.
flagMatches
ex
t
fs
=
ext
==
flagSpecName
fs
flagMatches
ex
fs
=
ex
==
flagSpecName
fs
-- Check if a FlagSpec matches "No<ExtensionName>". In that case, we disable the extension.
flagMatchesNo
ex
t
fs
=
ext
==
"No"
++
flagSpecName
fs
flagMatchesNo
ex
fs
=
ex
==
"No"
++
flagSpecName
fs
-- | Pretty-print dynamic flags (taken from 'InteractiveUI' module of `ghc-bin`)
pprDynFlags
::
Bool
-- ^ Whether to include flags which are on by default
...
...
@@ -91,11 +91,11 @@ pprDynFlags show_all dflags =
,
O
.
text
"other dynamic, non-language, flag settings:"
O
.$$
O
.
nest
2
(
O
.
vcat
(
map
(
setting
opt
)
others
))
,
O
.
text
"warning settings:"
O
.$$
O
.
nest
2
(
O
.
vcat
(
map
(
setting
wopt
)
w
arning
Flags
))
O
.
nest
2
(
O
.
vcat
(
map
(
setting
wopt
)
wFlags
))
]
where
w
arning
Flags
=
DynFlags
.
wWarningFlags
wFlags
=
DynFlags
.
wWarningFlags
opt
=
gopt
...
...
@@ -336,14 +336,14 @@ evalImport imports = do
_
->
False
removeImport
::
GhcMonad
m
=>
String
->
m
()
removeImport
mod
ule
Name
=
do
removeImport
modName
=
do
ctx
<-
getContext
let
ctx'
=
filter
(
not
.
(
isImportOf
$
mkModuleName
mod
ule
Name
))
ctx
let
ctx'
=
filter
(
not
.
(
isImportOf
$
mkModuleName
modName
))
ctx
setContext
ctx'
where
isImportOf
::
ModuleName
->
InteractiveImport
->
Bool
isImportOf
name
(
IIModule
m
odName
)
=
name
==
mod
Name
isImportOf
name
(
IIModule
m
Name
)
=
name
==
m
Name
isImportOf
name
(
IIDecl
impDecl
)
=
name
==
unLoc
(
ideclName
impDecl
)
-- | Evaluate a series of declarations. Return all names which were bound by these declarations.
...
...
@@ -396,9 +396,9 @@ getDescription str = do
-- Filter out types that have parents in the same set. GHCi also does this.
let
infos
=
catMaybes
maybeInfos
allNames
=
mkNameSet
$
map
(
getName
.
getType
)
infos
allNames
=
mkNameSet
$
map
(
getName
.
get
Info
Type
)
infos
hasParent
info
=
case
tyThingParent_maybe
(
getType
info
)
of
case
tyThingParent_maybe
(
get
Info
Type
info
)
of
Just
parent
->
getName
parent
`
elemNameSet
`
allNames
Nothing
->
False
filteredOutput
=
filter
(
not
.
hasParent
)
infos
...
...
@@ -411,9 +411,9 @@ getDescription str = do
getInfo'
=
getInfo
False
#
if
MIN_VERSION_ghc
(
8
,
4
,
0
)
getType
(
theType
,
_
,
_
,
_
,
_
)
=
theType
get
Info
Type
(
theType
,
_
,
_
,
_
,
_
)
=
theType
#
else
getType
(
theType
,
_
,
_
,
_
)
=
theType
get
Info
Type
(
theType
,
_
,
_
,
_
)
=
theType
#
endif
#
if
MIN_VERSION_ghc
(
8
,
4
,
0
)
...
...
src/IHaskell/Eval/Widgets.hs
View file @
f43b9129
...
...
@@ -47,7 +47,7 @@ queue = atomically . writeTChan widgetMessages
widgetSend
::
IHaskellWidget
a
=>
(
Widget
->
Value
->
WidgetMsg
)
->
a
->
Value
->
IO
()
widgetSend
m
sgType
widget
value
=
queue
$
msgT
ype
(
Widget
widget
)
value
widgetSend
m
type
widget
value
=
queue
$
mt
ype
(
Widget
widget
)
value
-- | Send a message to open a comm
widgetSendOpen
::
IHaskellWidget
a
=>
a
->
Value
->
IO
()
...
...
@@ -79,7 +79,7 @@ widgetPublishDisplay widget disp = display disp >>= queue . DispMsg (Widget widg
-- | Send a `clear_output` message as a [method .= custom] message
widgetClearOutput
::
IHaskellWidget
a
=>
a
->
Bool
->
IO
()
widgetClearOutput
widget
w
ait
=
queue
$
ClrOutput
(
Widget
widget
)
wait
widgetClearOutput
widget
w
=
queue
$
ClrOutput
(
Widget
widget
)
w
-- | Handle a single widget message. Takes necessary actions according to the message type, such as
-- opening comms, storing and updating widget representation in the kernel state etc.
...
...
@@ -108,8 +108,8 @@ handleMessage send replyHeader state msg = do
then
return
state
else
do
-- Send the comm open, with the initial state
h
eade
r
<-
dupHeader
replyHeader
CommOpenMessage
send
$
CommOpen
h
eade
r
target_name
target_module
uuid
value
h
d
r
<-
dupHeader
replyHeader
CommOpenMessage
send
$
CommOpen
h
d
r
target_name
target_module
uuid
value
-- Send anything else the widget requires.
open
widget
communicate
...
...
@@ -127,8 +127,8 @@ handleMessage send replyHeader state msg = do
-- If the widget is not present in the state, we don't close it.
if
present
then
do
h
eade
r
<-
dupHeader
replyHeader
CommCloseMessage
send
$
CommClose
h
eade
r
uuid
value
h
d
r
<-
dupHeader
replyHeader
CommCloseMessage
send
$
CommClose
h
d
r
uuid
value
return
newState
else
return
state
...
...
@@ -145,9 +145,9 @@ handleMessage send replyHeader state msg = do
let
dmsg
=
WidgetDisplay
dispHeader
$
unwrap
disp
sendMessage
widget
(
toJSON
$
CustomContent
$
toJSON
dmsg
)
ClrOutput
widget
w
ait
->
do
h
eade
r
<-
dupHeader
replyHeader
ClearOutputMessage
let
cmsg
=
WidgetClear
h
eader
wait
ClrOutput
widget
w
->
do
h
d
r
<-
dupHeader
replyHeader
ClearOutputMessage
let
cmsg
=
WidgetClear
h
dr
w
sendMessage
widget
(
toJSON
$
CustomContent
$
toJSON
cmsg
)
where
...
...
@@ -158,8 +158,8 @@ handleMessage send replyHeader state msg = do
-- If the widget is present, we send an update message on its comm.
when
present
$
do
h
eade
r
<-
dupHeader
replyHeader
CommDataMessage
send
$
CommData
h
eade
r
uuid
value
h
d
r
<-
dupHeader
replyHeader
CommDataMessage
send
$
CommData
h
d
r
uuid
value
return
state
unwrap
::
Display
->
[
DisplayData
]
...
...
@@ -178,20 +178,20 @@ instance ToJSON WidgetDisplay where
data
WidgetClear
=
WidgetClear
MessageHeader
Bool
instance
ToJSON
WidgetClear
where
toJSON
(
WidgetClear
replyHeader
w
ait
)
=
let
clrVal
=
toJSON
$
ClearOutput
replyHeader
w
ait
toJSON
(
WidgetClear
replyHeader
w
)
=
let
clrVal
=
toJSON
$
ClearOutput
replyHeader
w
in
toJSON
$
IPythonMessage
replyHeader
clrVal
ClearOutputMessage
data
IPythonMessage
=
IPythonMessage
MessageHeader
Value
MessageType
instance
ToJSON
IPythonMessage
where
toJSON
(
IPythonMessage
replyHeader
val
m
sgT
ype
)
=
toJSON
(
IPythonMessage
replyHeader
val
m
t
ype
)
=
object
[
"header"
.=
replyHeader
,
"parent_header"
.=
str
""
,
"metadata"
.=
str
"{}"
,
"content"
.=
val
,
"msg_type"
.=
(
toJSON
.
showMessageType
$
m
sgT
ype
)
,
"msg_type"
.=
(
toJSON
.
showMessageType
$
m
t
ype
)
]
str
::
String
->
String
...
...
@@ -203,4 +203,4 @@ widgetHandler :: (Message -> IO ())
->
KernelState
->
[
WidgetMsg
]
->
IO
KernelState
widgetHandler
sender
h
eader
=
foldM
(
handleMessage
sender
heade
r
)
widgetHandler
sender
h
dr
=
foldM
(
handleMessage
sender
hd
r
)
src/IHaskell/Flags.hs
View file @
f43b9129
...
...
@@ -65,7 +65,7 @@ data IHaskellMode = ShowDefault String
-- | Given a list of command-line arguments, return the IHaskell mode and arguments to process.
parseFlags
::
[
String
]
->
Either
String
Args
parseFlags
flags
=
let
modeIndex
=
findIndex
(`
elem
`
modeFl
a
gs
)
flags
let
modeIndex
=
findIndex
(`
elem
`
modeFlgs
)
flags
in
case
modeIndex
of
Nothing
->
-- Treat no mode as 'console'.
...
...
@@ -77,14 +77,14 @@ parseFlags flags =
let
(
start
,
first
:
end
)
=
splitAt
idx
flags
in
process
ihaskellArgs
$
first
:
start
++
end
where
modeFl
a
gs
=
concatMap
modeNames
allModes
modeFlgs
=
concatMap
modeNames
allModes
allModes
::
[
Mode
Args
]
allModes
=
[
installKernelSpec
,
kernel
,
convert
]
-- | Get help text for a given IHaskell ode.
help
::
IHaskellMode
->
String
help
m
ode
=
showText
(
Wrap
100
)
$
helpText
[]
HelpFormatAll
$
chooseMode
mode
help
m
d
=
showText
(
Wrap
100
)
$
helpText
[]
HelpFormatAll
$
chooseMode
md
where
chooseMode
InstallKernelSpec
=
installKernelSpec
chooseMode
(
Kernel
_
)
=
kernel
...
...
@@ -97,8 +97,8 @@ ghcLibFlag = flagReq ["ghclib", "l"] (store GhcLibDir) "<path>" "Library directo
ghcRTSFlag
::
Flag
Args
ghcRTSFlag
=
flagReq
[
"use-rtsopts"
]
storeRTS
"
\"
<flags>
\"
"
"Runtime options (multithreading etc.). See `ghc +RTS -?`."
where
storeRTS
allRTSFlags
(
Args
m
ode
prev
)
=
fmap
(
Args
m
ode
.
(
:
prev
)
.
RTSFlags
)
where
storeRTS
allRTSFlags
(
Args
m
d
prev
)
=
fmap
(
Args
m
d
.
(
:
prev
)
.
RTSFlags
)
.
parseRTS
.
words
$
filter
(
/=
'"'
)
allRTSFlags
parseRTS
(
"+RTS"
:
fs
)
-- Ignore if this is included (we already wrap
=
parseRTS
fs
-- the ihaskell-kernel call in +RTS <flags> -RTS anyway)
...
...
@@ -111,13 +111,13 @@ ghcRTSFlag = flagReq ["use-rtsopts"] storeRTS "\"<flags>\""
kernelDebugFlag
::
Flag
Args
kernelDebugFlag
=
flagNone
[
"debug"
]
addDebug
"Print debugging output from the kernel."
where
addDebug
(
Args
m
ode
prev
)
=
Args
mode
(
KernelDebug
:
prev
)
addDebug
(
Args
m
d
prev
)
=
Args
md
(
KernelDebug
:
prev
)
kernelStackFlag
::
Flag
Args
kernelStackFlag
=
flagNone
[
"stack"
]
addStack
"Inherit environment from `stack` when it is installed"
where
addStack
(
Args
m
ode
prev
)
=
Args
mode
(
KernelspecUseStack
:
prev
)
addStack
(
Args
m
d
prev
)
=
Args
md
(
KernelspecUseStack
:
prev
)
confFlag
::
Flag
Args
confFlag
=
flagReq
[
"conf"
,
"c"
]
(
store
ConfFile
)
"<rc.hs>"
...
...
@@ -131,10 +131,10 @@ helpFlag :: Flag Args
helpFlag
=
flagHelpSimple
(
add
Help
)
add
::
Argument
->
Args
->
Args
add
flag
(
Args
m
ode
flags
)
=
Args
mode
$
flag
:
flags
add
flag
(
Args
m
d
flags
)
=
Args
md
$
flag
:
flags
store
::
(
String
->
Argument
)
->
String
->
Args
->
Either
String
Args
store
constructor
str
(
Args
m
ode
prev
)
=
Right
$
Args
mode
$
constructor
str
:
prev
store
constructor
str
(
Args
m
d
prev
)
=
Right
$
Args
md
$
constructor
str
:
prev
installKernelSpec
::
Mode
Args
installKernelSpec
=
...
...
@@ -166,14 +166,14 @@ convert = mode "convert" (Args ConvertLhs []) description unnamedArg convertFlag
,
helpFlag
]
consForce
(
Args
m
ode
prev
)
=
Args
mode
(
OverwriteFiles
:
prev
)
consForce
(
Args
m
d
prev
)
=
Args
md
(
OverwriteFiles
:
prev
)
unnamedArg
=
Arg
(
store
ConvertFrom
)
"<file>"
False
consStyle
style
(
Args
m
ode
prev
)
=
Args
mode
(
ConvertLhsStyle
style
:
prev
)
consStyle
style
(
Args
m
d
prev
)
=
Args
md
(
ConvertLhsStyle
style
:
prev
)
storeFormat
constructor
str
(
Args
m
ode
prev
)
=
storeFormat
constructor
str
(
Args
m
d
prev
)
=
case
T
.
toLower
(
T
.
pack
str
)
of
"lhs"
->
Right
$
Args
m
ode
$
constructor
LhsMarkdown
:
prev
"ipynb"
->
Right
$
Args
m
ode
$
constructor
IpynbFile
:
prev
"lhs"
->
Right
$
Args
m
d
$
constructor
LhsMarkdown
:
prev
"ipynb"
->
Right
$
Args
m
d
$
constructor
IpynbFile
:
prev
_
->
Left
$
"Unknown format requested: "
++
str
storeLhs
str
previousArgs
=
...
...
@@ -194,12 +194,9 @@ ihaskellArgs =
let
noMode
=
mode
"IHaskell"
defaultReport
descr
noArgs
[
helpFlag
,
versionFlag
]
defaultReport
=
Args
(
ShowDefault
helpStr
)
[]
descr
=
"Haskell for Interactive Computing."
helpFlag
=
flagHelpSimple
(
add
Help
)
versionFlag
=
flagVersion
(
add
Version
)
helpStr
=
showText
(
Wrap
100
)
$
helpText
[]
HelpFormatAll
ihaskellArgs
in
noMode
{
modeGroupModes
=
toGroup
allModes
}
where
add
flag
(
Args
mode
flags
)
=
Args
mode
$
flag
:
flags
noArgs
::
Arg
a
noArgs
=
flagArg
unexpected
""
...
...
src/IHaskell/IPython.hs
View file @
f43b9129
...
...
@@ -89,14 +89,14 @@ ensure getDir = do
ihaskellDir
::
SH
.
Sh
FilePath
ihaskellDir
=
do
home
<-
maybe
(
error
"$HOME not defined."
)
SH
.
fromText
<$>
SH
.
get_env
"HOME"
fp
<$>
ensure
(
return
(
home
SH
.</>
".ihaskell"
))
fp
<$>
ensure
(
return
(
home
SH
.</>
(
".ihaskell"
::
SH
.
FilePath
)
))
getIHaskellDir
::
IO
String
getIHaskellDir
=
SH
.
shelly
ihaskellDir
defaultConfFile
::
IO
(
Maybe
String
)
defaultConfFile
=
fmap
(
fmap
fp
)
.
SH
.
shelly
$
do
filename
<-
(
SH
.</>
"rc.hs"
)
<$>
ihaskellDir
filename
<-
(
SH
.</>
(
"rc.hs"
::
SH
.
FilePath
)
)
<$>
ihaskellDir
exists
<-
SH
.
test_f
filename
return
$
if
exists
then
Just
filename
...
...
@@ -116,17 +116,17 @@ verifyIPythonVersion = do
Nothing
->
badIPython
"No Jupyter / IPython detected -- install Jupyter 3.0+ before using IHaskell."
Just
path
->
do
s
td
out
<-
SH
.
silently
(
SH
.
run
path
[
"--version"
])
s
td
err
<-
SH
.
lastStderr
sout
<-
SH
.
silently
(
SH
.
run
path
[
"--version"
])
serr
<-
SH
.
lastStderr
let
majorVersion
=
join
.
fmap
listToMaybe
.
parseVersion
.
T
.
unpack
case
mplus
(
majorVersion
s
tderr
)
(
majorVersion
std
out
)
of
case
mplus
(
majorVersion
s
err
)
(
majorVersion
s
out
)
of
Nothing
->
badIPython
$
T
.
concat
[
"Detected Jupyter, but could not parse version number."
,
"
\n
"
,
"(stdout = "
,
s
td
out
,
sout
,
", stderr = "
,
s
td
err
,
serr
,
")"
]
...
...
@@ -143,7 +143,7 @@ verifyIPythonVersion = do
-- | Install an IHaskell kernelspec into the right location. The right location is determined by
-- using `ipython kernelspec install --user`.
installKernelspec
::
Bool
->
KernelSpecOptions
->
SH
.
Sh
()
installKernelspec
repl
ace
opts
=
void
$
do
installKernelspec
repl
opts
=
void
$
do
ihaskellPath
<-
getIHaskellPath
confFile
<-
liftIO
$
kernelSpecConfFile
opts
...
...
@@ -169,7 +169,7 @@ installKernelspec replace opts = void $ do
-- shell out to IPython to install this kernelspec directory.
SH
.
withTmpDir
$
\
tmp
->
do
let
kernelDir
=
tmp
SH
.</>
kernelName
let
filename
=
kernelDir
SH
.</>
"kernel.json"
let
filename
=
kernelDir
SH
.</>
(
"kernel.json"
::
SH
.
FilePath
)
SH
.
mkdir_p
kernelDir
SH
.
writefile
filename
$
LT
.
toStrict
$
toLazyText
$
encodeToTextBuilder
$
toJSON
kernelSpec
...
...
@@ -180,7 +180,7 @@ installKernelspec replace opts = void $ do
ipython
<-
locateIPython
let
replaceFlag
=
[
"--replace"
|
repl
ace
]
let
replaceFlag
=
[
"--replace"
|
repl
]
installPrefixFlag
=
maybe
[
"--user"
]
(
\
prefix
->
[
"--prefix"
,
T
.
pack
prefix
])
(
kernelSpecInstallPrefix
opts
)
cmd
=
concat
[[
"kernelspec"
,
"install"
],
installPrefixFlag
,
[
SH
.
toTextIgnore
kernelDir
],
replaceFlag
]
...
...
src/IHaskell/IPython/Stdin.hs
View file @
f43b9129
...
...
@@ -72,8 +72,8 @@ stdinOnce dir = do
loop
stdinInput
oldStdin
newStdin
=
do
let
FileHandle
_
mvar
=
stdin
threadDelay
$
150
*
1000
e
mpty
<-
isEmptyMVar
mvar
if
not
e
mpty
e
<-
isEmptyMVar
mvar
if
not
e
then
loop
stdinInput
oldStdin
newStdin
else
do
line
<-
getInputLine
dir
...
...
@@ -87,17 +87,17 @@ getInputLine dir = do
-- Send a request for input.
uuid
<-
UUID
.
random
parentH
eade
r
<-
fromJust
.
readMay
<$>
readFile
(
dir
++
"/.last-req-header"
)
let
h
eade
r
=
MessageHeader
{
username
=
username
parentH
eade
r
,
identifiers
=
identifiers
parentH
eade
r
,
parentHeader
=
Just
parentH
eade
r
parentH
d
r
<-
fromJust
.
readMay
<$>
readFile
(
dir
++
"/.last-req-header"
)
let
h
d
r
=
MessageHeader
{
username
=
username
parentH
d
r
,
identifiers
=
identifiers
parentH
d
r
,
parentHeader
=
Just
parentH
d
r
,
messageId
=
uuid
,
sessionId
=
sessionId
parentH
eade
r
,
sessionId
=
sessionId
parentH
d
r
,
metadata
=
Map
.
fromList
[]
,
msgType
=
InputRequestMessage
}
let
msg
=
RequestInput
h
eade
r
""
let
msg
=
RequestInput
h
d
r
""
writeChan
req
msg
-- Get the reply.
...
...
@@ -105,8 +105,8 @@ getInputLine dir = do
return
value
recordParentHeader
::
String
->
MessageHeader
->
IO
()
recordParentHeader
dir
h
eade
r
=
writeFile
(
dir
++
"/.last-req-h
eader"
)
$
show
heade
r
recordParentHeader
dir
h
d
r
=
writeFile
(
dir
++
"/.last-req-h
dr"
)
$
show
hd
r
recordKernelProfile
::
String
->
Profile
->
IO
()
recordKernelProfile
dir
profile
=
...
...
src/IHaskell/Publish.hs
View file @
f43b9129
...
...
@@ -25,7 +25,7 @@ publishResult :: (Message -> IO ()) -- ^ A function to send messages
->
Bool
-- ^ Whether to use the pager
->
EvaluationResult
-- ^ The evaluation result
->
IO
()
publishResult
send
replyHeader
displayed
updateNeeded
p
agerOutput
useP
ager
result
=
do
publishResult
send
replyHeader
displayed
updateNeeded
p
output
up
ager
result
=
do
let
final
=
case
result
of
IntermediateResult
{}
->
False
...
...
@@ -51,21 +51,21 @@ publishResult send replyHeader displayed updateNeeded pagerOutput usePager resul
-- If this has some pager output, store it for later.
let
pager
=
pagerOut
result
unless
(
null
pager
)
$
if
u
seP
ager
then
modifyMVar_
p
agerO
utput
(
return
.
(
++
pager
))
if
u
p
ager
then
modifyMVar_
p
o
utput
(
return
.
(
++
pager
))
else
sendOutput
$
Display
pager
where
clearOutput
=
do
h
eade
r
<-
dupHeader
replyHeader
ClearOutputMessage
send
$
ClearOutput
h
eade
r
True
h
d
r
<-
dupHeader
replyHeader
ClearOutputMessage
send
$
ClearOutput
h
d
r
True
sendOutput
(
ManyDisplay
manyOuts
)
=
mapM_
sendOutput
manyOuts
sendOutput
(
Display
outs
)
=
do
h
eade
r
<-
dupHeader
replyHeader
DisplayDataMessage
send
$
PublishDisplayData
h
eade
r
$
map
(
convertSvgToHtml
.
prependCss
)
outs
h
d
r
<-
dupHeader
replyHeader
DisplayDataMessage
send
$
PublishDisplayData
h
d
r
$
map
(
convertSvgToHtml
.
prependCss
)
outs
convertSvgToHtml
(
DisplayData
MimeSvg
s
vg
)
=
html
$
makeSvgImg
$
base64
$
E
.
encodeUtf8
svg
convertSvgToHtml
(
DisplayData
MimeSvg
s
)
=
html
$
makeSvgImg
$
base64
$
E
.
encodeUtf8
s
convertSvgToHtml
x
=
x
makeSvgImg
::
Base64
->
String
...
...
@@ -73,6 +73,6 @@ publishResult send replyHeader displayed updateNeeded pagerOutput usePager resul
base64data
<>
"
\"
/>"
prependCss
(
DisplayData
MimeHtml
h
tml
)
=
DisplayData
MimeHtml
$
mconcat
[
"<style>"
,
T
.
pack
ihaskellCSS
,
"</style>"
,
h
tml
]
prependCss
(
DisplayData
MimeHtml
h
)
=
DisplayData
MimeHtml
$
mconcat
[
"<style>"
,
T
.
pack
ihaskellCSS
,
"</style>"
,
h
]
prependCss
x
=
x
src/IHaskell/Types.hs
View file @
f43b9129
...
...
@@ -12,7 +12,7 @@ module IHaskell.Types (
MessageType
(
..
),
dupHeader
,
Username
,
Metadata
(
..
)
,
Metadata
,
replyType
,
ExecutionState
(
..
),
StreamType
(
..
),
...
...
@@ -39,7 +39,7 @@ module IHaskell.Types (
import
IHaskellPrelude
import
Data.Aeson
(
Value
,
(
.=
),
object
)
import
Data.Aeson
(
ToJSON
,
Value
,
(
.=
),
object
)
import
Data.Function
(
on
)
import
Data.Serialize
import
GHC.Generics
...
...
@@ -91,6 +91,28 @@ class IHaskellDisplay a => IHaskellWidget a where
->
IO
()
close
_
_
=
return
()
-- | these instances cause the image, html etc. which look like:
--
-- > Display
-- > [Display]
-- > IO [Display]
-- > IO (IO Display)
--
-- be run the IO and get rendered (if the frontend allows it) in the pretty form.
instance
IHaskellDisplay
a
=>
IHaskellDisplay
(
IO
a
)
where
display
=
(
display
=<<
)
instance
IHaskellDisplay
Display
where
display
=
return
instance
IHaskellDisplay
DisplayData
where
display
disp
=
return
$
Display
[
disp
]
instance
IHaskellDisplay
a
=>
IHaskellDisplay
[
a
]
where
display
disps
=
do
displays
<-
mapM
display
disps
return
$
ManyDisplay
displays
data
Widget
=
forall
a
.
IHaskellWidget
a
=>
Widget
a
deriving
Typeable
...
...
@@ -221,9 +243,9 @@ data WidgetMethod = UpdateState Value
|
DisplayWidget
instance
ToJSON
WidgetMethod
where
toJSON
DisplayWidget
=
object
[
"method"
.=
"display"
]
toJSON
(
UpdateState
v
)
=
object
[
"method"
.=
"update"
,
"state"
.=
v
]
toJSON
(
CustomContent
v
)
=
object
[
"method"
.=
"custom"
,
"content"
.=
v
]
toJSON
DisplayWidget
=
object
[
"method"
.=
(
"display"
::
Text
)
]
toJSON
(
UpdateState
v
)
=
object
[
"method"
.=
(
"update"
::
Text
)
,
"state"
.=
v
]
toJSON
(
CustomContent
v
)
=
object
[
"method"
.=
(
"custom"
::
Text
)
,
"content"
.=
v
]
-- | Output of evaluation.
data
EvaluationResult
=
...
...
@@ -243,7 +265,7 @@ data EvaluationResult =
-- | Duplicate a message header, giving it a new UUID and message type.
dupHeader
::
MessageHeader
->
MessageType
->
IO
MessageHeader
dupHeader
h
eade
r
messageType
=
do
dupHeader
h
d
r
messageType
=
do
uuid
<-
liftIO
random
return
h
eade
r
{
messageId
=
uuid
,
msgType
=
messageType
}
return
h
d
r
{
messageId
=
uuid
,
msgType
=
messageType
}
src/tests/IHaskell/Test/Completion.hs
View file @
f43b9129
{-# language NoImplicitPrelude, DoAndIfThenElse, OverloadedStrings, ExtendedDefaultRules #-}
{-# LANGUAGE CPP #-}
-- Shelly's types are kinda borked.
{-# OPTIONS_GHC -Wno-type-defaults #-}
module
IHaskell.Test.Completion
(
testCompletions
)
where
import
Prelude
...
...
@@ -196,11 +201,11 @@ inDirectory dirs files action = shelly $ withTmpDir $ \dirPath -> do
where
cdEvent
path
=
liftIO
$
setCurrentDirectory
path
wrap
::
String
->
Interpreter
a
->
Interpreter
a
wrap
path
act
io
n
=
do
wrap
path
actn
=
do
initCompleter
pwd
<-
IHaskell
.
Eval
.
Evaluate
.
liftIO
getCurrentDirectory
cdEvent
path
-- change to the temporary directory
out
<-
act
io
n
-- run action
out
<-
actn
-- run action
cdEvent
pwd
-- change back to the original directory
return
out
...
...
@@ -212,4 +217,5 @@ withHsDirectory = inDirectory [p "" </> p "dir", p "dir" </> p "dir1"]
,
p
"dir"
</>
p
"file2.lhs"
]
where
p
::
T
.
Text
->
T
.
Text
p
=
id
src/tests/IHaskell/Test/Eval.hs
View file @
f43b9129
...
...
@@ -37,8 +37,8 @@ eval string = do
_
<-
interpret
GHC
.
Paths
.
libdir
False
$
const
$
IHaskell
.
Eval
.
Evaluate
.
evaluate
state
string
publish
noWidgetHandling
out
<-
readIORef
outputAccum
pager
O
ut
<-
readIORef
pagerAccum
return
(
reverse
out
,
unlines
.
map
extractPlain
.
reverse
$
pager
O
ut
)
pager
o
ut
<-
readIORef
pagerAccum
return
(
reverse
out
,
unlines
.
map
extractPlain
.
reverse
$
pager
o
ut
)
becomes
::
String
->
[
String
]
->
IO
()
becomes
string
expected
=
evaluationComparing
comparison
string
...
...
@@ -49,9 +49,9 @@ becomes string expected = evaluationComparing comparison string
expectationFailure
$
"Expected result to have "
++
show
(
length
expected
)
++
" results. Got "
++
show
results
forM_
(
zip
results
expected
)
$
\
(
ManyDisplay
[
Display
result
],
expect
ed
)
->
case
extractPlain
result
of
""
->
expectationFailure
$
"No plain-text output in "
++
show
result
++
"
\n
Expected: "
++
expect
ed
str
->
str
`
shouldBe
`
expect
ed
forM_
(
zip
results
expected
)
$
\
(
ManyDisplay
[
Display
result
],
expect
)
->
case
extractPlain
result
of
""
->
expectationFailure
$
"No plain-text output in "
++
show
result
++
"
\n
Expected: "
++
expect
str
->
str
`
shouldBe
`
expect
evaluationComparing
::
(([
Display
],
String
)
->
IO
b
)
->
String
->
IO
b
evaluationComparing
comparison
string
=
do
...
...
@@ -72,21 +72,21 @@ pages string expected = evaluationComparing comparison string
-- A very, very hacky method for removing HTML
stripHtml
str
=
go
str
where
go
(
'<'
:
str
)
=
case
stripPrefix
"script"
str
of
go
(
'<'
:
xs
)
=
case
stripPrefix
"script"
xs
of
Nothing
->
go'
str
Just
s
tr
->
dropScriptTag
str
Just
s
->
dropScriptTag
s
go
(
x
:
xs
)
=
x
:
go
xs
go
[]
=
[]
go'
(
'>'
:
str
)
=
go
str
go'
(
'>'
:
xs
)
=
go
xs
go'
(
_
:
xs
)
=
go'
xs
go'
[]
=
error
$
"Unending bracket html tag in string "
++
str
dropScriptTag
str
=
case
stripPrefix
"</script>"
str
of
Just
s
tr
->
go
str
Nothing
->
dropScriptTag
$
tail
str
dropScriptTag
str
1
=
case
stripPrefix
"</script>"
str
1
of
Just
s
->
go
s
Nothing
->
dropScriptTag
$
tail
str
fixQuotes
::
String
->
String
fixQuotes
=
id
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment