Add Graphics.Vty.Config.getTtyEraseChar

This commit adds getTtyEraseChar. This function queries the kernel
for the current terminal's settings to obtain the character assigned
by the "stty erase" command. The "erase" character indicates which
input character the terminal should interpret to mean "backspace" when
the terminal is in canonical input mode. Vty applications run with
canonical mode disabled, but even in those cases some users may want
their "stty erase" setting honored by Vty's input-handling so that
incoming erase characters (according to stty) result in "KBS" key events
being delivered to the application.
This commit is contained in:
Jonathan Daugherty 2020-02-27 09:43:50 -08:00
parent 0f08358bd3
commit 4362b3cb1c
4 changed files with 44 additions and 0 deletions

18
cbits/get_tty_erase.c Normal file
View File

@ -0,0 +1,18 @@
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
// Given a file descriptor for a terminal, get the ERASE character for
// the terminal. If the terminal info cannot be obtained, this returns
// zero.
char vty_get_tty_erase(int fd)
{
struct termios trm;
if (0 == tcgetattr(fd, &trm)) {
return (char) trm.c_cc[VERASE];
} else {
return (char) 0;
}
}

View File

@ -2,6 +2,8 @@ module Main where
import Control.Applicative
import Data.Monoid
import Foreign.C.Types (CInt(..), CChar(..))
import System.Posix.Types (Fd(..))
import Graphics.Vty

View File

@ -65,6 +65,7 @@ module Graphics.Vty.Config
, runParseConfig
, parseConfigFile
, defaultConfig
, getTtyEraseChar
)
where
@ -92,6 +93,7 @@ import System.Directory (getAppUserDataDirectory)
import System.Environment (lookupEnv)
import System.Posix.IO (stdInput, stdOutput)
import System.Posix.Types (Fd(..))
import Foreign.C.Types (CInt(..), CChar(..))
import Text.Parsec hiding ((<|>))
import Text.Parsec.Token ( GenLanguageDef(..) )
@ -306,3 +308,24 @@ instance (GParseAlts f, GParseAlts g) => GParseAlts (f :+: g) where
gparseAlts con = L1 <$> gparseAlts con <|> R1 <$> gparseAlts con
instance GParseAlts V1 where gparseAlts _ = fail "GParse: V1"
foreign import ccall "vty_get_tty_erase" cGetTtyErase :: Fd -> IO CChar
-- | Get the "erase" character for the terminal attached to the
-- specified file descriptor. This is the character configured by 'stty
-- erase'. If the call to 'tcgetattr' fails, this will return 'Nothing'.
-- Otherwise it will return the character that has been configured to
-- indicate the canonical mode ERASE behavior. That character can then
-- be added to the table of strings that we interpret to mean Backspace.
--
-- For more details, see:
--
-- * https://www.gnu.org/software/libc/manual/html_node/Canonical-or-Not.html
-- * https://www.gsp.com/cgi-bin/man.cgi?section=1&topic=stty
-- * https://github.com/matterhorn-chat/matterhorn/issues/565
getTtyEraseChar :: Fd -> IO (Maybe Char)
getTtyEraseChar fd = do
c <- cGetTtyErase fd
if c /= 0
then return $ Just $ toEnum $ fromEnum c
else return Nothing

View File

@ -106,6 +106,7 @@ library
c-sources: cbits/gwinsz.c
cbits/set_term_timing.c
cbits/get_tty_erase.c
cbits/mk_wcwidth.c
include-dirs: cbits