7

Eg. when you're running nice things like Perl or Ruby REPLs, you have code/command completion exposed via GNU Readline. What I want to do is set some elisp/env variable when entering/exiting such a program to indicate that I want shell-mode to pass the TAB key onto those programs.

Note that C-q TAB also does not work, so I think that Readline is also ignoring it because TERM=dumb, but setting it to eg. vt100 also doesn't do the trick, so it might even be looking at EMACS=t.

Stefan
  • 26,154
  • 3
  • 46
  • 84
Mark
  • 1,409
  • 1
  • 15
  • 20
  • 3
    Comint doesn't work that way. It waits for a line to be sent with `RET`, then receives output until it recognizes a prompt. Completion must therefore be solved on its side. – wasamasa Feb 01 '16 at 06:22
  • Take a look at [ESS](http://ess.r-project.org/), or [grass-mode](https://bitbucket.org/tws/grass-mode.el/wiki/Home) to see how completion is handled directly in elisp on the Emacs side, rather than by relying on readline. – Tyler Feb 01 '16 at 13:23
  • This would be also useful to Prolog mode, where pressing tab is supposed to prompt the interpreter to generate next solution. – wvxvw Feb 01 '16 at 15:28
  • @Tyler the thing is where the knowledge exists elsewhere (eg. in a running interpreter). I guess I could make some sort of readline proxy that could have completion delegated to it from lisp - seems like a lot of work :) – Mark Feb 02 '16 at 00:37
  • @MarkAufflick ESS does something like that I think, with most completions provided via elisp, but some special cases/situations passed to the R process. The special cases can result in painfully slow completions. – Tyler Feb 02 '16 at 01:23
  • The various `comint-send-*` functions allow you to send input to the process. You could certainly write a command which would send the input you wanted, and bind that to TAB. Whether you'd get back the output you want in a form that was usable is another question, but you might as well try it and see what happens. – phils Sep 26 '18 at 02:45
  • python.el uses readline for completion when "native completion" is enabled, though this does require some setup on the python side. And it doesn't work on w32 (due to lack of pty). – npostavs Sep 26 '18 at 12:10

2 Answers2

2

M-x shell works line-at-a-time. It passes a line of input to the external shell process when you press Ret key.

M-x term passes every keystroke to the external shell process, with the exceptions of C-c and I think Esc. When you press Tab it will be seen and interpreted by the external shell process.

user20119
  • 21
  • 4
2

As @user20119 pointed out, M-x term might be a good option: it also supports dynamically switching to "line mode" which is somewhat similar to what you get with M-x shell.

M-x eshell also tries to give you a mix of the two behaviors.

I'll also point out that C-q TAB didn't work because all it does is to insert a TAB character in the buffer (rather than sending a TAB to the sub-process). Furthermore, just sending a TAB char to the underlying process wouldn't be sufficient, because the text on the current line hasn't yet been sent to the process, so you might need something like:

(defun my-comint-tab ()
  (interactive)
  (let* ((proc (get-buffer-process (current-buffer)))
         (str (buffer-substring (process-mark proc) (point))))
    (process-send-string proc (concat str "\t"))))

and indeed you'll probably also need to convince M-x shell to use a different setting for $TERM.

Stefan
  • 26,154
  • 3
  • 46
  • 84