More things

This commit is contained in:
Daniel Harvey 2020-02-20 08:02:22 +00:00
parent 1963e77dc2
commit e2f1195f8b
5 changed files with 150 additions and 52 deletions

View File

@ -8,6 +8,7 @@ module TmuxMate
createWindowPanes,
removeWindowPanes,
removeWindows,
attachToSession,
)
where
@ -21,38 +22,35 @@ import TmuxMate.Commands
import TmuxMate.Running
import TmuxMate.Types
getCommands :: Session -> [Running] -> [Command]
getCommands sesh running =
concatMap createActualCommand (getTmuxCommands sesh running)
getCommands :: [TmuxCommand] -> [Command]
getCommands =
concatMap createActualCommand
getTmuxCommands :: Session -> [Running] -> [TmuxCommand]
getTmuxCommands sesh running =
maybeToList (createSession (sessionTitle sesh) running)
<> ( concatMap
(maybeToList . createWindow (sessionTitle sesh) running)
(windowTitle <$> sessionWindows sesh)
)
<> ( concatMap
(createWindowPanes (sessionTitle sesh) running)
(sessionWindows sesh)
)
<> (removeWindowPanes (sessionTitle sesh) running (sessionWindows sesh))
<> (removeWindows (sessionTitle sesh) running (sessionWindows sesh))
where
{-startSession isNewSession (sessionTitle sesh)
<> concatMap (addPane (sessionTitle sesh)) filteredPanes
<> concatMap (removePane (sessionTitle sesh)) filteredRunning
<> attach isNewSession (sessionTitle sesh)-}
{-filteredPanes =
filterPanes (sessionTitle sesh) running (sessionPanes sesh)
filteredRunning =
filterRunning (sessionTitle sesh) (sessionPanes sesh) running
isNewSession =
if length running > 0
then IsOldSession
else IsNewSession-}
getTmuxCommands :: Session -> TmuxState -> [TmuxCommand]
getTmuxCommands sesh tmuxState =
let runningPanes =
running tmuxState
runningSessions =
sessions tmuxState
runningInTmux =
inSession tmuxState
sTitle =
sessionTitle sesh
sWindows =
sessionWindows sesh
in (createSession runningInTmux sTitle runningSessions)
<> ( concatMap
(maybeToList . createWindow sTitle runningPanes)
(windowTitle <$> sWindows)
)
<> ( concatMap
(createWindowPanes sTitle runningPanes)
(sessionWindows sesh)
)
<> (removeWindowPanes sTitle runningPanes sWindows)
<> (removeWindows sTitle runningPanes sWindows)
<> (removeAdminPane sTitle)
<> (attachToSession runningInTmux sTitle runningSessions)
runCommands :: [Command] -> IO ()
runCommands =
@ -73,20 +71,32 @@ testSession =
Pane (PaneCommand "yes 'Pane 3'") (PaneTitle "Three"),
Pane (PaneCommand "yes 'Pane 4'") (PaneTitle "Four")
]
},
Window
{ windowTitle = WindowName "second-window",
windowPanes =
[ Pane (PaneCommand "yes 'Second Window - Pane 1'") (PaneTitle "2One"),
Pane (PaneCommand "yes 'Second Window - Pane 2'") (PaneTitle "2Two"),
Pane (PaneCommand "yes 'Second Window - Pane 3'") (PaneTitle "2Three"),
Pane (PaneCommand "yes 'Second Window - Pane 4'") (PaneTitle "2Four")
]
}
]
}
-- create a new session if required
createSession :: SessionName -> [Running] -> Maybe TmuxCommand
createSession seshName running =
if sessionExists seshName running
then Nothing
else Just (NewSession seshName)
createSession :: InTmuxSession -> SessionName -> [SessionName] -> [TmuxCommand]
createSession inTmux seshName runningSessions =
if sessionExists seshName runningSessions
then case inTmux of
InTmuxSession _ -> [SwitchToSession seshName]
NotInTmuxSession -> []
else case inTmux of
InTmuxSession _ -> [NewSession seshName, SwitchToSession seshName]
NotInTmuxSession -> [NewSession seshName]
sessionExists :: SessionName -> [Running] -> Bool
sessionExists seshName running =
length (filter (\a -> sessionName a == seshName) running) > 0
sessionExists :: SessionName -> [SessionName] -> Bool
sessionExists = elem
-- do we need to create this window?
createWindow :: SessionName -> [Running] -> WindowName -> Maybe TmuxCommand
@ -186,12 +196,17 @@ removeWindows seshName running windows =
nub $ windowName <$> filter (\(Running sesh' win' _ _) -> sesh' == seshName) running
--- attaching or switching to session
-- if the stuff we've made is running, switch to it
-- attach sometimes?
attachToSession :: InTmuxSession -> SessionName -> [SessionName] -> [TmuxCommand]
attachToSession inTmux seshName runningSessions =
case inTmux of
InTmuxSession sesh -> [SwitchToSession sesh]
_ -> [AttachToSession seshName]
-- remove admin window (always)
removeAdminPane :: SessionName -> [TmuxCommand]
removeAdminPane seshName = pure (KillAdminPane seshName)
---- load dhall file and let's get cracking
loadTestSession :: FilePath -> IO ()
@ -199,10 +214,12 @@ loadTestSession path = do
--let (decoder :: Dhall.Decoder Session) = Dhall.auto
--- config <- Dhall.inputFile decoder path
let config = testSession
running <- askRunning (sessionTitle config)
print running
let tmuxCommands = getTmuxCommands config running
tmuxState <- askTmuxState (sessionTitle config)
print tmuxState
let tmuxCommands = getTmuxCommands config tmuxState
putStrLn "Tmux Commands"
print tmuxCommands
let commands = (getCommands config running)
let commands = getCommands tmuxCommands
putStrLn "Shell commands"
print commands
runCommands commands

View File

@ -18,7 +18,9 @@ createActualCommand (CreateAdminPane (SessionName seshName)) =
createActualCommand (KillAdminPane seshName) =
pure $ sendKeys seshName "exit"
createActualCommand (CreatePane seshName winName cmd) =
pure $ sendKeys seshName ("tmux split-window -h -d " <> (getCommand cmd))
[ Command $ "tmux select-window -t '" <> (getWindowName winName) <> "'",
sendKeys seshName ("tmux split-window -h -d " <> (getCommand cmd))
]
createActualCommand (KillPane seshName index) =
pure $ sendKeys seshName ("tmux kill-pane -t " <> show index)
createActualCommand (AttachToSession (SessionName seshName)) =
@ -30,4 +32,4 @@ createActualCommand (KillSession (SessionName seshName)) =
createActualCommand (NewSession (SessionName seshName)) =
pure $ Command $ "tmux new-session -d -s " <> seshName
createActualCommand (CreateWindow (SessionName seshName) (WindowName winName)) =
pure $ Command $ "tmux new-window -n '" <> seshName <> "'"
pure $ Command $ "tmux new-window -n '" <> winName <> "'"

View File

@ -5,10 +5,30 @@ module TmuxMate.Running where
import Control.Exception
import Data.List (intercalate, isPrefixOf)
import Data.Maybe (catMaybes, listToMaybe)
import System.Environment
import System.Process
import Text.Read
import TmuxMate.Types
buildTmuxState :: SessionName -> IO TmuxState
buildTmuxState seshName = do
sessions <- askRunningSessions
running <- askRunning seshName
inTmux <- askIfWeAreInTmux
pure $ TmuxState inTmux running sessions
askTmuxState :: SessionName -> IO TmuxState
askTmuxState seshName =
catch
(buildTmuxState seshName)
(\(e :: IOError) -> pure def)
where
def = TmuxState
{ inSession = NotInTmuxSession,
running = mempty,
sessions = mempty
}
-- "foo:yes Pane 2\nfoo:yes Pane 1\n"
askRunning :: SessionName -> IO [Running]
@ -23,6 +43,36 @@ readTmuxProcess =
(shell "tmux list-pane -as -F '#{session_name}:#{window_name}:#{pane_index}:#{pane_start_command}'")
""
-- "foo/npoo/n0/n"
askRunningSessions :: IO [SessionName]
askRunningSessions = do
str <- catch readTmuxSessions (\(e :: IOError) -> pure "")
pure $ SessionName <$> lines str
readTmuxSessions :: IO String
readTmuxSessions =
readCreateProcess
(shell "tmux list-sessions -F '#{session_name}'")
""
-- are we currently in a tmux session? (if so, don't nest)
askIfWeAreInTmux :: IO InTmuxSession
askIfWeAreInTmux = do
tmuxEnv <- lookupEnv "TMUX"
seshName <- askCurrentSessionName
case tmuxEnv of
Nothing -> pure NotInTmuxSession
Just "" -> pure NotInTmuxSession
Just a -> pure $ InTmuxSession seshName
askCurrentSessionName :: IO SessionName
askCurrentSessionName =
SessionName
<$> readCreateProcess
(shell "tmux display-message -p '#S'")
""
-- stop unrequired
removeQuotes :: PaneCommand -> PaneCommand

View File

@ -8,6 +8,19 @@ module TmuxMate.Types where
import Dhall (Decoder, FromDhall, ToDhall, autoWith)
import GHC.Generics
data InTmuxSession
= InTmuxSession SessionName
| NotInTmuxSession
deriving (Eq, Ord, Show)
data TmuxState
= TmuxState
{ inSession :: InTmuxSession,
running :: [Running],
sessions :: [SessionName]
}
deriving (Eq, Ord, Show)
data IsNewSession
= IsNewSession
| IsOldSession

View File

@ -10,6 +10,7 @@ import TmuxMate
import TmuxMate.Running
import TmuxMate.Types
( Command (..),
InTmuxSession (..),
Pane (..),
PaneCommand (..),
Running (..),
@ -24,15 +25,23 @@ main = hspec $ do
describe "createSession" $ do
it "Creates a session if needed" $ do
createSession
( InTmuxSession
(SessionName "horses")
)
(SessionName "horses")
[]
`shouldBe` Just
(NewSession (SessionName "horses"))
`shouldBe` [ NewSession (SessionName "horses"),
SwitchToSession (SessionName "horses")
]
it "Creates a session but does not switch to it if we're outside tmux" $ do
createSession NotInTmuxSession (SessionName "horses") []
`shouldBe` [NewSession (SessionName "horses")]
it "Does nothing if one already exists" $ do
createSession
(InTmuxSession (SessionName "horses"))
(SessionName "horses")
[Running (SessionName "horses") undefined undefined 0]
`shouldBe` Nothing
[SessionName "horses"]
`shouldBe` [SwitchToSession (SessionName "horses")]
describe "createWindow" $ do
it "Creates a window if needed" $ do
createWindow
@ -126,6 +135,13 @@ main = hspec $ do
)
]
`shouldBe` [KillWindow (SessionName "horses") (WindowName "window2")]
describe "attachToSession" $ do
it "Attaches to new session if just created" $ do
attachToSession NotInTmuxSession (SessionName "new-session") []
`shouldBe` [AttachToSession (SessionName "new-session")]
it "Switches back to old session if we're already in tmux" $ do
attachToSession (InTmuxSession (SessionName "old-session")) (SessionName "new-session") []
`shouldBe` [SwitchToSession (SessionName "old-session")]
describe "ParseRunning" $ do
it "Rejects nonsense" $ do
parseSingle "sdfdsf" `shouldBe` Nothing