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
1cda25e4
Commit
1cda25e4
authored
Jan 06, 2014
by
Andrew Gibiansky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #103 from edechter/path_completion
Path completion
parents
92361c93
42365e54
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
93 additions
and
76 deletions
+93
-76
IHaskell.cabal
IHaskell.cabal
+8
-4
Hspec.hs
src/Hspec.hs
+22
-14
Completion.hs
src/IHaskell/Eval/Completion.hs
+47
-48
Evaluate.hs
src/IHaskell/Eval/Evaluate.hs
+16
-10
No files found.
IHaskell.cabal
View file @
1cda25e4
...
@@ -73,11 +73,12 @@ library
...
@@ -73,11 +73,12 @@ library
directory,
directory,
here,
here,
system-filepath,
system-filepath,
filemanip,
filepath,
filepath,
cereal ==0.3.*,
cereal ==0.3.*,
text >=0.11,
text >=0.11,
mtl >= 2.1
mtl >= 2.1
transformers,
haskeline
exposed-modules: IHaskell.Display
exposed-modules: IHaskell.Display
IHaskell.Eval.Completion
IHaskell.Eval.Completion
IHaskell.Eval.Evaluate
IHaskell.Eval.Evaluate
...
@@ -145,11 +146,12 @@ executable IHaskell
...
@@ -145,11 +146,12 @@ executable IHaskell
directory,
directory,
here,
here,
system-filepath,
system-filepath,
filemanip,
filepath,
filepath,
cereal ==0.3.*,
cereal ==0.3.*,
text >=0.11,
text >=0.11,
mtl >= 2.1
mtl >= 2.1,
transformers,
haskeline
Test-Suite hspec
Test-Suite hspec
hs-source-dirs: src
hs-source-dirs: src
...
@@ -185,7 +187,9 @@ Test-Suite hspec
...
@@ -185,7 +187,9 @@ Test-Suite hspec
filepath,
filepath,
cereal ==0.3.*,
cereal ==0.3.*,
text >=0.11,
text >=0.11,
mtl >= 2.1
mtl >= 2.1,
transformers,
haskeline
extensions: DoAndIfThenElse
extensions: DoAndIfThenElse
OverloadedStrings
OverloadedStrings
ExtendedDefaultRules
ExtendedDefaultRules
...
...
src/Hspec.hs
View file @
1cda25e4
...
@@ -75,9 +75,9 @@ completes string expected = completionTarget newString cursorloc `shouldBe` expe
...
@@ -75,9 +75,9 @@ completes string expected = completionTarget newString cursorloc `shouldBe` expe
Nothing
->
error
"Expected cursor written as '!'."
Nothing
->
error
"Expected cursor written as '!'."
Just
idx
->
(
replace
"!"
""
string
,
idx
)
Just
idx
->
(
replace
"!"
""
string
,
idx
)
completionHas_
action
string
expected
=
do
completionHas_
wrap
string
expected
=
do
(
matched
,
completions
)
<-
doGhc
$
do
(
matched
,
completions
)
<-
doGhc
$
do
initCompleter
action
wrap
$
do
initCompleter
complete
newString
cursorloc
complete
newString
cursorloc
let
existsInCompletion
=
(`
elem
`
completions
)
let
existsInCompletion
=
(`
elem
`
completions
)
unmatched
=
filter
(
not
.
existsInCompletion
)
expected
unmatched
=
filter
(
not
.
existsInCompletion
)
expected
...
@@ -86,10 +86,12 @@ completionHas_ action string expected = do
...
@@ -86,10 +86,12 @@ completionHas_ action string expected = do
Nothing
->
error
"Expected cursor written as '!'."
Nothing
->
error
"Expected cursor written as '!'."
Just
idx
->
(
replace
"!"
""
string
,
idx
)
Just
idx
->
(
replace
"!"
""
string
,
idx
)
completionHas
=
completionHas_
(
return
()
)
completionHas
=
completionHas_
id
initCompleter
::
GhcMonad
m
=>
m
a
->
m
a
initCompleter
::
GhcMonad
m
=>
m
()
initCompleter
action
=
do
initCompleter
=
do
pwd
<-
Eval
.
liftIO
$
getCurrentDirectory
--Eval.liftIO $ traceIO $ pwd
flags
<-
getSessionDynFlags
flags
<-
getSessionDynFlags
setSessionDynFlags
$
flags
{
hscTarget
=
HscInterpreted
,
ghcLink
=
LinkInMemory
}
setSessionDynFlags
$
flags
{
hscTarget
=
HscInterpreted
,
ghcLink
=
LinkInMemory
}
...
@@ -99,7 +101,6 @@ initCompleter action = do
...
@@ -99,7 +101,6 @@ initCompleter action = do
"import qualified Data.List as List"
,
"import qualified Data.List as List"
,
"import Data.Maybe as Maybe"
]
"import Data.Maybe as Maybe"
]
setContext
$
map
IIDecl
imports
setContext
$
map
IIDecl
imports
action
withHsDirectory
::
(
FilePath
->
Sh
()
)
->
IO
()
withHsDirectory
::
(
FilePath
->
Sh
()
)
->
IO
()
withHsDirectory
f
=
shelly
$
withTmpDir
$
\
dirPath
->
withHsDirectory
f
=
shelly
$
withTmpDir
$
\
dirPath
->
...
@@ -141,7 +142,7 @@ completionTests = do
...
@@ -141,7 +142,7 @@ completionTests = do
completionType
"A.x"
[
"A"
,
"x"
]
`
shouldBe
`
Qualified
"A"
"x"
completionType
"A.x"
[
"A"
,
"x"
]
`
shouldBe
`
Qualified
"A"
"x"
completionType
"a.x"
[
"a"
,
"x"
]
`
shouldBe
`
Identifier
"x"
completionType
"a.x"
[
"a"
,
"x"
]
`
shouldBe
`
Identifier
"x"
completionType
"pri"
[
"pri"
]
`
shouldBe
`
Identifier
"pri"
completionType
"pri"
[
"pri"
]
`
shouldBe
`
Identifier
"pri"
completionType
":load A"
[
""
]
`
shouldBe
`
HsFilePath
"A"
completionType
":load A"
[
"
A
"
]
`
shouldBe
`
HsFilePath
"A"
it
"properly completes identifiers"
$
do
it
"properly completes identifiers"
$
do
"pri!"
`
completionHas
`
[
"print"
]
"pri!"
`
completionHas
`
[
"print"
]
...
@@ -166,16 +167,23 @@ completionTests = do
...
@@ -166,16 +167,23 @@ completionTests = do
withHsDirectory
$
\
dirPath
->
withHsDirectory
$
\
dirPath
->
let
loading
xs
=
":load "
++
encodeString
xs
let
loading
xs
=
":load "
++
encodeString
xs
paths
xs
=
map
encodeString
xs
paths
xs
=
map
encodeString
xs
completionHas'
=
completionHas_
$
completionHas'
=
completionHas_
fun
do
Eval
.
evaluate
defaultKernelState
fun
action
=
do
pwd
<-
Eval
.
liftIO
getCurrentDirectory
Eval
.
evaluate
defaultKernelState
(
":! cd "
++
dirPath
)
(
":! cd "
++
dirPath
)
(
\
b
d
->
return
()
)
(
\
b
d
->
return
()
)
out
<-
action
Eval
.
evaluate
defaultKernelState
(
":! cd "
++
pwd
)
(
\
b
d
->
return
()
)
return
out
in
liftIO
$
do
in
liftIO
$
do
loading
(
"dir"
</>
"file!"
)
`
completionHas'
`
paths
[
"dir"
</>
"file2.hs"
,
loading
(
"dir"
</>
"file!"
)
`
completionHas'
`
paths
[
"dir"
</>
"file2.hs"
,
"dir"
</>
"file2.lhs"
]
"dir"
</>
"file2.lhs"
]
loading
(
""
</>
"file1!"
)
`
completionHas'
`
paths
[
""
</>
"file1.hs"
,
loading
(
""
</>
"file1!"
)
`
completionHas'
`
paths
[
""
</>
"file1.hs"
,
""
</>
"file1.lhs"
]
""
</>
"file1.lhs"
]
loading
(
""
</>
"file1!"
)
`
completionHas'
`
paths
[
""
</>
"file1.hs"
,
""
</>
"file1.lhs"
]
evalTests
=
do
evalTests
=
do
describe
"Code Evaluation"
$
do
describe
"Code Evaluation"
$
do
...
...
src/IHaskell/Eval/Completion.hs
View file @
1cda25e4
...
@@ -27,15 +27,17 @@ import GhcMonad
...
@@ -27,15 +27,17 @@ import GhcMonad
import
PackageConfig
import
PackageConfig
import
Outputable
(
showPpr
)
import
Outputable
(
showPpr
)
import
qualified
System.FilePath.Find
as
Find
(
find
)
import
System.FilePath.Find
hiding
(
find
)
import
System.Directory
import
System.Directory
import
System.FilePath.GlobPattern
import
System.FilePath
import
System.FilePath
import
MonadUtils
(
MonadIO
)
import
MonadUtils
(
MonadIO
)
import
Control.Monad
(
filterM
,
mapM
,
liftM
)
import
Control.Monad
(
filterM
,
mapM
,
liftM
)
import
System.Console.Haskeline.Completion
import
qualified
Control.Monad.IO.Class
as
MonadIO
(
MonadIO
()
,
liftIO
)
import
IHaskell.Types
import
IHaskell.Types
import
IHaskell.Eval.Evaluate
(
Interpreter
)
data
CompletionType
data
CompletionType
...
@@ -45,9 +47,10 @@ data CompletionType
...
@@ -45,9 +47,10 @@ data CompletionType
|
Qualified
String
String
|
Qualified
String
String
|
ModuleName
String
String
|
ModuleName
String
String
|
HsFilePath
String
|
HsFilePath
String
|
FilePath
String
deriving
(
Show
,
Eq
)
deriving
(
Show
,
Eq
)
complete
::
GHC
.
GhcMonad
m
=>
String
->
Int
->
m
(
String
,
[
String
])
complete
::
String
->
Int
->
Interpreter
(
String
,
[
String
])
complete
line
pos
=
do
complete
line
pos
=
do
flags
<-
getSessionDynFlags
flags
<-
getSessionDynFlags
rdrNames
<-
map
(
showPpr
flags
)
<$>
getRdrNamesInScope
rdrNames
<-
map
(
showPpr
flags
)
<$>
getRdrNamesInScope
...
@@ -89,12 +92,13 @@ complete line pos = do
...
@@ -89,12 +92,13 @@ complete line pos = do
nonames
=
map
(
"No"
++
)
names
nonames
=
map
(
"No"
++
)
names
return
$
filter
(
ext
`
isPrefixOf
`)
$
names
++
nonames
return
$
filter
(
ext
`
isPrefixOf
`)
$
names
++
nonames
HsFilePath
path
->
do
pwd
<-
liftIO
getCurrentDirectory
HsFilePath
path
->
completePathWithExtensions
[
".hs"
,
".lhs"
]
path
completePath
pwd
(
Just
[
".hs"
,
".lhs"
])
path
FilePath
path
->
completePath
path
return
(
matchedText
,
options
)
return
(
matchedText
,
options
)
getTrueModuleName
::
GhcMonad
m
=>
String
->
m
String
getTrueModuleName
::
String
->
Interpreter
String
getTrueModuleName
name
=
do
getTrueModuleName
name
=
do
-- Only use the things that were actually imported
-- Only use the things that were actually imported
let
onlyImportDecl
(
IIDecl
decl
)
=
Just
decl
let
onlyImportDecl
(
IIDecl
decl
)
=
Just
decl
...
@@ -115,8 +119,10 @@ getTrueModuleName name = do
...
@@ -115,8 +119,10 @@ getTrueModuleName name = do
completionType
::
String
->
[
String
]
->
CompletionType
completionType
::
String
->
[
String
]
->
CompletionType
completionType
line
[]
=
Empty
completionType
line
[]
=
Empty
completionType
line
target
completionType
line
target
|
startswith
":! "
stripped
=
FilePath
complete_target
|
startswith
":l"
stripped
|
startswith
":l"
stripped
=
HsFilePath
$
last
$
splitOn
" "
stripped
=
HsFilePath
complete_target
|
startswith
"import"
stripped
&&
isModName
|
startswith
"import"
stripped
&&
isModName
=
ModuleName
dotted
candidate
=
ModuleName
dotted
candidate
|
isModName
&&
(
not
.
null
.
init
)
target
|
isModName
&&
(
not
.
null
.
init
)
target
...
@@ -131,6 +137,7 @@ completionType line target
...
@@ -131,6 +137,7 @@ completionType line target
dots
=
intercalate
"."
.
init
dots
=
intercalate
"."
.
init
isModName
=
all
isCapitalized
(
init
target
)
isModName
=
all
isCapitalized
(
init
target
)
isCapitalized
=
isUpper
.
head
isCapitalized
=
isUpper
.
head
complete_target
=
intercalate
"."
target
...
@@ -164,32 +171,24 @@ completionTarget code cursor = expandCompletionPiece pieceToComplete
...
@@ -164,32 +171,24 @@ completionTarget code cursor = expandCompletionPiece pieceToComplete
expandCompletionPiece
Nothing
=
[]
expandCompletionPiece
Nothing
=
[]
expandCompletionPiece
(
Just
str
)
=
splitOn
"."
str
expandCompletionPiece
(
Just
str
)
=
splitOn
"."
str
completePath
::
MonadIO
m
=>
completePathFilter
::
(
String
->
Bool
)
-- ^ filter files
String
-- ^ Current directory
->
(
String
->
Bool
)
-- ^ filter directories
->
Maybe
[
String
]
-- ^ list of file extensions
->
String
-- ^ line contents left of cursor
->
String
-- ^ prefix to be completed
->
String
-- ^ line contents right of cursor
->
m
[
String
]
-- ^ completions, that is, if prefix is "Mai" one completion might be "Main.hs"
->
Interpreter
[
String
]
completePath
currDir
exts
prefix
completePathFilter
fileFilter
dirFilter
loc
roc
=
=
let
absolutePrefix
=
combine
currDir
prefix
do
(
_
,
comps
)
<-
MonadIO
.
liftIO
$
(
completeFilename
(
reverse
loc
,
roc
))
searchDir
=
dropFileName
absolutePrefix
let
completions
=
map
replacement
comps
pattern
=
absolutePrefix
++
"*"
dirs
<-
liftIO
$
filterM
doesDirectoryExist
completions
completions
=
liftIO
$
Find
.
find
always
(
filePath
~~?
pattern
)
searchDir
files
<-
liftIO
$
filterM
(
liftM
not
.
doesDirectoryExist
)
completions
allFileCompletions
=
completions
>>=
liftIO
.
filterM
(
liftM
not
.
doesDirectoryExist
)
let
dirs'
=
filter
dirFilter
files
fileCompletions
=
case
exts
of
files'
=
filter
fileFilter
dirs
Nothing
->
allFileCompletions
return
$
filter
(
\
x
->
elem
x
$
dirs'
++
files'
)
completions
Just
exts
->
do
xs
<-
allFileCompletions
return
$
filter
(
\
s
->
or
[
endswith
ext
s
|
ext
<-
exts
])
xs
completePath
::
String
->
Interpreter
[
String
]
dirCompletions
=
completions
completePath
loc
=
completePathFilter
(
const
True
)
(
const
True
)
loc
""
>>=
liftIO
.
filterM
doesDirectoryExist
>>=
\
xs
->
do
return
$
[
x
++
[
pathSeparator
]
|
x
<-
xs
]
completePathWithExtensions
::
[
String
]
->
String
->
Interpreter
[
String
]
relativeCompletions
=
do
validSearchDir
<-
liftIO
$
doesDirectoryExist
searchDir
completePathWithExtensions
extensions
loc
=
if
validSearchDir
then
completePathFilter
(
\
s
->
any
(
\
x
->
endswith
x
s
)
extensions
)
(
const
True
)
loc
""
do
xs
<-
fileCompletions
ys
<-
dirCompletions
return
$
map
(
cut
$
currDir
++
[
pathSeparator
])
$
xs
++
ys
else
return
[]
cut
::
String
->
String
->
String
cut
(
x
:
xs
)
z
@
(
y
:
ys
)
|
x
==
y
=
cut
xs
ys
|
otherwise
=
z
cut
_
z
=
z
in
relativeCompletions
src/IHaskell/Eval/Evaluate.hs
View file @
1cda25e4
{-# LANGUAGE DoAndIfThenElse, NoOverloadedStrings #-}
{-# LANGUAGE DoAndIfThenElse, NoOverloadedStrings, TypeSynonymInstances #-}
{- | Description : Wrapper around GHC API, exposing a single `evaluate` interface that runs
{- | Description : Wrapper around GHC API, exposing a single `evaluate` interface that runs
a statement, declaration, import, or directive.
a statement, declaration, import, or directive.
...
@@ -29,6 +30,8 @@ import Control.Monad (guard)
...
@@ -29,6 +30,8 @@ import Control.Monad (guard)
import
System.Process
import
System.Process
import
System.Exit
import
System.Exit
import
Data.Maybe
(
fromJust
)
import
Data.Maybe
(
fromJust
)
import
qualified
Control.Monad.IO.Class
as
MonadIO
(
MonadIO
,
liftIO
)
import
qualified
MonadUtils
as
MonadUtils
(
MonadIO
,
liftIO
)
import
NameSet
import
NameSet
import
Name
import
Name
...
@@ -81,6 +84,9 @@ write x = when debug $ liftIO $ hPutStrLn stderr $ "DEBUG: " ++ x
...
@@ -81,6 +84,9 @@ write x = when debug $ liftIO $ hPutStrLn stderr $ "DEBUG: " ++ x
type
Interpreter
=
Ghc
type
Interpreter
=
Ghc
instance
MonadIO
.
MonadIO
Interpreter
where
liftIO
=
MonadUtils
.
liftIO
globalImports
::
[
String
]
globalImports
::
[
String
]
globalImports
=
globalImports
=
[
"import IHaskell.Display"
[
"import IHaskell.Display"
...
...
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