ribosome-0.9.9.9: lib/Ribosome/Api/Window.hs
-- |API functions for windows.
module Ribosome.Api.Window where
import Ribosome.Data.WindowView (PartialWindowView, WindowView)
import Ribosome.Host.Api.Data (Window)
import Ribosome.Host.Api.Effect (
nvimBufGetOption,
nvimCallFunction,
nvimCommand,
nvimGetCurrentWin,
nvimWinClose,
nvimWinGetBuf,
nvimWinGetCursor,
nvimWinSetCursor,
vimCallFunction,
vimGetWindows,
vimSetCurrentWindow,
windowIsValid,
)
import Ribosome.Host.Class.Msgpack.Encode (toMsgpack)
import Ribosome.Host.Effect.Rpc (Rpc)
import Ribosome.Host.Modify (silentBang)
-- |Close a window if it is valid and not the last one.
closeWindow ::
Member Rpc r =>
Window ->
Sem r ()
closeWindow window = do
valid <- windowIsValid window
last' <- (1 ==) . length <$> vimGetWindows
when (valid && not last') $ nvimWinClose window True
-- |Get the zero-based position of the cursor in a window.
cursor ::
Member Rpc r =>
Window ->
Sem r (Int, Int)
cursor window = do
(line, col) <- nvimWinGetCursor window
pure (line - 1, col)
-- |Get the zero-based position of the cursor in the active window.
currentCursor ::
Member Rpc r =>
Sem r (Int, Int)
currentCursor =
cursor =<< nvimGetCurrentWin
-- |Get the zero-based line number of the cursor in a window.
windowLine ::
Member Rpc r =>
Window ->
Sem r Int
windowLine window =
fst <$> cursor window
-- |Get the zero-based line number of the cursor in the active window.
currentLine ::
Member Rpc r =>
Sem r Int
currentLine =
windowLine =<< nvimGetCurrentWin
-- |Set the zero-based position of the cursor in a window.
setCursor ::
Member Rpc r =>
Window ->
Int ->
Int ->
Sem r ()
setCursor window line col =
nvimWinSetCursor window (line + 1, col)
-- |Set the zero-based position of the cursor in the current window.
setCurrentCursor ::
Member Rpc r =>
Int ->
Int ->
Sem r ()
setCurrentCursor line col = do
window <- nvimGetCurrentWin
setCursor window line col
-- |Set the zero-based line number of the cursor in a window, using the beginning of the line for the column.
setLine ::
Member Rpc r =>
Window ->
Int ->
Sem r ()
setLine window line =
setCursor window line 0
-- |Set the zero-based line number of the cursor in the current window, using the beginning of the line for the column.
setCurrentLine ::
Member Rpc r =>
Int ->
Sem r ()
setCurrentLine line =
setCurrentCursor line 0
-- |Redraw the screen.
redraw ::
Member Rpc r =>
Sem r ()
redraw =
silentBang do
nvimCommand "redraw!"
-- |A main window means here any non-window that may be used to edit a file, i.e. one with an empty @buftype@.
findMainWindow ::
Member Rpc r =>
Sem r (Maybe Window)
findMainWindow =
listToMaybe <$> (filterM isFile =<< vimGetWindows)
where
isFile w = do
buf <- nvimWinGetBuf w
(("" :: Text) ==) <$> nvimBufGetOption buf "buftype"
-- |Create a new window at the top if no existing window has empty @buftype@.
-- Focuses the window.
ensureMainWindow ::
Member Rpc r =>
Sem r Window
ensureMainWindow =
maybe create focus =<< findMainWindow
where
create = do
nvimCommand "aboveleft new"
nvimGetCurrentWin <* nvimCommand "wincmd K"
focus w =
w <$ vimSetCurrentWindow w
-- |Call @winsaveview@.
saveView ::
Member Rpc r =>
Sem r WindowView
saveView =
vimCallFunction "winsaveview" []
-- |Call @winrestview@ with a previously obtained view from 'saveView'.
restoreView ::
Member Rpc r =>
PartialWindowView ->
Sem r ()
restoreView v =
vimCallFunction "winrestview" [toMsgpack v]
-- |Execute a command in a window.
windowExec ::
Member Rpc r =>
Window ->
Text ->
Sem r ()
windowExec window cmd =
nvimCallFunction "win_execute" [toMsgpack window, toMsgpack cmd]