Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to configure terminal to change behaviour on calling executable... #216

Open
mgajda opened this issue Oct 12, 2022 · 1 comment
Open
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@mgajda
Copy link

mgajda commented Oct 12, 2022

It would be nice to change behaviour when a different executable is called:

  1. When ssh is called to another machine, add options for SSH out-of-band commands (copy file, open remote port etc.)
  2. When vim is called, add an option to open the same local file in another window, or show URL of the file.
  3. When launching a command supporting xterm-256color (like Vim, or CLI output colorizer), switch TERMINFO to xterm-256color or better.
  4. When serial console is open (/dev/ttyUSB*), limit TERMINFO to barebones.

Many of the shells and commands simply set terminal name using special characters, so one could add a hook
that recognizes the name by a regex.
That would be a hook from Name -> ... -> IO Terminal.

Some other shells use a command sequence to find terminal name, we could try to react to this detection, and leave it to the user to choose TERMINFO and switch it.

Related to #215

@cdepillabout
Copy link
Owner

When ssh is called to another machine, add options for SSH out-of-band commands (copy file, open remote port etc.)

Let me make sure I understand what you're suggesting. So, when you run Termonad, initially bash is run, and then within bash, if you run the ssh command, you'd like additional MenuBar options to be available to run SSH out-of-band commands?

That would be really neat.

One problem is that Termonad is just using VTE for the actual terminal emulator, so VTE may not expose all the functionality that would be needed to implement this. Here's the code in Termonad related to VTE:

https://github.com/cdepillabout/termonad/blob/e47d4b2cfe87849c03f327a4befb962dc5614b43/src/Termonad/Term.hs

It is mostly driven by this function:

-- | Create a new 'TMTerm', setting it up and adding it to the GTKNotebook.
createTerm
:: (TMState -> EventKey -> IO Bool)
-- ^ Funtion for handling key presses on the terminal.
-> TMState
-> IO TMTerm
createTerm handleKeyPress mvarTMState = do
-- Check preconditions
assertInvariantTMState mvarTMState
-- Read needed data in TMVar
TMState{tmStateAppWin, tmStateFontDesc, tmStateConfig, tmStateNotebook=currNote} <-
readMVar mvarTMState
-- Create a new terminal and launch a shell in it
vteTerm <- createAndInitVteTerm tmStateFontDesc (options tmStateConfig)
maybeCurrDir <- getCWDFromFocusedTab currNote
termShellPid <- launchShell vteTerm maybeCurrDir
tmTerm <- newTMTerm vteTerm termShellPid
-- Create the container add the VTE term in it
scrolledWin <- createScrolledWin mvarTMState
containerAdd scrolledWin vteTerm
-- Create the GTK widget for the Notebook tab
(tabLabelBox, tabLabel, tabCloseButton) <- createNotebookTabLabel
-- Create notebook state
let notebookTab = createTMNotebookTab tabLabel scrolledWin tmTerm
-- Add the new notebooktab to the notebook.
addPage mvarTMState notebookTab tabLabelBox
-- Setup the initial label for the notebook tab. This needs to happen
-- after we add the new page to the notebook, so that the page can get labelled
-- appropriately.
relabelTab (tmNotebook currNote) tabLabel scrolledWin vteTerm
-- Connect callbacks
void $ onButtonClicked tabCloseButton $ termClose notebookTab mvarTMState
void $ onTerminalWindowTitleChanged vteTerm $ do
TMState{tmStateNotebook} <- readMVar mvarTMState
let notebook = tmNotebook tmStateNotebook
relabelTab notebook tabLabel scrolledWin vteTerm
void $ onWidgetKeyPressEvent vteTerm $ handleKeyPress mvarTMState
void $ onWidgetKeyPressEvent scrolledWin $ handleKeyPress mvarTMState
void $ onWidgetButtonPressEvent vteTerm $ handleMousePress vteTerm
void $ onTerminalChildExited vteTerm $ \_ -> termExit notebookTab mvarTMState
-- Put the keyboard focus on the term
setFocusOn tmStateAppWin vteTerm
-- Make sure the state is still right
assertInvariantTMState mvarTMState
-- Run user-defined hooks for modifying the newly-created VTE Terminal.
createTermHook (hooks tmStateConfig) mvarTMState vteTerm
pure tmTerm

Here's the Haddocks for the VTE-related functionality:

https://hackage.haskell.org/package/gi-vte-2.91.29/docs/GI-Vte-Objects-Terminal.html

VTE / Termonad definitely has knowledge of the shell you run initially (bash), but I'm not sure how much knowledge they have of the commands you're running within bash. If you want to look through these APIs and try to figure something out, I'd really appreciate a PR.

Many of the shells and commands simply set terminal name using special characters, so one could add a hook
that recognizes the name by a regex.

If I remember off the top of my head, there is some functionality in VTE to pick up on the ANSI escape sequences to set window titles, but I don't quite remember how that works without digging into the code, or if you'd be able to hook into that functionality.

@cdepillabout cdepillabout added enhancement New feature or request help wanted Extra attention is needed labels Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants