+pprHsString fs = vcat (map text (showMultiLineString (unpackFS fs)))
+
+---------------------
+-- Put a name in parens if it's an operator
+pprPrefixVar :: Bool -> SDoc -> SDoc
+pprPrefixVar is_operator pp_v
+ | is_operator = parens pp_v
+ | otherwise = pp_v
+
+-- Put a name in backquotes if it's not an operator
+pprInfixVar :: Bool -> SDoc -> SDoc
+pprInfixVar is_operator pp_v
+ | is_operator = pp_v
+ | otherwise = char '`' <> pp_v <> char '`'
+
+---------------------
+-- pprHsVar and pprHsInfix use the gruesome isOperator, which
+-- in turn uses (showSDoc (ppr v)), rather than isSymOcc (getOccName v).
+-- Reason: it means that pprHsVar doesn't need a NamedThing context,
+-- which none of the HsSyn printing functions do
+pprHsVar, pprHsInfix :: Outputable name => name -> SDoc
+pprHsVar v = pprPrefixVar (isOperator pp_v) pp_v
+ where pp_v = ppr v
+pprHsInfix v = pprInfixVar (isOperator pp_v) pp_v
+ where pp_v = ppr v
+
+isOperator :: SDoc -> Bool
+isOperator ppr_v
+ = case showSDocUnqual ppr_v of
+ ('(':_) -> False -- (), (,) etc
+ ('[':_) -> False -- []
+ ('$':c:_) -> not (isAlpha c) -- Don't treat $d as an operator
+ (':':c:_) -> not (isAlpha c) -- Don't treat :T as an operator
+ ('_':_) -> False -- Not an operator
+ (c:_) -> not (isAlpha c) -- Starts with non-alpha
+ _ -> False
+
+pprFastFilePath :: FastString -> SDoc
+pprFastFilePath path = text $ normalise $ unpackFS path