diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -11,6 +11,7 @@
 import Control.Monad.Error
 
 import Data.Version
+import Data.List
 import Data.ByteString.Lazy (ByteString)
 import Data.ByteString.Lazy.Char8 ()
 import qualified Data.ByteString.Lazy.Char8 as B
@@ -179,7 +180,7 @@
   where
     settings :: MonadIO m => FilePath -> Settings m
     settings home = do
-      setComplete noCompletion $ defaultSettings { historyFile = Just (home </> ".egison_tutorial_history") }
+      setComplete completeParen $ defaultSettings { historyFile = Just (home </> ".egison_tutorial_history") }
     
     loop :: Env -> String -> String -> [Content] -> Bool -> InputT IO ()
     loop env prompt' _ [] _ = do
@@ -240,6 +241,76 @@
             Right env' ->
               loop env' prompt "" ts False
 
+completeParen :: Monad m => CompletionFunc m
+completeParen arg@((')':_), _) = completeParen' arg
+completeParen arg@(('>':_), _) = completeParen' arg
+completeParen arg@((']':_), _) = completeParen' arg
+completeParen arg@(('}':_), _) = completeParen' arg
+completeParen arg@(('(':_), _) = (completeWord Nothing " \t<>[]{}$," completeAfterOpenParen) arg
+completeParen arg@(('<':_), _) = (completeWord Nothing " \t()[]{}$," completeAfterOpenCons) arg
+completeParen arg@((' ':_), _) = (completeWord Nothing "" completeNothing) arg
+completeParen arg@([], _) = (completeWord Nothing "" completeNothing) arg
+completeParen arg@(_, _) = (completeWord Nothing " \t[]{}$," completeEgisonKeyword) arg
+
+completeAfterOpenParen :: Monad m => String -> m [Completion]
+completeAfterOpenParen str = return $ map (\kwd -> Completion kwd kwd False) $ filter (isPrefixOf str) egisonKeywordsAfterOpenParen
+
+completeAfterOpenCons :: Monad m => String -> m [Completion]
+completeAfterOpenCons str = return $ map (\kwd -> Completion kwd kwd False) $ filter (isPrefixOf str) egisonKeywordsAfterOpenCons
+
+completeNothing :: Monad m => String -> m [Completion]
+completeNothing _ = return []
+
+completeEgisonKeyword :: Monad m => String -> m [Completion]
+completeEgisonKeyword str = return $ map (\kwd -> Completion kwd kwd False) $ filter (isPrefixOf str) egisonKeywords
+
+egisonKeywordsAfterOpenParen = map ((:) '(') $ ["define", "let", "letrec", "do", "lambda", "match-lambda", "match", "match-all", "pattern-function", "matcher", "algebraic-data-matcher", "if", "loop", "io"]
+                            ++ ["id", "or", "and", "not", "char", "eq?/m", "compose", "compose3", "list", "map", "between", "repeat1", "repeat", "filter", "separate", "concat", "foldr", "foldl", "map2", "zip", "empty?", "member?", "member?/m", "include?", "include?/m", "any", "all", "length", "count", "count/m", "car", "cdr", "rac", "rdc", "nth", "take", "drop", "while", "reverse", "multiset", "add", "add/m", "delete-first", "delete-first/m", "delete", "delete/m", "difference", "difference/m", "union", "union/m", "intersect", "intersect/m", "set", "unique", "unique/m", "simple-select", "print", "print-to-port", "each", "pure-rand", "fib", "fact", "divisor?", "gcd", "primes", "find-factor", "prime-factorization", "p-f", "pfs", "pfs-n", "min", "max", "min-and-max", "power", "mod", "float", "ordering", "qsort", "intersperse", "intercalate", "split", "split/m"]
+egisonKeywordsAfterOpenCons = map ((:) '<') ["nil", "cons", "join", "snoc", "nioj"]
+egisonKeywordsInNeutral = ["something"]
+                       ++ ["bool", "string", "integer", "nat", "nats", "nats0"]
+egisonKeywords = egisonKeywordsAfterOpenParen ++ egisonKeywordsAfterOpenCons ++ egisonKeywordsInNeutral
+
+completeParen' :: Monad m => CompletionFunc m
+completeParen' (lstr, _) = case (closeParen lstr) of
+                             Nothing -> return (lstr, [])
+                             Just paren -> return (lstr, [(Completion paren paren False)])
+
+closeParen :: String -> Maybe String
+closeParen str = closeParen' 0 $ removeCharAndStringLiteral str
+
+removeCharAndStringLiteral :: String -> String
+removeCharAndStringLiteral [] = []
+removeCharAndStringLiteral ('"':'\\':str) = '"':'\\':(removeCharAndStringLiteral str)
+removeCharAndStringLiteral ('"':str) = removeCharAndStringLiteral' str
+removeCharAndStringLiteral ('\'':'\\':str) = '\'':'\\':(removeCharAndStringLiteral str)
+removeCharAndStringLiteral ('\'':str) = removeCharAndStringLiteral' str
+removeCharAndStringLiteral (c:str) = c:(removeCharAndStringLiteral str)
+
+removeCharAndStringLiteral' :: String -> String
+removeCharAndStringLiteral' [] = []
+removeCharAndStringLiteral' ('"':'\\':str) = removeCharAndStringLiteral' str
+removeCharAndStringLiteral' ('"':str) = removeCharAndStringLiteral str
+removeCharAndStringLiteral' ('\'':'\\':str) = removeCharAndStringLiteral' str
+removeCharAndStringLiteral' ('\'':str) = removeCharAndStringLiteral str
+removeCharAndStringLiteral' (_:str) = removeCharAndStringLiteral' str
+
+closeParen' :: Integer -> String -> Maybe String
+closeParen' _ [] = Nothing
+closeParen' 0 ('(':_) = Just ")"
+closeParen' 0 ('<':_) = Just ">"
+closeParen' 0 ('[':_) = Just "]"
+closeParen' 0 ('{':_) = Just "}"
+closeParen' n ('(':str) = closeParen' (n - 1) str
+closeParen' n ('<':str) = closeParen' (n - 1) str
+closeParen' n ('[':str) = closeParen' (n - 1) str
+closeParen' n ('{':str) = closeParen' (n - 1) str
+closeParen' n (')':str) = closeParen' (n + 1) str
+closeParen' n ('>':str) = closeParen' (n + 1) str
+closeParen' n (']':str) = closeParen' (n + 1) str
+closeParen' n ('}':str) = closeParen' (n + 1) str
+closeParen' n (_:str) = closeParen' n str
+              
 data Tutorial =
     Sections [(String, Tutorial)]
   | Contents [Content]
diff --git a/egison-tutorial.cabal b/egison-tutorial.cabal
--- a/egison-tutorial.cabal
+++ b/egison-tutorial.cabal
@@ -1,5 +1,5 @@
 Name:                egison-tutorial
-Version:             3.2.3
+Version:             3.2.4
 Synopsis:            A tutorial program for the programming language Egison
 Description:         A tutorial program for the programming language Egison.
                      Egison is the programming langugage that realized non-linear pattern-matching with unfree data types.
