diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 Usage
 -----
 
-Cgrep 6.5.9 Usage: cgrep [OPTION] [PATTERN] files...
+Cgrep 6.5.10 Usage: cgrep [OPTION] [PATTERN] files...
 
 cgrep [OPTIONS] [ITEM]
 
diff --git a/cgrep.cabal b/cgrep.cabal
--- a/cgrep.cabal
+++ b/cgrep.cabal
@@ -1,6 +1,6 @@
 Name:                cgrep
 Description:         Cgrep: a context-aware grep for source codes
-Version:             6.5.9
+Version:             6.5.10
 Synopsis:            Command line tool
 Homepage:            http://awgn.github.io/cgrep/
 License:             GPL-2
diff --git a/src/CGrep/Output.hs b/src/CGrep/Output.hs
--- a/src/CGrep/Output.hs
+++ b/src/CGrep/Output.hs
@@ -35,7 +35,6 @@
 
 import Data.Maybe
 import Data.List
-import Data.List.Split
 import Data.Function
 
 import CGrep.Types
@@ -50,7 +49,7 @@
 
 
 getOffsetsLines :: Text8 -> [Int]
-getOffsetsLines = C.elemIndices '\n'
+getOffsetsLines txt = let l = C.length txt in filter (<(l-1)) $ C.elemIndices '\n' txt
 
 
 getOffset2d :: [OffsetLine] -> Offset -> Offset2d
@@ -63,10 +62,9 @@
 mkOutput :: (Monad m) => FilePath -> Text8 -> Text8 -> [Token] -> ReaderT Options m [Output]
 mkOutput f text multi ts = do
     invert <- reader invert_match
-    case () of
-        _ | invert      -> return $ map (\(n, xs) -> Output f n (ls !! (n-1)) xs) . invertMatchLines (length ls) $ mkMatchLines multi ts
-          | otherwise   -> return $ map (\(n, xs) -> Output f n (ls !! (n-1)) xs) $ mkMatchLines multi ts
-            where ls = C.lines text
+    return $ if invert then map (\(n, xs) -> Output f n (ls !! (n-1)) xs) . invertMatchLines (length ls) $ mkMatchLines multi ts
+                       else map (\(n, xs) -> Output f n (ls !! (n-1)) xs) $ mkMatchLines multi ts
+    where ls = C.lines text
 
 
 mkMatchLines :: Text8 -> [Token] -> [MatchLine]
@@ -149,10 +147,11 @@
                                                     unwords (map mkToken ts) ++
                                                     "</match>"
 
+
 formatOutput :: (Monad m) => Output -> ReaderT Options m String
 formatOutput (Output f n l ts) = do
     opt <- ask
-    return $ foldl trans (fromJust $ format opt)
+    return $ replace (fromJust $ format opt)
         [
             ("#f", showFile opt f),
             ("#n", show n),
@@ -172,12 +171,15 @@
             ("#8", atDef "" ts' 8),
             ("#9", atDef "" ts' 9)
         ]
-    where trans str (old, new) = replace old new str
-          ts' = map snd ts
+    where ts' = map snd ts
 
 
-replace :: Eq a => [a] -> [a] -> [a] -> [a]
-replace old new = intercalate new . splitOn old
+replace :: String -> [(String, String)] -> String
+replace ys@(x:xs) pats =
+  let pats' = filter ((`isPrefixOf` ys) . fst) pats  in
+  if null pats' then x : replace xs pats
+                else let new = head pats' in snd new ++ replace (drop (length(fst new) - 1) xs) pats
+replace [] _ = []
 
 
 #ifdef ENABLE_HINT
@@ -221,13 +223,25 @@
 
 
 hilightLine :: [Token] -> String -> String
-hilightLine ts =  hilightLine' (hilightIndicies ts, 0)
-    where hilightLine' :: ([Int],Int) -> String -> String
+hilightLine ts =  hilightLine' (hilightIndicies ts, 0, 0)
+    where hilightLine' :: ([(Int, Int)], Int, Int) -> String -> String
           hilightLine'  _ [] = []
-          hilightLine' (ns,n) (x:xs) = (if n `elem` ns then bold ++ [x] ++ resetTerm
-                                                       else [x]) ++ hilightLine' (ns, n+1) xs
-
+          hilightLine' (ns, n, bs) s@(x:_) = (case () of
+                                                  _ | check && bs' == 0 -> if fst stack > 0 then bold ++ [x] ++ resetTerm
+                                                                                            else x : resetTerm
+                                                    | check && bs' > 0 -> bold ++ [x]
+                                                    | otherwise -> next
+                                             ) ++ hilightLine' (ns, n + nn, bs') rest
+            where stack = foldr (\(a, b) (c, d) -> (c + fromEnum (a == n), d + fromEnum (b == n))) (0, 0) ns
+                  check = fst stack > 0 || snd stack > 0
+                  bs' = bs + fst stack - snd stack
+                  plain = nub . sort $ foldr (\(a, b) acc -> a : b : acc) [] ns
+                  nn | check = 1
+                     | null plain' = length s
+                     | otherwise = head plain' - n
+                         where plain' = dropWhile (<=n) plain
+                  (next, rest) = splitAt nn s
 
-hilightIndicies :: [Token] -> [Int]
-hilightIndicies = concatMap (\(o, s) -> take (length s) [o..])
+hilightIndicies :: [Token] -> [(Int, Int)]
+hilightIndicies = foldr (\t a -> let b = fst t in (b, b + length (snd t) - 1) : a) [] . filter ((>0) . length . snd)
 
diff --git a/src/Config.hs b/src/Config.hs
--- a/src/Config.hs
+++ b/src/Config.hs
@@ -33,7 +33,7 @@
 cgreprc = "cgreprc"
 
 version :: String
-version = "6.5.9"
+version = "6.5.10"
 
 
 data Config = Config
