Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tab completion in internal shell causes escape mode mess #336

Open
rofl0r opened this issue Apr 24, 2019 · 6 comments · May be fixed by #337
Open

tab completion in internal shell causes escape mode mess #336

rofl0r opened this issue Apr 24, 2019 · 6 comments · May be fixed by #337

Comments

@rofl0r
Copy link

rofl0r commented Apr 24, 2019

admittedly, in sabotage linux we have a quite unusual python setup:

  • netbsd-curses is used instead of ncurses
  • libedit is used instead of readline

nonetheless, i'm reporting the issue i experienced with pudb 2018-1 here for the record.

when the internal shell is selected, and one switched there using '!', as soon as TAB is pressed for the first time for completion (there needs to be something written, for example "a", which would then be completed to e.g. "abs" or "assert"), escapes are broken and every subsequent keypress is displayed as eg ^CC or similar, but not recognized as such. makes it impossible to exit the shell via CTRL-X. or use backspace, etc. only way out is to kill pudb.

fortunately, i noticed that if i used e.g. the "classic" shell once, then switched to "internal" using preferences, everything behaves as exactly as it should.
this lead me to produce the following patch, which fixes the issue for me.
apparently the readline completer needs to be "initialized" with the code in the patch at least once.

--- pudb-2018.1/pudb/debugger.py
+++ pudb-2018.1.org/pudb/debugger.py
@@ -1831,7 +1831,13 @@
 
         def run_cmdline(w, size, key):
             if CONFIG["shell"] == "internal":
-                return toggle_cmdline_focus(w, size, key)
+                curframe = self.debugger.curframe
+                self.screen.stop()
+                import pudb.shell as shell
+                shell.setup_readline(curframe.f_globals, curframe.f_locals)
+                ret = toggle_cmdline_focus(w, size, key)
+                self.screen.start()
+                return ret
             else:
                 return run_external_cmdline(w, size, key)
 
--- pudb-2018.1/pudb/shell.py
+++ pudb-2018.1.org/pudb/shell.py
@@ -72,14 +72,7 @@
 
 custom_shell_dict = {}
 
-
-def run_classic_shell(globals, locals, first_time=[True]):
-    if first_time:
-        banner = "Hit Ctrl-D to return to PuDB."
-        first_time.pop()
-    else:
-        banner = ""
-
+def setup_readline(globals, locals):
     ns = SetPropagatingDict([locals, globals], locals)
 
     from pudb.settings import get_save_config_path
@@ -97,6 +90,18 @@
             readline.read_history_file(hist_file)
         except IOError:
             pass
+
+    return hist_file
+
+
+def run_classic_shell(globals, locals, first_time=[True]):
+    if first_time:
+        banner = "Hit Ctrl-D to return to PuDB."
+        first_time.pop()
+    else:
+        banner = ""
+
+    hist_file = setup_readline(globals, locals)
 
     from code import InteractiveConsole
     cons = InteractiveConsole(ns)

(the self.screen.stop/start is probably not necessary, it's a leftover from my first attempts at fixing)

@asmeurer
Copy link
Collaborator

libedit is known to be quite buggy (it's also included by default on OS X). I believe you can install readline with https://pypi.org/project/gnureadline/ (though I'm not sure how that package works if PuDB needs to be modified to support it).

Can you send your diff as a pull request? We would need to test it to make sure that it doesn't break the normal readline environments.

@rofl0r
Copy link
Author

rofl0r commented Apr 24, 2019

I believe you can install readline with https://pypi.org/project/gnureadline/ (though I'm not sure how that package works if PuDB needs to be modified to support it).

i'm aware that i could install GNU readline instead, but the whole point of using libedit is to use less bloated components. that way we can have a python 2.7 package that extracts to a mere 22.2 MB. using a static-linked readline just for python would add even more bloat than simply using GNU readline distro-wide ;)

Can you send your diff as a pull request?

thanks, i will accept your invitation and give it a shot

rofl0r added a commit to rofl0r/pudb that referenced this issue Apr 24, 2019
when switching to the internal shell and using tab completion, libedit messes
up the terminal state, unless it uses the readline initialization routine that
the "classic" shell code uses as well.
additionally to that, it requires that the console screen is stopped before
doing that for the first time.

fixes inducer#336
@rofl0r rofl0r linked a pull request Apr 24, 2019 that will close this issue
@inducer
Copy link
Owner

inducer commented Apr 25, 2019

I don't understand this at all--neither the bug nor the patch, sorry. The internal shell is implemented purely in Urwid, with no code path that goes through readline. So introducing readline into that code path seems like a weird thing to do.

My read on what's happening is that your Curses library fails to properly set up the terminal to receive the Tab key, resulting in the breakage you observe. Rather than calling into readline to (mostly, by voodoo) fix that bit of terminal state, I feel like there are two options that would be strongly preferable:

  • Fix the curses library to do the right thing.
  • Use Urwid's "raw" (not "curses") terminal driver, which can be chosen from PuDB's preferences screen.

@rofl0r
Copy link
Author

rofl0r commented Apr 26, 2019

is that so ?

i've seen this snippet and assumed it was used:

        def cmdline_tab_complete(w, size, key):
            from rlcompleter import Completer

although i didn't step through it

@inducer
Copy link
Owner

inducer commented Apr 28, 2019

That's true--but rlcompleter is independent of readline. All it does is, given a command line fragment and a scope, produce some options for Tab completion.

@inducer
Copy link
Owner

inducer commented Apr 28, 2019

Hmm, now that I've said that: It does import readline and set itself as the completer there. So if importing readline has some side effect in your setup (it shouldn't!), that's probably what's causing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants