0

I am trying to recreate the functionality of the very old conque plugin via terminal in modern vim. So far I have found a few plugins that send code to a terminal buffer. However, these do not update the display in the terminal buffer (and does not match conque's behaviour). What I want is a way to script the following:

  1. call term_sendkeys to send some code to the terminal buffer. (existing plugins already do this).
  2. change focus to the terminal buffer so that the sent code renders in that window. (this part I do not know how to do.)

Any hints? I believe I can get the job number of the terminal buffer from term_getjob, but then I am at a loss.

3
  • I thing the solution very if you are using Vim or Neovim. Could you tell us which one your are using? May 9, 2023 at 2:54
  • 1
    I am using vim, version 9.
    – shabbychef
    May 9, 2023 at 3:40
  • Is one of the answer solving your problem? If not, how can we help you further? Otherwise maybe could you accept one of the solution using the v button next to the arrow voting buttons. It allow the question to rest :-) May 11, 2023 at 15:18

3 Answers 3

1

I would do:

function! MoveFocusToTerminal()
  let loop = 0
  let term_buffers = term_list()
  while 1
    let loop = loop + 1
    let bufnr = bufnr('%')
    if loop > 10
      " Don't search for more than 10 windows
      " To handle the case where there are no terminal window
      break
    endif
    if index(term_buffers, bufnr) >= 0
      " Stop if the corresponding buffer is a terminal buffer
      break
    endif
    " Go to the next window
    wincmd w
  endwhile
endfunction
2
  • 1
    This almost works. I found I have to add exec 'normal! i' after wincmd w to enter terminal-job mode in the window.
    – shabbychef
    May 9, 2023 at 22:53
  • Thanks for the feedback. The intention of the function is indeed to move the focus. To pass terminal command you have indeed to switch to insert mode. But the solution of @Chrstian looks simpler to me ;-) May 10, 2023 at 3:43
3

I might misunderstand the question, but you can simply switch to a particular window using the normal window-move commands.

So if your terminal is in the second window (starting from top to bottom and left to right), simply pressing CTRL-W 2 w should move your cursor directly there.

You can also script it like this:

exe term_list()[0]->bufwinnr() .. 'wincmd w'

This assumes that you have at least one terminal window open.

1
  • This looks like it might work, but I only have baby brain understanding of vimscript and would have problems integrating it. Will experiment.
    – shabbychef
    May 14, 2023 at 22:19
1

Building on the previous answers I would do:

function! TerminalFocus()
    let l:term_bufs = term_list()
    if len(term_bufs) > 0 && len(win_findbuf(term_bufs[0])) > 0
        return ':' . win_id2win(win_findbuf(term_bufs[0])[0]) . 'wincmd w' . "\<CR>"
    endif
    return
endfunction

nnoremap <expr> <YOUR_MAPPING> TerminalFocus()

This function first fetches current terminal processes and then checks if there any. Then move to the window by converting the bufnr from the first element in term_list() to a window id by win_findbuf() and converting this window id to a window by win_id2win(). This will always move the focus to the first terminal in term_list(). Then the function is called via a mapping, if you so wish.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.