From d3a686627704c3c73d86f5d31bf3669e5c793b35 Mon Sep 17 00:00:00 2001 From: krasimir Date: Tue, 24 Aug 2010 15:58:22 +0000 Subject: [PATCH] more advanced complete function in the PGFService --- src/runtime/haskell/PGF.hs | 33 --------------- src/server/PGFService.hs | 42 ++++++++++++++----- src/ui/gwt/Translate-compile | 3 -- .../ui/gwt/client/CompletionOracle.java | 10 ++++- .../ui/gwt/client/FridgeBagPanel.java | 27 +++++------- .../ui/gwt/client/PGF.java | 16 +++++++ 6 files changed, 66 insertions(+), 65 deletions(-) diff --git a/src/runtime/haskell/PGF.hs b/src/runtime/haskell/PGF.hs index 9bdfd8b23..0a110f83d 100644 --- a/src/runtime/haskell/PGF.hs +++ b/src/runtime/haskell/PGF.hs @@ -79,7 +79,6 @@ module PGF( TcError(..), ppTcError, -- ** Low level parsing API - complete, Parse.ParseState, Parse.initState, Parse.nextState, Parse.getCompletions, Parse.recoveryStates, Parse.ParseInput(..), Parse.simpleParseInput, Parse.mkParseInput, @@ -208,14 +207,6 @@ functions :: PGF -> [CId] -- | The type of a given function functionType :: PGF -> CId -> Maybe Type --- | Complete the last word in the given string. If the input --- is empty or ends in whitespace, the last word is considred --- to be the empty string. This means that the completions --- will be all possible next words. -complete :: PGF -> Language -> Type -> String - -> [String] -- ^ Possible completions, - -- including the given input. - --------------------------------------------------- -- Implementation @@ -274,30 +265,6 @@ functionType pgf fun = Just (ty,_,_) -> Just ty Nothing -> Nothing -complete pgf from typ input = - let (ws,prefix) = tokensAndPrefix input - state0 = Parse.initState pgf from typ - in case loop state0 ws of - Nothing -> [] - Just state -> (if null prefix && isSuccessful state then [unwords ws ++ " "] else []) - ++ [unwords (ws++[c]) ++ " " | c <- Map.keys (Parse.getCompletions state prefix)] - where - isSuccessful state = - case Parse.getParseOutput state typ of - (Parse.ParseOk ts, _) -> not (null ts) - _ -> False - - tokensAndPrefix :: String -> ([String],String) - tokensAndPrefix s | not (null s) && isSpace (last s) = (ws, "") - | null ws = ([],"") - | otherwise = (init ws, last ws) - where ws = words s - - loop ps [] = Just ps - loop ps (t:ts) = case Parse.nextState ps (Parse.simpleParseInput t) of - Left es -> Nothing - Right ps -> loop ps ts - -- | Converts an expression to normal form compute :: PGF -> Expr -> Expr compute pgf = PGF.Data.normalForm (funs (abstract pgf),const Nothing) 0 [] diff --git a/src/server/PGFService.hs b/src/server/PGFService.hs index d79cf644b..dae25c567 100644 --- a/src/server/PGFService.hs +++ b/src/server/PGFService.hs @@ -213,12 +213,15 @@ doParse pgf input mcat mfrom = showJSON $ map toJSObject ] | (fid,err) <- errs])] doComplete :: PGF -> String -> Maybe PGF.Type -> Maybe PGF.Language -> Maybe Int -> JSValue -doComplete pgf input mcat mfrom mlimit = showJSON $ map toJSObject $ limit - [[("from", PGF.showLanguage from),("text",text)] - | (from,compls) <- complete' pgf input mcat mfrom, - text <- compls] +doComplete pgf input mcat mfrom mlimit = showJSON $ map toJSObject + [[("from", showJSON from), + ("brackets", showJSON bs), + ("completions", showJSON cs), + ("text", showJSON s)] + | from <- froms, let (bs,s,cs) = complete' pgf from cat mlimit input] where - limit xs = maybe xs (\n -> take n xs) mlimit + froms = maybe (PGF.languages pgf) (:[]) mfrom + cat = fromMaybe (PGF.startCat pgf) mcat doLinearize :: PGF -> PGF.Tree -> Maybe PGF.Language -> JSValue doLinearize pgf tree mto = showJSON $ map toJSObject @@ -388,12 +391,29 @@ parse' pgf input mcat mfrom = where froms = maybe (PGF.languages pgf) (:[]) mfrom cat = fromMaybe (PGF.startCat pgf) mcat -complete' :: PGF -> String -> Maybe PGF.Type -> Maybe PGF.Language -> [(PGF.Language,[String])] -complete' pgf input mcat mfrom = - [(from,order ss) | from <- froms, let ss = PGF.complete pgf from cat input, not (null ss)] - where froms = maybe (PGF.languages pgf) (:[]) mfrom - cat = fromMaybe (PGF.startCat pgf) mcat - order = sortBy (compare `on` map toLower) +complete' :: PGF -> PGF.Language -> PGF.Type -> Maybe Int -> String + -> (PGF.BracketedString, String, [String]) +complete' pgf from typ mlimit input = + let (ws,prefix) = tokensAndPrefix input + ps0 = PGF.initState pgf from typ + (ps,ws') = loop ps0 ws + bs = snd (PGF.getParseOutput ps typ) + in if not (null ws') + then (bs, unwords (if null prefix then ws' else ws'++[prefix]), []) + else (bs, prefix, maybe id take mlimit $ order $ Map.keys (PGF.getCompletions ps prefix)) + where + order = sortBy (compare `on` map toLower) + + tokensAndPrefix :: String -> ([String],String) + tokensAndPrefix s | not (null s) && isSpace (last s) = (ws, "") + | null ws = ([],"") + | otherwise = (init ws, last ws) + where ws = words s + + loop ps [] = (ps,[]) + loop ps (w:ws) = case PGF.nextState ps (PGF.simpleParseInput w) of + Left es -> (ps,w:ws) + Right ps -> loop ps ws linearize' :: PGF -> Maybe PGF.Language -> PGF.Tree -> [(PGF.Language,String)] linearize' pgf mto tree = diff --git a/src/ui/gwt/Translate-compile b/src/ui/gwt/Translate-compile index c2fbca65c..220cf4a46 100644 --- a/src/ui/gwt/Translate-compile +++ b/src/ui/gwt/Translate-compile @@ -2,9 +2,6 @@ APPDIR=`dirname $0`; -GWT_DIR="/home/angelov/gwt-2.0.4" -GWT_CLASSPATH="$GWT_DIR/gwt-user.jar:$GWT_DIR/gwt-dev.jar" - if [ -z "$GWT_CLASSPATH" ]; then echo 'ERROR: $GWT_CLASSPATH is not set' echo 'Set $GWT_CLASSPATH to point to the GWT JAR files. For example:' diff --git a/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/CompletionOracle.java b/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/CompletionOracle.java index 0e78deb1b..1ff3f5d16 100644 --- a/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/CompletionOracle.java +++ b/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/CompletionOracle.java @@ -122,7 +122,15 @@ public class CompletionOracle extends SuggestOracle { jsonRequest = null; List suggestions = new ArrayList(); for (PGF.Completion completion : completions.iterable()) { - suggestions.add(new CompletionSuggestion(completion.getText())); + String text = completion.getBracketedString().render(); + for (String tokn : completion.getCompletions()) { + StringBuilder sbuilder = new StringBuilder(); + sbuilder.append(text); + if (sbuilder.length() > 0) + sbuilder.append(' '); + sbuilder.append(tokn); + suggestions.add(new CompletionSuggestion(sbuilder.toString())); + } } suggestionsReady(request, callback, suggestions); } diff --git a/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/FridgeBagPanel.java b/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/FridgeBagPanel.java index 525bb968d..657f3bf13 100644 --- a/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/FridgeBagPanel.java +++ b/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/FridgeBagPanel.java @@ -54,23 +54,16 @@ public class FridgeBagPanel extends Composite { limit, new PGF.CompleteCallback() { public void onResult(PGF.Completions completions) { for (PGF.Completion completion : completions.iterable()) { - String newText = completion.getText(); - if (!newText.equals(text + " ")) { - String[] words = newText.split("\\s+"); - if (words.length > 0) { - String word = words[words.length - 1]; - if (word.length() > 0) { - if (updatePrefixes) { - addPrefix(text, word.substring(0,1)); - } - if (mainPanel.getWidgetCount() < maxMagnets) { - Magnet magnet = magnetFactory.createMagnet(word, completion.getFrom()); - mainPanel.add(magnet); - removeStyleDependentName("empty"); - } else { - prefixPanel.setVisible(true); - } - } + for (String word : completion.getCompletions()) { + if (updatePrefixes) { + addPrefix(text, word.substring(0,1)); + } + if (mainPanel.getWidgetCount() < maxMagnets) { + Magnet magnet = magnetFactory.createMagnet(word, completion.getFrom()); + mainPanel.add(magnet); + removeStyleDependentName("empty"); + } else { + prefixPanel.setVisible(true); } } } diff --git a/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/PGF.java b/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/PGF.java index f6776597e..a6c5cab55 100644 --- a/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/PGF.java +++ b/src/ui/gwt/src/org/grammaticalframework/ui/gwt/client/PGF.java @@ -113,6 +113,8 @@ public class PGF { protected Completion() { } public final native String getFrom() /*-{ return this.from; }-*/; + public final native BracketedString getBracketedString() /*-{ return this.brackets; }-*/; + public final native String[] getCompletions() /*-{ return this.completions; }-*/; public final native String getText() /*-{ return this.text; }-*/; } @@ -150,6 +152,20 @@ public class PGF { public final native int getFId() /*-{ return this.fid; }-*/; public final native int getIndex() /*-{ return this.index; }-*/; public final native BracketedString[] getChildren() /*-{ return this.children; }-*/; + + public final String render() { + if (getToken() != null) + return getToken(); + else { + StringBuilder sbuilder = new StringBuilder(); + for (BracketedString bs : getChildren()) { + if (sbuilder.length() > 0) + sbuilder.append(' '); + sbuilder.append(bs.render()); + } + return sbuilder.toString(); + } + } } public static class TcError extends JavaScriptObject {