purebred-0.1.0.0: An mail user agent built around notmuch

Safe HaskellNone
LanguageHaskell2010

Purebred

Description

To customise purebred configuration, create ~/.config/purebred/purebred.hs and change the default config to your liking. For example, the following configuration adds some custom keybindings:

import Data.Semigroup ((<>))
import Purebred

scrollKeybindings :: (Scrollable w) => [Keybinding v w]
scrollKeybindings =
  [ Keybinding (EvKey (KChar j) []) (scrollDown `chain` continue)
  , Keybinding (EvKey (KChar k) []) (scrollUp `chain` continue)
  , Keybinding (EvKey (KChar d) []) (scrollPageDown `chain` continue)
  , Keybinding (EvKey (KChar u) []) (scrollPageUp `chain` continue)
  ]

mailViewKeybindings =
  [ Keybinding (EvKey (KChar J) []) (listDown `chain'` displayMail `chain` continue)
  , Keybinding (EvKey (KChar K) []) (listUp `chain'` displayMail `chain` continue)
  , Keybinding (EvKey (KChar G) []) (listJumpToEnd `chain` continue)
  , Keybinding (EvKey (KChar g) []) (listJumpToStart `chain` continue)
  ]
  <> scrollKeybindings

main = purebred $ tweak defaultConfig where
  tweak =
    over (confMailView . mvKeybindings) (mailViewKeybindings <>)
    . over (confHelpView . hvKeybindings) (scrollKeybindings <>)

The invoke the program, just run purebred:

But if recompilation is needed and you used stack to build and install the program, it will not be able to find the libraries:

ftweedal% purebred
Configuration '/home/ftweedal/.config/purebred/purebred.hs' changed. Recompiling.
Error occurred while loading configuration file.
Launching custom binary /home/ftweedal/.cache/purebred/purebred-linux-x86_64

purebred-linux-x86_64: 
/home/ftweedal/.config/purebred/purebred.hs:4:1: error:
    Could not find module ‘Purebred’
    Use -v to see a list of the files searched for.
  |
4 | import Purebred
  | ^^^^^^^^^^^^^^^

CallStack (from HasCallStack):
  error, called at src/Purebred.hs:205:32 in purebred-0.1.0.0-8yyFpK6IBghCAYUvNAhJRk:Purebred

To avoid this, don't use stack. But if you insist, you can run stack exec purebred from the source tree.

If you want to override the configuration file location, use the PUREBRED_CONFIG_DIR environment variable. The configuration file, located in this directory, must always be name purebred.hs.

The binary is normally cached in ~/.cache/purebred/. If you override the configuration directory, the configuration directory is also used as the cache directory, to avoid clobbering the cached binary for the other configurations.

Synopsis

Documentation

module Types

module UI.Actions

data Event :: * #

Events.

Constructors

EvKey Key [Modifier]

A keyboard key was pressed with the specified modifiers.

EvMouseDown Int Int Button [Modifier]

A mouse button was pressed at the specified column and row. Any modifiers available in the event are also provided.

EvMouseUp Int Int (Maybe Button)

A mouse button was released at the specified column and row. Some terminals report only that a button was released without specifying which one; in that case, Nothing is provided. Otherwise Just the button released is included in the event.

EvResize Int Int

If read from eventChannel this is the size at the time of the signal. If read from nextEvent this is the size at the time the event was processed by Vty. Typically these are the same, but if somebody is resizing the terminal quickly they can be different.

EvPaste ByteString

A paste event occurs when a bracketed paste input sequence is received. For terminals that support bracketed paste mode, these events will be triggered on a paste event. Terminals that do not support bracketed pastes will send the paste contents as ordinary input (which is probably bad, so beware!) Note that the data is provided in raw form and you'll have to decode (e.g. as UTF-8) if that's what your application expects.

EvLostFocus

The terminal running the application lost input focus.

EvGainedFocus

The terminal running the application gained input focus.

Instances

Eq Event 

Methods

(==) :: Event -> Event -> Bool #

(/=) :: Event -> Event -> Bool #

Ord Event 

Methods

compare :: Event -> Event -> Ordering #

(<) :: Event -> Event -> Bool #

(<=) :: Event -> Event -> Bool #

(>) :: Event -> Event -> Bool #

(>=) :: Event -> Event -> Bool #

max :: Event -> Event -> Event #

min :: Event -> Event -> Event #

Read Event 
Show Event 

Methods

showsPrec :: Int -> Event -> ShowS #

show :: Event -> String #

showList :: [Event] -> ShowS #

Generic Event 

Associated Types

type Rep Event :: * -> * #

Methods

from :: Event -> Rep Event x #

to :: Rep Event x -> Event #

type Rep Event 
type Rep Event = D1 * (MetaData "Event" "Graphics.Vty.Input.Events" "vty-5.25.1-JEARZr2LXqdK3hJKzOMFt" False) ((:+:) * ((:+:) * (C1 * (MetaCons "EvKey" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Key)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * [Modifier])))) ((:+:) * (C1 * (MetaCons "EvMouseDown" PrefixI False) ((:*:) * ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int))) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Button)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * [Modifier]))))) (C1 * (MetaCons "EvMouseUp" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int)) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Maybe Button)))))))) ((:+:) * ((:+:) * (C1 * (MetaCons "EvResize" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int)))) (C1 * (MetaCons "EvPaste" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * ByteString)))) ((:+:) * (C1 * (MetaCons "EvLostFocus" PrefixI False) (U1 *)) (C1 * (MetaCons "EvGainedFocus" PrefixI False) (U1 *)))))

data Key :: * #

Representations of non-modifier keys.

  • KFun is indexed from 0 to 63. Range of supported FKeys varies by terminal and keyboard.
  • KUpLeft, KUpRight, KDownLeft, KDownRight, KCenter support varies by terminal and keyboard.
  • Actually, support for most of these but KEsc, KChar, KBS, and KEnter vary by terminal and keyboard.

Instances

Eq Key 

Methods

(==) :: Key -> Key -> Bool #

(/=) :: Key -> Key -> Bool #

Ord Key 

Methods

compare :: Key -> Key -> Ordering #

(<) :: Key -> Key -> Bool #

(<=) :: Key -> Key -> Bool #

(>) :: Key -> Key -> Bool #

(>=) :: Key -> Key -> Bool #

max :: Key -> Key -> Key #

min :: Key -> Key -> Key #

Read Key 
Show Key 

Methods

showsPrec :: Int -> Key -> ShowS #

show :: Key -> String #

showList :: [Key] -> ShowS #

Generic Key 

Associated Types

type Rep Key :: * -> * #

Methods

from :: Key -> Rep Key x #

to :: Rep Key x -> Key #

type Rep Key 
type Rep Key = D1 * (MetaData "Key" "Graphics.Vty.Input.Events" "vty-5.25.1-JEARZr2LXqdK3hJKzOMFt" False) ((:+:) * ((:+:) * ((:+:) * ((:+:) * (C1 * (MetaCons "KEsc" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "KChar" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Char))) (C1 * (MetaCons "KBS" PrefixI False) (U1 *)))) ((:+:) * (C1 * (MetaCons "KEnter" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "KLeft" PrefixI False) (U1 *)) (C1 * (MetaCons "KRight" PrefixI False) (U1 *))))) ((:+:) * ((:+:) * (C1 * (MetaCons "KUp" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "KDown" PrefixI False) (U1 *)) (C1 * (MetaCons "KUpLeft" PrefixI False) (U1 *)))) ((:+:) * (C1 * (MetaCons "KUpRight" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "KDownLeft" PrefixI False) (U1 *)) (C1 * (MetaCons "KDownRight" PrefixI False) (U1 *)))))) ((:+:) * ((:+:) * ((:+:) * (C1 * (MetaCons "KCenter" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "KFun" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int))) (C1 * (MetaCons "KBackTab" PrefixI False) (U1 *)))) ((:+:) * (C1 * (MetaCons "KPrtScr" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "KPause" PrefixI False) (U1 *)) (C1 * (MetaCons "KIns" PrefixI False) (U1 *))))) ((:+:) * ((:+:) * (C1 * (MetaCons "KHome" PrefixI False) (U1 *)) ((:+:) * (C1 * (MetaCons "KPageUp" PrefixI False) (U1 *)) (C1 * (MetaCons "KDel" PrefixI False) (U1 *)))) ((:+:) * ((:+:) * (C1 * (MetaCons "KEnd" PrefixI False) (U1 *)) (C1 * (MetaCons "KPageDown" PrefixI False) (U1 *))) ((:+:) * (C1 * (MetaCons "KBegin" PrefixI False) (U1 *)) (C1 * (MetaCons "KMenu" PrefixI False) (U1 *)))))))

data Modifier :: * #

Modifier keys. Key codes are interpreted such that users are more likely to have Meta than Alt; for instance on the PC Linux console, MMeta will generally correspond to the physical Alt key.

Constructors

MShift 
MCtrl 
MMeta 
MAlt 

Instances

Eq Modifier 
Ord Modifier 
Read Modifier 
Show Modifier 
Generic Modifier 

Associated Types

type Rep Modifier :: * -> * #

Methods

from :: Modifier -> Rep Modifier x #

to :: Rep Modifier x -> Modifier #

type Rep Modifier 
type Rep Modifier = D1 * (MetaData "Modifier" "Graphics.Vty.Input.Events" "vty-5.25.1-JEARZr2LXqdK3hJKzOMFt" False) ((:+:) * ((:+:) * (C1 * (MetaCons "MShift" PrefixI False) (U1 *)) (C1 * (MetaCons "MCtrl" PrefixI False) (U1 *))) ((:+:) * (C1 * (MetaCons "MMeta" PrefixI False) (U1 *)) (C1 * (MetaCons "MAlt" PrefixI False) (U1 *))))

data List n e :: * -> * -> * #

List state. Lists have an element type e that is the data stored by the list. Lists handle the following events by default:

  • Up/down arrow keys: move cursor of selected item
  • Page up / page down keys: move cursor of selected item by one page at a time (based on the number of items shown)
  • Home/end keys: move cursor of selected item to beginning or end of list

Instances

Functor (List n) 

Methods

fmap :: (a -> b) -> List n a -> List n b #

(<$) :: a -> List n b -> List n a #

Foldable (List n) 

Methods

fold :: Monoid m => List n m -> m #

foldMap :: Monoid m => (a -> m) -> List n a -> m #

foldr :: (a -> b -> b) -> b -> List n a -> b #

foldr' :: (a -> b -> b) -> b -> List n a -> b #

foldl :: (b -> a -> b) -> b -> List n a -> b #

foldl' :: (b -> a -> b) -> b -> List n a -> b #

foldr1 :: (a -> a -> a) -> List n a -> a #

foldl1 :: (a -> a -> a) -> List n a -> a #

toList :: List n a -> [a] #

null :: List n a -> Bool #

length :: List n a -> Int #

elem :: Eq a => a -> List n a -> Bool #

maximum :: Ord a => List n a -> a #

minimum :: Ord a => List n a -> a #

sum :: Num a => List n a -> a #

product :: Num a => List n a -> a #

Traversable (List n) 

Methods

traverse :: Applicative f => (a -> f b) -> List n a -> f (List n b) #

sequenceA :: Applicative f => List n (f a) -> f (List n a) #

mapM :: Monad m => (a -> m b) -> List n a -> m (List n b) #

sequence :: Monad m => List n (m a) -> m (List n a) #

(Show n, Show e) => Show (List n e) 

Methods

showsPrec :: Int -> List n e -> ShowS #

show :: List n e -> String #

showList :: [List n e] -> ShowS #

Generic (List n e) 

Associated Types

type Rep (List n e) :: * -> * #

Methods

from :: List n e -> Rep (List n e) x #

to :: Rep (List n e) x -> List n e #

WithContext (List Name (Bool, FileSystemEntry)) Source # 
WithContext (List Name MIMEMessage) Source # 
WithContext (List Name NotmuchThread) Source # 
WithContext (List Name NotmuchMail) Source # 
Named (List n e) n 

Methods

getName :: List n e -> n #

type Rep (List n e) 
type Rep (List n e) = D1 * (MetaData "List" "Brick.Widgets.List" "brick-0.41.5-87zQ1USbBHPKSbVNLiU2sh" False) (C1 * (MetaCons "List" PrefixI True) ((:*:) * ((:*:) * (S1 * (MetaSel (Just Symbol "listElements") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 * (Vector e))) (S1 * (MetaSel (Just Symbol "listSelected") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 * (Maybe Int)))) ((:*:) * (S1 * (MetaSel (Just Symbol "listName") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * n)) (S1 * (MetaSel (Just Symbol "listItemHeight") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Int)))))

data Next a :: * -> * #

The type of actions to take upon completion of an event handler.

Instances

Functor Next 

Methods

fmap :: (a -> b) -> Next a -> Next b #

(<$) :: a -> Next b -> Next a #

(</>) :: FilePath -> FilePath -> FilePath infixr 5 #

Combine two paths with a path separator. If the second path starts with a path separator or a drive letter, then it returns the second. The intention is that readFile (dir </> file) will access the same file as setCurrentDirectory dir; readFile file.

Posix:   "/directory" </> "file.ext" == "/directory/file.ext"
Windows: "/directory" </> "file.ext" == "/directory\\file.ext"
         "directory" </> "/file.ext" == "/file.ext"
Valid x => (takeDirectory x </> takeFileName x) `equalFilePath` x

Combined:

Posix:   "/" </> "test" == "/test"
Posix:   "home" </> "bob" == "home/bob"
Posix:   "x:" </> "foo" == "x:/foo"
Windows: "C:\\foo" </> "bar" == "C:\\foo\\bar"
Windows: "home" </> "bob" == "home\\bob"

Not combined:

Posix:   "home" </> "/bob" == "/bob"
Windows: "home" </> "C:\\bob" == "C:\\bob"

Not combined (tricky):

On Windows, if a filepath starts with a single slash, it is relative to the root of the current drive. In [1], this is (confusingly) referred to as an absolute path. The current behavior of </> is to never combine these forms.

Windows: "home" </> "/bob" == "/bob"
Windows: "home" </> "\\bob" == "\\bob"
Windows: "C:\\home" </> "\\bob" == "\\bob"

On Windows, from [1]: "If a file name begins with only a disk designator but not the backslash after the colon, it is interpreted as a relative path to the current directory on the drive with the specified letter." The current behavior of </> is to never combine these forms.

Windows: "D:\\foo" </> "C:bar" == "C:bar"
Windows: "C:\\foo" </> "C:bar" == "C:bar"

data Mailbox :: * #

Constructors

Mailbox (Maybe Text) AddrSpec 

Instances

Eq Mailbox 

Methods

(==) :: Mailbox -> Mailbox -> Bool #

(/=) :: Mailbox -> Mailbox -> Bool #

Show Mailbox 
Generic Mailbox 

Associated Types

type Rep Mailbox :: * -> * #

Methods

from :: Mailbox -> Rep Mailbox x #

to :: Rep Mailbox x -> Mailbox #

NFData Mailbox 

Methods

rnf :: Mailbox -> () #

type Rep Mailbox 
type Rep Mailbox = D1 * (MetaData "Mailbox" "Data.RFC5322.Address.Types" "purebred-email-0.1.0.0-9nLvUwtPRu9FHNqmt6ZBRM" False) (C1 * (MetaCons "Mailbox" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (Maybe Text))) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * AddrSpec))))

data AddrSpec :: * #

Constructors

AddrSpec ByteString Domain 

Instances

Eq AddrSpec 
Show AddrSpec 
Generic AddrSpec 

Associated Types

type Rep AddrSpec :: * -> * #

Methods

from :: AddrSpec -> Rep AddrSpec x #

to :: Rep AddrSpec x -> AddrSpec #

NFData AddrSpec 

Methods

rnf :: AddrSpec -> () #

type Rep AddrSpec 
type Rep AddrSpec = D1 * (MetaData "AddrSpec" "Data.RFC5322.Address.Types" "purebred-email-0.1.0.0-9nLvUwtPRu9FHNqmt6ZBRM" False) (C1 * (MetaCons "AddrSpec" PrefixI False) ((:*:) * (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * ByteString)) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * Domain))))

data Domain :: * #

Instances

Eq Domain 

Methods

(==) :: Domain -> Domain -> Bool #

(/=) :: Domain -> Domain -> Bool #

Show Domain 
Generic Domain 

Associated Types

type Rep Domain :: * -> * #

Methods

from :: Domain -> Rep Domain x #

to :: Rep Domain x -> Domain #

NFData Domain 

Methods

rnf :: Domain -> () #

type Rep Domain 
type Rep Domain = D1 * (MetaData "Domain" "Data.RFC5322.Address.Types" "purebred-email-0.1.0.0-9nLvUwtPRu9FHNqmt6ZBRM" False) ((:+:) * (C1 * (MetaCons "DomainDotAtom" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * (NonEmpty ByteString)))) (C1 * (MetaCons "DomainLiteral" PrefixI False) (S1 * (MetaSel (Nothing Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * ByteString))))