Code Monkey home page Code Monkey logo

Comments (8)

qcc-na avatar qcc-na commented on July 30, 2024 4

@Kaligule @simonmichael @jtdaugherty
I'm super late to the party here but I found a way past this for anyone running into this who is willing to use customMain instead of simpleMain. customMain allows you to override the underlying VTY configuration and give it the handle of the controlling terminal even when input originally comes from a pipe.

Reading stdin using getContents will put the handle into a semi closed state. Just read it, then close the handle. After this, using System.Posix.Terminal , you can make a call to getControllingTerminalName then open that descriptor using openFd in the System.Posix.IO.ByteString module, and then pass that descriptor to inputFd on the VTY value passed to customMain.

Here is a crude example that requires the unix, brick, vty, bytestring packages:

You can test this with your shell: $ echo 12345 | YourApp

module Main where

import           Brick
import           Brick.BChan
import           Control.Monad
import qualified Data.ByteString.Char8 as C
import           Graphics.Vty
import           Graphics.Vty.Config
import           System.IO
import           System.Posix.IO.ByteString
import           System.Posix.Terminal
import           System.Posix.Types

data AppState = AppState String
type ResourceName = ()

main :: IO ()
main = do
  stdin' <- getContents
  print stdin' -- no lazy plz
  _ <- hClose stdin
  terminalName <- getControllingTerminalName
  terminalFd <- openFd (C.pack terminalName) ReadOnly Nothing (OpenFileFlags False False False False False)
  channel <- newBChan 1000
  initialVty <- buildVty terminalFd
  _          <- customMain initialVty (buildVty terminalFd) (Just channel) app (AppState stdin')
  return ()
  where
    buildVty :: Fd -> IO Vty
    buildVty terminalFd' = do
          vtyCfg <- standardIOConfig
          v      <- mkVty $ vtyCfg { inputFd = Just terminalFd' }
          when (supportsMode (outputIface v) Mouse) $ setMode (outputIface v) Mouse True
          when (supportsMode (outputIface v) BracketedPaste) $ setMode (outputIface v) BracketedPaste True
          return v

app :: App AppState e ResourceName
app = App draw neverShowCursor handleEvent startEvent attributeMap

draw :: AppState -> [Widget ResourceName]
draw (AppState stdin) = [ str stdin ]

handleEvent :: AppState -> BrickEvent ResourceName e -> EventM ResourceName (Next AppState)
handleEvent s e = continue s

startEvent :: AppState -> EventM ResourceName AppState
startEvent = return

attributeMap :: AppState -> AttrMap
attributeMap = const $ attrMap Graphics.Vty.defAttr []

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

I think the issue here is that invoking a program with standard input from the terminal is not the same as invoking a program with a pipe redirection. In the former case, stdin is a file descriptor from the terminal that supports different ioctl system calls (such as the ones needed by vty), while the file descriptor opened by the shell for the pipe redirection is not a terminal device and will not support the same ioctl operations. In the redirection case you get the error about an unsupported ioctl as a result.

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

Here is something that sheds a little light on what I'm talking about:

http://unix.stackexchange.com/questions/68712/how-to-detect-if-a-program-is-not-run-from-a-terminal

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

Here's another:

http://unix.stackexchange.com/questions/157852/echo-test-stty-echo-stty-standard-input-inappropriate-ioctl-for-device

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

So, to sum up: this isn't a vty or brick problem; it's purely a consequence of using a pipe where none should be used because vty (and therefore brick) programs expect stdin to be a terminal.

from brick.

Kaligule avatar Kaligule commented on July 30, 2024

I see that this sort of thing could happen in a nonpure world of bash. Thanks for pointing that out. I am going to search for a workaround.

from brick.

simonmichael avatar simonmichael commented on July 30, 2024

@Kaligule did you find a workaround ? We'd like to make this work:

$ cat some.file | hledger-ui -f-   # 1. take initial input from stdin
# 2. continue in normal interactive mode

I guess some shuffling of handles could do it.

from brick.

Kaligule avatar Kaligule commented on July 30, 2024

@simonmichael I never found a way to make it work, sorry.

from brick.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.