Shellac 0.9 → 0.9.1
raw patch · 10 files changed
+118/−193 lines, 10 filesdep +directorydep +unixdep ~basedep ~haskell98dep ~mtl
Dependencies added: directory, unix
Dependency ranges changed: base, haskell98, mtl
Files
- LICENSE +0/−1
- README +0/−81
- Shellac.cabal +42/−25
- src/System/Console/Shell.hs +19/−25
- src/System/Console/Shell/Backend.hs +18/−13
- src/System/Console/Shell/Backend/Basic.hs +6/−6
- src/System/Console/Shell/Commands.hs +11/−7
- src/System/Console/Shell/ConsoleHandler.hs +14/−13
- src/System/Console/Shell/ShellMonad.hs +1/−1
- src/System/Console/Shell/Types.hs +7/−21
LICENSE view
@@ -1,6 +1,5 @@ Copyright 2005-2006, Robert Dockins. PPrint library: Copyright 2000, Dan Leijen.-Shell History module: Copyright (C) 2000,2006 Michael Weber All Rights Reserved.
− README
@@ -1,81 +0,0 @@-- Shellac --========================----== What is it?--Shellac is a framework for building read-eval-print style shells. -Shells are created by declaratively defining a set of shell commands-and an evaluation function. Shellac supports multiple shell backends,-including a 'basic' backend which uses only Haskell IO primitives and-a full featured 'readline' backend based on the the Haskell readline-bindings found in the standard libraries.--This library attempts to allow users to write shells at a high level-and still enjoy the advanced features that may be available from a-powerful line editing package like readline.---== Why do I care?--Shellac takes care of much the muckety-muck of writing robust, -feature-full shells so you don't have to.---== How is it licensed?--Shellac is available under a BSD3 license. See the LICENSE file for-details.--Be aware, however, that the GNU readline library itself is-licensed under the GPL. If you wish to use the readline bindings,-your project will need to be GPL compatible.--Go here (http://directory.fsf.org/GNU/readline.html) for more information-about the readline library.---== What about portability?--Currently, Shellac is GHC only. The 0.5 release made significant-efforts toward portability by eliminating dependencies on the GHC-specific features GADTs and STM. However, it still requires-existential types, multi-parameter type classes, functional-dependencies, preemptive concurrency support and the FFI. Currently no-Haskell implementation other than GHC supports all these features.--== How do I build it?--Shellac uses a Cabal build system. The following commands-assume you have a Haskell interpreter in your system-path named 'runhaskell'. All commands are run from-this directory.--To install for the whole system:--runhaskell Setup.hs configure-runhaskell Setup.hs build-runhaskell Setup.hs install--To install for a single user:--runhaskell Setup.hs configure --prefix=/home/<username>-runhaskell Setup.hs build-runhaskell Setup.hs install --user--To build the API docs:--runhaskell Setup.hs haddock---== Why 'Shellac'?--I had to call it something. And it starts with 'shell'.---== Who is responsible for this mess?--You can send bug reports, rants and comments to:-- Robert Dockins <robdockins AT fastmail.fm>
Shellac.cabal view
@@ -1,5 +1,7 @@ Name: Shellac-Version: 0.9+Cabal-Version: >= 1.2+Build-Type: Simple+Version: 0.9.1 License: BSD3 License-File: LICENSE Author: Robert Dockins@@ -7,6 +9,7 @@ Category: User Interfaces Stability: Beta Synopsis: A framework for creating shell envinronments+Homepage: http://www.cs.princeton.edu/~rdockins/shellac/home/ Description: Shellac is a framework for building read-eval-print style shells. Shells are created by declaratively defining a set of shell commands@@ -17,27 +20,41 @@ This library attempts to allow users to write shells at a high level and still enjoy the advanced features that may be available from a powerful line editing package like readline.-Hs-Source-Dirs:- src-Build-Depends:- base >= 1.0,- haskell98 >= 1.0,- mtl >= 1.0-Extensions:- MultiParamTypeClasses- FunctionalDependencies- ExistentialQuantification- CPP- UndecidableInstances-Exposed-modules:- System.Console.Shell- System.Console.Shell.Backend- System.Console.Shell.Backend.Basic- System.Console.Shell.ShellMonad-Other-modules:- System.Console.Shell.Regex- System.Console.Shell.PPrint- System.Console.Shell.Types- System.Console.Shell.RunShell- System.Console.Shell.Commands- System.Console.Shell.ConsoleHandler++Library+ Hs-Source-Dirs:+ src+ Build-Depends:+ base, haskell98, mtl+ Extensions:+ MultiParamTypeClasses+ FunctionalDependencies+ ExistentialQuantification+ CPP+ UndecidableInstances+ GeneralizedNewtypeDeriving+ FlexibleInstances+ ScopedTypeVariables++ if os(windows)+ GHC-Options: -DBUILD_WINDOWS+ else+ if impl( ghc >= 6.8 )+ Build-Depends: unix++ if impl( ghc >= 6.8 )+ Build-Depends: directory+ GHC-Options: -XPatternSignatures++ Exposed-modules:+ System.Console.Shell+ System.Console.Shell.Backend+ System.Console.Shell.Backend.Basic+ System.Console.Shell.ShellMonad+ Other-modules:+ System.Console.Shell.Regex+ System.Console.Shell.PPrint+ System.Console.Shell.Types+ System.Console.Shell.RunShell+ System.Console.Shell.Commands+ System.Console.Shell.ConsoleHandler
src/System/Console/Shell.hs view
@@ -4,23 +4,25 @@ - -} -{- | This module implements a framework for creating read-eval-print style- command shells. Shells are created by declaratively defining evaluation- functions and \"shell commands\". Input is read using a plugable backend.- The shell framework handles command history and word completion if the- backend supports it.-- The basic idea is for creating a shell is:-- (1) Create a list of shell commands and an evaluation function-- (2) Create a shell description (using 'mkShellDescription')-- (3) Set up the initial shell state-- (4) Run the shell (using 'runShell')--}-+-- | This module implements a framework for creating read-eval-print style+-- command shells. Shells are created by declaratively defining evaluation+-- functions and \"shell commands\". Input is read using a pluggable backend.+-- The shell framework handles command history and word completion if the+-- backend supports it.+--+-- The basic idea is for creating a shell is:+--+-- (1) Create a list of shell commands and an evaluation function+--+-- (2) Create a shell description (using 'mkShellDescription')+--+-- (3) Set up the initial shell state+--+-- (4) Run the shell (using 'runShell')+--+--+-- Shell commands and the evaluation function are written in a custom+-- monad. See "System.Console.Shell.ShellMonad" for details on using this monad. module System.Console.Shell ( @@ -52,14 +54,6 @@ -- * Printing Help Messages , showShellHelp , showCmdHelp---- * Generating text output-, shellPutStr-, shellPutStrLn-, shellPutInfo-, shellPutInfoLn-, shellPutErr-, shellPutErrLn -- * Auxiliary Types , CommandStyle (..)
src/System/Console/Shell/Backend.hs view
@@ -4,12 +4,17 @@ - -} -{- | This module defines the Shellac interface for shell backends. A shell backend- is required to provide sensible implementations for 'outputString', 'flushOutput',- 'getSingleChar', 'getInput', and 'getWordBreakChars'. All other operations may - be noops (however, they must not denote bottom!). --}+-- | This module defines the Shellac interface for shell backends. A shell backend+-- is required to provide sensible implementations for 'outputString', 'flushOutput',+-- 'getSingleChar', 'getInput', and 'getWordBreakChars'. All other operations may +-- be noops (however, they must not denote bottom!).+--+-- This module is intended for use by backend implementers. It is not intended to+-- be used by regular clients of the library. The Shellac package provides a+-- basic backend ("System.Console.Shell.Backend.Basic"). More advanced backends+-- are available in separate packages. + module System.Console.Shell.Backend ( CompletionFunction , BackendOutput (..)@@ -28,7 +33,7 @@ -- \'Just (newWord,completions)\' if completions can be generated. \'newWord\' -- is a new string to replace \'word\' on the command line and \'completions\' -- is a list of all possible completions of \'word\'. To achieve the standard--- \"complete-as-far-as-possible\" behavior, \'newWord\' should be the longest possible+-- \"complete-as-far-as-possible\" behavior, \'newWord\' should be the longest common -- prefix of all words in \'completions\'. type CompletionFunction = (String,String,String) @@ -45,7 +50,7 @@ -- | This record type contains all the functions that Shellac allows the pluggable--- backend to provide. Most of these operations are optional andn relate to+-- backend to provide. Most of these operations are optional and relate to -- advanced features like command completion and history. However, a shell backend -- is required to provide sensible implementations for 'outputString', 'flushOutput', -- 'getSingleChar', 'getInput', and 'getWordBreakChars'.@@ -53,7 +58,7 @@ data ShellBackend bst = ShBackend { initBackend :: IO bst- -- ^ Provides the backend a way to perform any necessary initilization+ -- ^ Provides the backend a way to perform any necessary initialization -- before the shell starts. This function is called once for each -- shell instance. The generated value will be passed back in to each call of the -- other methods in this record.@@ -70,10 +75,10 @@ -- operation, the user should be able to view any output sent to this backend. , getSingleChar :: bst -> String -> IO (Maybe Char)- -- ^ Retrive a single character from the user without waiting for carriage return.+ -- ^ Retrieve a single character from the user without waiting for carriage return. , getInput :: bst -> String -> IO (Maybe String)- -- ^ Print the prompt and retrive a line of input from the user.+ -- ^ Print the prompt and retrieve a line of input from the user. , addHistory :: bst -> String -> IO () -- ^ Add a string to the history list.@@ -86,7 +91,7 @@ -- ^ Get the current set of word break characters. , onCancel :: bst -> IO ()- -- ^ A callback to run whenever evaluation or a command is cancled+ -- ^ A callback to run whenever evaluation or a command is canceled -- by the keyboard signal , setAttemptedCompletionFunction :: bst -> CompletionFunction -> IO ()@@ -124,8 +129,8 @@ } -- | Provides a sane default set of characters to use when breaking--- lines into \'words\'. If a backend does not have configuratble--- word break characters, the 'getWordBreakCharacters' can just+-- lines into \'words\'. If a backend does not have configurable+-- word break characters, then 'getWordBreakCharacters' can just -- return this default set. defaultWordBreakChars :: [Char] defaultWordBreakChars = " \t\n\r\v`~!@#$%^&*()=[]{};\\\'\",<>"
src/System/Console/Shell/Backend/Basic.hs view
@@ -5,12 +5,12 @@ -} -{- | This module implements a simple Shellac backend that uses only- the primitaves from "System.IO". It provides no history or- command completion capabilities. You get whatever line editing- capabilities 'hGetLine' has and that's it.--}+-- | This module implements a simple Shellac backend that uses only+-- the primitives from \"System.IO\". It provides no history or+-- command completion capabilities. You get whatever line editing+-- capabilities 'hGetLine' has and that's it. + module System.Console.Shell.Backend.Basic ( basicBackend ) where@@ -27,7 +27,7 @@ basicBackend = ShBackend { initBackend = return () , shutdownBackend = \_ -> return ()- , outputString = \_ -> basicOutput + , outputString = \_ -> basicOutput , flushOutput = \_ -> hFlush stdout , getSingleChar = \_ -> basicGetSingleChar , getInput = \_ -> basicGetInput
src/System/Console/Shell/Commands.hs view
@@ -128,7 +128,7 @@ where doToggle = do st <- getShellSt- if getter st + if getter st then shellPutInfoLn (name++" off") >> putShellSt (setter False st) else shellPutInfoLn (name++" on") >> putShellSt (setter True st) @@ -233,13 +233,17 @@ instance (CommandFunction r st,Completion compl st) => CommandFunction (Completable compl -> r) st where- parseCommand wbc = doParseCommand- (Just (OtherCompleter (complete (undefined::compl))))- (wordRegex wbc)- Completable- wbc- commandSyntax f = text (completableLabel (undefined::compl)) : commandSyntax (f undefined) + parseCommand wbc =+ ( doParseCommand+ (Just (OtherCompleter (complete (undefined::compl))))+ (wordRegex wbc)+ Completable+ wbc+ ) :: (Completable compl -> r) -> CommandParser st++ commandSyntax (f:: (Completable compl -> r)) =+ text (completableLabel (undefined::compl)) : commandSyntax (f undefined) ---------------------------------------------------------------- -- Helper functions used in the above instance declarations
src/System/Console/Shell/ConsoleHandler.hs view
@@ -10,22 +10,12 @@ import qualified Control.Exception as Ex -#ifndef mingw32_HOST_OS--import qualified System.Posix.Signals as PS--withControlCHandler :: IO () -> IO a -> IO a-withControlCHandler hdl m =- Ex.bracket- (PS.installHandler PS.keyboardSignal (PS.Catch hdl) Nothing)- (\oldh -> PS.installHandler PS.keyboardSignal oldh Nothing)- (\_ -> m)--#else+#ifdef BUILD_WINDOWS +-- Windows build, use the GHC console+-- handler module import qualified GHC.ConsoleHandler as CH - handleCtrlC :: IO () -> CH.Handler handleCtrlC hdl = CH.Catch $ \ev -> case ev of@@ -40,5 +30,16 @@ (\oldh -> CH.installHandler oldh) (\_ -> m) +#else++-- not Windows, assume POSIX+import qualified System.Posix.Signals as PS++withControlCHandler :: IO () -> IO a -> IO a+withControlCHandler hdl m =+ Ex.bracket+ (PS.installHandler PS.keyboardSignal (PS.Catch hdl) Nothing)+ (\oldh -> PS.installHandler PS.keyboardSignal oldh Nothing)+ (\_ -> m) #endif
src/System/Console/Shell/ShellMonad.hs view
@@ -42,7 +42,7 @@ shellPut :: BackendOutput -> Sh st () shellPut out = Sh (lift ask >>= \f -> liftIO (f out)) --- | Prints a regular output string with a line terminator+-- | Prints a regular output string shellPutStr :: String -> Sh st () shellPutStr = shellPut . RegularOutput
src/System/Console/Shell/Types.hs view
@@ -20,24 +20,11 @@ data CommandStyle = OnlyCommands -- ^ Indicates that all input is to be interpreted as shell commands; no -- input will be passed to the evaluation function.- | CharPrefixCommands Char -- ^ Indicates that commands are prefixed with a particular character- -- Colon \':\' is the default charcter (a la GHCi).- | SingleCharCommands -- ^ Commands consisit of a single character+ | CharPrefixCommands Char -- ^ Indicates that commands are prefixed with a particular character.+ -- Colon \':\' is the default character (a la GHCi).+ | SingleCharCommands -- ^ Commands consist of a single character. --- | The type of an evaluation function for a shell. The function--- takes three arguments:------ (1) An output function command. Pass this command into 'shellPutStr' --- and friends rather than using 'putStr'.------ (2) The input string------ (3) The current shell state------ Evaluation functions should return the new shell state and--- possibly a shell special action to execute.- data CommandCompleter st = FilenameCompleter | UsernameCompleter@@ -73,8 +60,9 @@ type OutputCommand = BackendOutput -> IO () --- | The type of shell commands. This monad is a stae monad layerd over @IO@. It is--- also a member of 'MonadException' which allows safe exception handling.+-- | The type of shell commands. This monad is a state monad layered over @IO@.+-- The type parameter @st@ allows the monad to carry around a package of+-- user-defined state. newtype Sh st a = Sh { unSh :: StateT (CommandResult st) (ReaderT OutputCommand IO) a } deriving (Monad, MonadIO) @@ -114,7 +102,7 @@ -- -- (2) A function to generate the outer shell state from the final subshell state ----- (3) A function to generate the shell description from the inital subshell state+-- (3) A function to generate the shell description from the initial subshell state type Subshell st st' = (st -> IO st', st' -> IO st, st' -> IO (ShellDescription st') ) @@ -130,5 +118,3 @@ -- be appended to the given string | forall st'. ExecSubshell (Subshell st st') -- ^ Causes the shell to execute a subshell--