<commit_before>\chapter{Expansions module}

Here is where we do the various expansions.

\begin{code}

module System.Console.ShSh.Expansions ( expandWords, expandWord ) where

import System.Console.ShSh.Parse.AST ( Word(..), Lexeme(..),
                                       Expansion(..) )
import System.Console.ShSh.Foreign.Pwd ( getHomeDir )
import System.Console.ShSh.Shell ( Shell, setEnv, getEnv )
import System.Console.ShSh.ShellError ( throw )

import Control.Monad ( (<=<) )
import Control.Monad.Trans ( lift, liftIO )

import Data.Char ( isAlphaNum )
import Data.List ( takeWhile, dropWhile, groupBy )
import Data.Maybe ( fromMaybe )
import Data.Monoid ( Monoid, mappend, mempty )

-- |This is the primary function now.  We simply take a 'Word' and
-- turn it into a 'LitWord'.  Later we'll need to be a bit more careful
-- with whether or not to field-split, among other things.  Also,
-- we might make convenience functions for expanding a whole 'Statement'
-- (at least, so long as it's not a subshell - these runtime checks are
-- pretty hokey).  Note that 'Word's inside 'Redir's are never split
-- regardless of the value of @$IFS@.
expand' :: Word -> Shell [Lexeme]
expand' = expandParams <=< expandTilde . toLexemes

expandWord :: Word -> Shell String
expandWord = fmap removeQuotes . expand'

-- |This will share a lot of functionality with @expandWord@...
expandWords :: [Word] -> Shell [String]
expandWords = fmap (map removeQuotes) . (splitFields <=< mapM expand')
              -- should we (dropWhile null) as well?

-- |First step: tilde expansion.
expandTilde :: [Lexeme] -> Shell [Lexeme]
expandTilde w = let (lit,rest) = span isLiteral w
                in case (fromLit lit) of
                     '~':s -> exp s rest
                     _     -> return w<commit_msg>don't import <=<, which isn't present in ghc 6.6.<commit_after>\chapter{Expansions module}

Here is where we do the various expansions.

\begin{code}

module System.Console.ShSh.Expansions ( expandWords, expandWord ) where

import System.Console.ShSh.Parse.AST ( Word(..), Lexeme(..),
                                       Expansion(..) )
import System.Console.ShSh.Foreign.Pwd ( getHomeDir )
import System.Console.ShSh.Shell ( Shell, setEnv, getEnv )
import System.Console.ShSh.ShellError ( throw )

import Control.Monad.Trans ( lift, liftIO )

import Data.Char ( isAlphaNum )
import Data.List ( takeWhile, dropWhile, groupBy )
import Data.Maybe ( fromMaybe )
import Data.Monoid ( Monoid, mappend, mempty )

-- |This is the primary function now.  We simply take a 'Word' and
-- turn it into a 'LitWord'.  Later we'll need to be a bit more careful
-- with whether or not to field-split, among other things.  Also,
-- we might make convenience functions for expanding a whole 'Statement'
-- (at least, so long as it's not a subshell - these runtime checks are
-- pretty hokey).  Note that 'Word's inside 'Redir's are never split
-- regardless of the value of @$IFS@.
expand' :: Word -> Shell [Lexeme]
expand' = expandParams <=< expandTilde . toLexemes

expandWord :: Word -> Shell String
expandWord = fmap removeQuotes . expand'

-- |This will share a lot of functionality with @expandWord@...
expandWords :: [Word] -> Shell [String]
expandWords = fmap (map removeQuotes) . (splitFields <=< mapM expand')
              -- should we (dropWhile null) as well?

f <=< g = \a -> g a >>= f
infixr 1 <=<

-- |First step: tilde expansion.
expandTilde :: [Lexeme] -> Shell [Lexeme]
expandTilde w = let (lit,rest) = span isLiteral w
                in case (fromLit lit) of
                     '~':s -> exp s rest
                     _     -> return w
{'fraction_non_alphanumeric': 0.11556409552566566, 'fraction_numerical': 0.0008234971177600879, 'mean_word_length': 2.930960086299892, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4020808', 'n_tokens_mistral': 1114, 'n_tokens_neox': 1071, 'n_words': 406}