history-search-backward with python-prompt-toolkit? - ipython

In ipython 5+, readline behavior has changed significantly from previous versions. Previously, I could type a partial command and press the keyboard up arrow to search backward through history for any command that started with those characters. For example, if I had previously typed:
import blah
import foo
import foo
then typing import ^ (with the carat representing up arrow) would cycle first through import foo, then import blah, with the cursor hovering over the f and the b respectively. import foo would only show up once, i.e., the search was over unique entries.
In ipython 5, the behavior is different, and I don't fully understand what it is doing, but it seems that only some of this behavior is retained. The cursor position changes with each press of the up arrow, and searches are not over unique entries, but it seems that the first characters are still used to initiate the search.
Is there any way to restore the gnu-readline-like history-search-backward functionality?

Related

Odd behavior of 'vi' mode in ipython

I'm trying to understand some annoying behaviour from ipython. I have vi mode enabled, I can confirm this like so;
[ins] In [1]: from IPython import get_ipython
...: ipython = get_ipython()
...: ipython.editing_mode
Out[1]: 'vi'
Mostly it works, but if I hit esc then two other keys in quick succession, only the first of the two is treated as a "normal" mode command ([nav]), the other one gets treated as an insert mode command ([ins]).
For example, say the cursor is at the end of the line
[nav] In [2]: who = ["some", "person"]
and I hit the b key 4 times quickly, the result is
[ins] In [2]: who = ["some", "personbbb"]
so the first press did what I expected, took the cursor back a word. Pressed 2,3 and 4 all acted in insert mode, resulting in "personbbb".
On the other hand, if I hit esc, wait a second or so, and then hit b 4 times I get exactly what I expect
[nav] In [2]: who = ["some", "person"]
and the cursor is by the 'e' in "some".
Hitting esc multiple times also ensures I stay in normal mode properly, no matter how fast I hit keys.
Is this a setting somewhere?
What I've tried
All the sugestions in How do I use vi keys in ipython under *nix? just in case I wasn't setting 'vi' mode properly.
Also updating my ipython, in case it was a bug in this version.
Searching for questions about 'vi' mode in ipython. The one I've just listed is the main thing that comes up, but I'm pretty surprised that this behaviour hasn't been mentioned before?
What I'm using
My zsh version is 5.8.1 (x86_64-apple-darwin21.0).
My ipython version is 8.6.0
My ~/.inputrc has
set editing-mode vi
set keymap vi
My ~/.ipython/profile_default/ipython_config.py has
c.TerminalInteractiveShell.editing_mode = 'vi'
(excluding comments)
I was torn between asking this here, and asking on the macOS stack exchange, because I don't know if this is an ipython issue, or a mac issue. I've only seen it on my mac using zsh.

Is there a way to always stay at the searched-for Symbol location when using vscode and pressing `esc` key?

Let's say I use Go to Symbol in Editor. Let's further say I have a function def run(): (this is Python) that I want to jump to.
If I type #run in the Symbol search dropbox, the viewport will shift to def run in the source code.
So far, so I good. I have found what I want!
At that point, if I press esc I jump back to my starting location, rather than staying at def run() in the source. I have to remember to press Enter to get out of Go to Symbol in Editor... and stay at my location.
How can I make it so esc, by itself, always leaves me where I have found the symbol in the text?
I.e. I want to get more the behavior I get from using Edit, Find where esc leaves at the pattern location. And pressing Enter when in Find mode jumps me to the next pattern hit, if any.
environment: macos, vscode 1.63.2 (latest as of now)
p.s. You also get the same behavior from a Go to Line/Column... dialog, esc will yank you back to your starting point, Enter will leave you at the new location.
I'm afraid it's not currently possible. I've tried to unbind every single keyboard shortcut bound to Escape key so it should basically become a dead key, yet even with this setting symbol suggest highlight were cancelled by pressing the Escape, so no luck.
Unbinding the primary action is normally prerequisite for changing default behaviour -- in your case for mapping it to "accept highlighted symbol" action (which I haven't found either) -- so it seems that Enter/Escape behaviour of symbol palette is not exposed for remapping.

Complete command from history in ipython

For reasons outside of my control I'm stuck using python 2.6.6 and IPython 0.10.2. I also normally use the tcsh shell, and have gotten quite used to completing a command from the history using <A-p> (i.e. pressing the ALT key and p). However, this doesn't work in IPython. I know I can press <C-r> and then start typing a command, but what inevitably is happening is that I start a command, press <A-p>, get a colon indicating some weird state, then exit out of that state, delete my command, press <C-r> then search for my command. It's getting rather irritating. Is there any way to make <A-p> complete my already started command by relying on the history?
Ouch, this is an old version of IPython, Python (and pip). The bad news is I don't have much experience with such an old version of IPython, the good new is; it was way simpler at that time.
Most of the shortcut and feature are provided using readline, and the python bindings of stdlib. Meaning that most likely what you are trying to configure is readline itself and not only IPython; so you can find more information on that outside of IPython !
The secret is to grep in the source-code for parse_and_bind, then you'll find the following example configuration, leading me to change the ~/.ipython/ipy_user_conf.py to be like so at around line 99 (all indented an extra 4 space to be in the main() function):
import readline
readline.parse_and_bind('set completion-query-items 1000')
readline.parse_and_bind('set page-completions no')
rlopts = """\
tab: complete
"\C-l": possible-completions
set show-all-if-ambiguous on
"\C-o": tab-insert
"\M-i": " "
"\M-o": "\d\d\d\d"
"\M-I": "\d\d\d\d"
"\C-r": reverse-search-history
"\C-s": forward-search-history
"\C-p": history-search-backward
"\C-n": history-search-forward
"\e[A": history-search-backward
"\e[B": history-search-forward
"\C-k": kill-line
"\C-u": unix-line-discard"""
for cmd in rlopts.split('\n'):
readline.parse_and_bind(cmd)
The repetition of commands make me think that what \C,\M or [e mean might be system dependant. I would bet on \C being Control, and \M being Meta (Alt, Opt), but at least one of these line did the trick for me (and also now tab allows to complete). See also man readline for the list of commands you can bind to what, and enjoy! Hoping you can upgrade to Python 3 and IPython 6 at some point.
[Edit]
See Eric Carlsen second comment under this answer for how it was resolved.

Emacs ido-mode to insert common block at point

I just started using ido-mode for selecting buffers and files and I am very pleased with it so far. Now I got the idea: It could be nice to use this to insert common blocks of text in the buffer too.
Is this simple to achieve? For example, I imagine that this could be done using
a text file of text blocks (or several files, one for each major mode for example) separated by say "---". For example:
from numpy import *
---
def f():
return
---
import os,sys
---
Then pressing, say F1 would bring up the ido-mode completion buffer, and typing fr would be enough to select the first item from numpy import *, and pressing enter would insert it into the buffer at point.
(Also, to add new blocks to the file of completion blocks, one could imagine selecting the region in the buffer and then pressing, say F2 to store it in the file for later use).
I'm not sure which aspect in particular you needed help with: reusing ido or storing a list of completions. However, once you have a list of completions (perhaps just a list defined in your .emacs?) , check out the function ido-completing-read. I use it to use ido functionality on my kill ring like so:
(ido-completing-read "Yank text: " kill-ring)

Emacs - Min chars for auto completion

I'm using Emacs to write Java code (but I noticed this happens for other languages as well), and I'm having an issue with the completion. Say I want to import a library:
import java.|
Where | is the cursor. If I invoke the auto completion, it won't show anything.
import java.u|
In the case above, if I invoke auto completion, it works, showing every candidate starting with u.
Is it possible to change this behavior of needing to type the first letter to see the results? It would also be nice to do that for other languages as well.
I read the auto-complete documentation, also tried to study and change the code, but as I'm not familiar with lisp, didn't have any success.