monsanto / readline-complete.el

autocomplete in shell mode buffers
67 stars 16 forks source link

Does it work with `term` (or multi-term)? #5

Closed Silex closed 10 years ago

Silex commented 10 years ago

Hello,

Do you know if we can make this work with M-x multi-term? I recently discovered it and so far it looks more powerful than shell and it seems without drawbacks. I can already tab complete the bash completions so it shouldn't be too to hard I guess.

monsanto commented 10 years ago

term does have some drawbacks compared to shell. The primary one is that the editing functionality will be provided via readline, not emacs. You might not notice at first because readline provides Emacs emulation, but if you try to do more advanced editing you'll bump into a wall. For example I use paredit religiously; that kind of editing is unavailable outside of shell or term-line-mode (which is basically shell). That being said I use term all the time. It's great.

As for your question, yes, you can make it work with term--the term and shell modes are actually very closely related. The actual readline parser shouldn't interfere with term-mode, your primary problem will be with input handling.

term works by intercepting each keypress and sending it to the buffer's associated process. Compare this to shell, where (most) keypresses instead modify the Emacs buffer, and data is only sent to the associated process on RET.

First, you'll need to set up a keybinding to activate completions. The keymap you're interested in is term-raw-map. Bind some key to (auto-complete) (or whatever completion engine you use).

Second, you'll need to add a post-completion hook to whatever completion engine you're using. Auto-complete works by modifying the current buffer with completions. This is fine for shell, but not for term. Therefore you need a hook that says "don't add the completion to the buffer, instead use term-send-string"

Make sense? If you get this to work, feel free to send a patch my way.

Silex commented 10 years ago

Very interesting! Thanks for the detailed answer, I'll see if I can hack something.

This raised a few more questions tho:

  1. How do you use paredit in shell? I thought paredit was for parenthesis, and when I looked it looked great but only useful for lisp languages. I'd like to use if it was somewhat "generic" (C++/Ruby/Lisp). I know magnars is doing some paredit for js2-mode.
  2. Can you describe a bit when do you use term and when you use shell? I'm currently doing a bit of research and I found several great things, especially reguarding TRAMP:
    1. I can make term automatically setup TRAMP connection when I log on a remote box with ssh. Meaning I just use term like a console, and I ssh left and right, and when I need to open a file I just C-x C-f and open it. The shell alternative requires me to first open a TRAMP connection to open a file, then M-x shell, and then sometimes shell isn't powerful enough (e.g running vim on the remote box). That's what I use currently and it's ok but it's less natural in the sysadmin sense.
    2. I can setup TRAMP in a way so I can do this inside a shell/term remote buffer: EDITOR=somemagic crontab -e and it opens the crontab buffer through TRAMP inside my local emacs. I can actually do this inside an ssh session inside xterm too. This not really related to the shell/term discussion but it somewhat affects it.

Ideally I'd like to use only one of term/shell to have a consistent experience. I also considered eshell but I feel it's just not good enough for basic stuffs like input redirection.

monsanto commented 10 years ago

Hey @Silex, sorry for not responding. I meant to reply to this when I saw it but got sidetracked with something else.

1) Not sure what you mean by "how". I do use a modified version of paredit in shell, and it is for parentheses. I like the advanced sexp/paren manipulation when I'm working with CLI REPLs, or if I'm passing JSON to commands, etc, etc. Unfortunately I can't give you much guidance here on how to set it up for yourself as I am strapped for time these days.

2) I use term when I want to use the native interface presented by whatever command I'm using, shell otherwise. I actually switch between them in the same buffer. If you want to play with that behavior read up on term-char-mode and term-line-mode. As for TRAMP, it isn't necessary to open a file first before opening the shell to get that behavior, but I remember coding up a few hacks to make it work. To be honest I don't even remember what shell mode is like out of the box, I have been using Emacs for a decade or so, and have customized and tweaked many things.

Silex commented 10 years ago

Alright, no worries. My main question about paredit was for other stuffs than parentheses, like curly braces or brackets. I don't want to be proficient in parenthesis languages but a turtle in curly-braces languages... I want to be fast in both :)

Anyway, thanks for the answer!