Tab completion, rlcompleter in Emacs - emacs

I have a Python program which uses rlcompleter to provide custom Tab-completion. The completion works when it is run under a bash terminal. However, it does not work under emacs, in shell mode, nor in eshell mode.
I noticed that Tab is really bound to completion-at-point, eshell-pcomplete, and so on, so I tried an (insert "\t"), supposing that this would trigger the completion, which I understand happens when the child process reads a "\t" character. But this does not work either. Perhaps input is buffered until a "RET"?
Completion for commands like service, which define their own candidates, does not work as expected either.
How can I access these candidates within Emacs?

Try using M-x ansi-term. I find it behaves a bit more like what I have come to expect from a *nix terminal.

Related

Emacs execute process continuously

There's a way to launch a process(continuously) in emacs?
For example, imagine ruby REPL, I expect launch the command "irb" in emacs and it should be in some some kinda of separated tab or buffer.
For the specific case of REPLs in Spacemacs you can start one for any supported language with SPC m s i then explore SPC m s prefix command for all the commands to interact with the REPL.
M-x shell
irb
This will cover simple use cases. To get previous commands, type M-p and M-n instead of up and down.
You can get a fancier version from #legoscia's link.
Can also do M-! to execute a single shell command and output to a new buffer.

Emacs Comint History: Search Rather Than Navigate One By One

I would like to, after switching to the buffer where I usually run commands, navigate the history by searching it, rather than navigate one-command-at-a-time at the end of the buffer (e.g. C-p).
Basically I would like to "Reverse I-search" the command history at the end of the buffer, rather than search the buffer.
Did anyone code a working solution? Note that I noticed there is a Command History buffer available, but here it is just a bunch of text and it is not grouped well enough I think to use.
As in a terminal, you can use M-r to search backward. It works in comint-mode, but it also work elsewhere, like in M-x (M-xM-rpatternRET).
Yes, with Icicles.
In Icicle mode, command icicle-comint-search is bound to C-c ` in shell buffers. It gives you the behavior you are looking for. It is described here.
It uses only stuff that is in the currently visible history as candidates, however. If you want to access stuff from your history from previous sessions then use command comint-input-ring, bound to C-c TAB, instead. (This is explained in the same doc.)

Get tab completion in custom comint mode

I usually try to start CLI's (might not be defining it properly) using commands like:
(make-comint-in-buffer "PUTTY" nil "./plink.exe" nil "dbserver")
(make-comint-in-buffer "Python" nil "c:/Python26/python.exe" nil "-i")
(make-comint-in-buffer "Python" nil "c:/Python27/python.exe" nil "-i")
(make-comint-in-buffer "git" nil "C:/Program Files (x86)/Git/bin/sh.exe" nil "--login" "-i")
Starting the above specially the first and the last in command prompt provides the facility of tab completion. But in comint-mode I don't seem to get this feature.
Entering tab adds a simple tab character under the point instead of passing it to the process and getting back the completion candidates. comint-dynamic-complete and C-qtab doesn't produce the desired result.
How can I utilize in above said feature in comint-mode running different processes?
Short answer
You need to write your own completion functions inside Emacs. These may pull info in from the external program, but you can't have direct access to the tab-completion provided by python or git etc.
Long answer:
When you run make-comint-in-buffer, you are setting up the most basic setup for interactively sending and receiving data from an external process. Whenever you press enter, Emacs sends the current line to the underlying process, and then prints back the output from the process. The external process doesn't know what you're doing until Emacs sends a full line to it - no single characters are passed directly.
This is different from running the external program directly in a terminal. When you run python in a terminal, it interprets every character as you type it (or at least it can). So when you hit tab it knows to try to complete something. When you run python inside Emacs, Emacs is processing all of your input until you hit enter. Which means when you hit tab, Emacs just inserts a tab character, and python doesn't know to try and complete something.
Emacs can provide tab-completion for comint modes, but you need to build the completion targets on the Emacs side, you can't rely on the native completion of the external program. To get an idea of how this works, take a look at the completion functions in shell.el, which you can open with M-x find-library shell.
This isn't something you can do with a line or two of elisp. It's an important part of major-modes written to interact with external processes - things like ESS for R http://ess.r-project.org/
That said, if you dig into the guts of shell.el you may find enough code you can modify to get you started.

Why does emacs' comint-send-string behave differently in different derived modes?

I've been fooling around with comint-mode lately and I'm noticing some weird behaviors. Its very poorly documented, so I'm wondering if anyone has any insight on this.
In some modes, comint-send-string causes whatever is sent to be inserted into the comint buffer and then sent to the associated process, whereas in others, the input is send directly to the process without being placed into the buffer. For example, do run-python with the new (24.3) python.el and then do (comint-send-string "*Python*" "x=3\n"), the string x=3 is inserted into the buffer and then executed. If you do M-x shell, however, and then (comint-send-string "*shell*" "x=3\n"), no text is inserted into the buffer, the input is simply sent to the shell process directly to be executed.
Does anyone know why this difference in behavior exists or how I can change it?
I observe identical behavior on linux (emacs-version == "24.3.50.7", both GUI and emacs -Q -nw): neither
(comint-send-string "*Python*" "x=3\n")
nor
(comint-send-string "*shell*" "x=3\n")
insert anything in the comint buffer (i.e., the next prompt appears
right after the previous prompt - without even a newline between them).
I eventually figured it out. For some reason the system python on OSX causes this behavior, installing python from homebrew fixed it.

Terminal emacs colors only work with TERM=xterm-256color

I've found that terminal emacs does not render the correct colors unless I explicitly set TERM=xterm-256color. I use gnome-terminal, and from what I understand, TERM should be set to gnome-256color. Similarly, I tend to use tmux a lot, which advises against any TERM setting other than screen-256color. Unfortunately, both of those settings (within their respective context - gnome-terminal or tmux) result in emacs having wrong colors, whereas vim displays colors correctly. However, if I export TERM=xterm-256color, the colors work just fine in emacs.
Can anyone explain what's going on, or offer a solution?
Update
Here's what I'm dealing with:
I can get the colors to look correct in the terminal by adding the following to my init.el:
(defun terminal-init-gnome ()
"Terminal initialization function for gnome-terminal."
;; This is a dirty hack that I accidentally stumbled across:
;; initializing "rxvt" first and _then_ "xterm" seems
;; to make the colors work... although I have no idea why.
(tty-run-terminal-initialization (selected-frame) "rxvt")
(tty-run-terminal-initialization (selected-frame) "xterm"))
This feels really, really wrong though. There has to be a logical explanation for this...
P.S.
I have very little knowledge of terminfo and the precise role that $TERM plays in the process of color terminal behavior. If it's safe to always use xterm-256color (even when $TERM "should" be gnome-256color or screen-256color), I'll go with that.
Maybe I'm not understanding something, buy why don't you run emacs like this:
TERM=xterm-256color emacs -nw
This way Emacs has its own TERM setting that you know works. You can also make an alias or wrap this in shell-script.
Terminals are a special type of device. When a process sends special byte sequences (called control sequences) to the terminal, it performs some action (like cursor positioning, change colors, etc).
You can read the ANSI terminal codes to find more detail about control sequences.
But terminals come from 70s, when hardware was limited in its capabilities, and a terminal cannot provide info about its capabilities (ie. which sequences it supports).
$TERM was used to resolve this issue - it allows programs to know what to send to the terminal to get the job done. termcap and terminfo are databases that store info about terminal capabilities for many $TERM names. If your $TERM is not in the db, you must ask an administrator to add it.
All terminal emulators inherit these limitations from old hardware terminals. So they need a properly set $TERM, and the terminfo/termcap DB MUST have data for this terminal. When a virtual terminal starts it sets the $TERM variable for you (and inside programs like bash). If $TERM is not in the terminfo/termcap you can quickly define an alias from $TERM to xterm-256color (you can find examples in the termcap file on how to do that).
This behavior has to do with the logic EMACS uses to determine whether the terminal background is dark or light. Run M-x list-colors-display with TERM set to either xterm-256color or screen-256color and you'll see that the exact same colors are listed. As you pointed out in the comments, the difference in color schemes that you've observed is due to the frame background mode. To see this, with your TERM set to screen-256color, compare the colors in
emacs -Q -nw --eval "(setq frame-background-mode 'light)"
and
emacs -Q -nw --eval "(setq frame-background-mode 'dark)"
The function frame-set-background-mode (in frame.el) checks to see whether the terminal type matches "^\\(xterm\\|\\rxvt\\|dtterm\\|eterm\\)" if it can't deduce the background color otherwise.
Within a running session, you can change the color scheme to 'light by evaluating
(let ((frame-background-mode 'light)) (frame-set-background-mode nil))
I am not that familiar with how emacs handles different terminals exactly. But looking at lisp/term directory in emacs sources, I found out that the existence of a function terminal-init-xxx allows you to add support for different terminals. For example, I've got:
(defun terminal-init-screen ()
"Terminal initialization function for screen."
;; Use the xterm color initialization code.
(xterm-register-default-colors)
(tty-set-up-initial-frame-faces))
in my .emacs, which adds support for screen-256color. You may try defining a similar function for gnome by renaming the above function to terminal-init-gnome.
NOTE: If you are interested, you can try to track down the calls from tty-run-terminal-initialization code. It first gets the terminal type using tty-type function, then looks at certain locations to load a relevant terminal file, then tries to locate the matching terminal-init-xxx function, and finally calls it. It may help you figure out the correct name for gnome-terminal.
It looks like unless your TERM indicates that your terminal has 256 colors, emacs will only use 8. Changing TERM to gnome-256color allowed the color registration functions to work.
There is a way to cheat, after all. When I run gnome-terminal, my terminal is set to xterm by default. Instead of changing TERM variable, it is possible to redirect xterm to another terminal, say, gnome-256color. Simply create the directory $(HOME)/.terminfo/x, then run ln -s /usr/share/terminfo/g/gnome-256color ~/.terminfo/x/xterm. I think this is better than setting TERM manually in .bashrc, because it only redirects a particular terminal to something else. A console login would still leave TERM as linux, and not xterm-256color.
Add this to your ~/.emacs:
(add-to-list 'term-file-aliases
'("st-256color" . "xterm-256color"))
It tells emacs that if it sees TERM=st-256color then it should initialize the terminal as if it had seen TERM=xterm-256color.
Longer answer:
Emacs is showing strange colors because it thinks your terminal can only support 8 colors. In Emacs, run M-x list-colors-display to see the colors it thinks are available. The correct number of colors is detected during terminal-specific initialization. It says, in part:
Each terminal type can have its own Lisp library that Emacs loads when run on that type of terminal.
On my machine, the terminal-specific initialization files are in /usr/local/share/emacs/25.*/lisp/term. It has files for xterm, rxvt, screen, etc. but nothing for st. We need to help Emacs find the right initialization file. The documentation further says:
If there is an entry matching TERM in the term-file-aliases association list, Emacs uses the associated value in place of TERM
So that association list is a recommended way to handle unknown terminals. It works without you having to manually override the TERM environment variable.
On ubuntu 10.04 I too had noticed that running emacs -nw inside byobu/tmux/screen was using different colours from emacs -nw in the regular gnome-terminal.
I found that this is because byobu was setting TERM to screen-bce. Then setting TERM to xterm (for me, in the normal gnome-terminal TERM=xterm) gave me the same syntax highlighting when not running through byobu/screen.
So still not sure what the proper solution is.
See also this post:
Emacs Python-mode syntax highlighting