##// END OF EJS Templates
Backport PR #10489: Prefer execution when there's only a single line entered...
Backport PR #10489: Prefer execution when there's only a single line entered Closes gh-10425 The heuristic here is to treat a single line specially, and always evaluate it as if the cursor was at the end. An alternative heuristic could be to do this if the cursor is on the last line of the input. This could also cause some weird effects if you e.g. type `for a in range(5):`, move the cursor back a few places and press enter - you'll get a newline inserted in the text, but it will indent as if it were after the colon. I'm still trying to think if there's a better way to approach it.

File last commit:

r23569:b3762654
r23583:13833706
Show More
autogen_shortcuts.py
86 lines | 2.4 KiB | text/x-python | PythonLexer
/ docs / autogen_shortcuts.py
from os.path import abspath, dirname, join
from IPython.terminal.interactiveshell import KeyBindingManager
from IPython.utils.py3compat import string_types
def name(c):
s = c.__class__.__name__
if s == '_Invert':
return '(Not: %s)' % name(c.filter)
if s in log_filters.keys():
return '(%s: %s)' % (log_filters[s], ', '.join(name(x) for x in c.filters))
return log_filters[s] if s in log_filters.keys() else s
def sentencize(s):
"""Extract first sentence
"""
s = s.replace('\n', ' ').strip().split('.')
s = s[0] if len(s) else s
try:
return " ".join(s.split())
except AttributeError:
return s
def most_common(lst, n=3):
"""Most common elements occurring more then `n` times
"""
from collections import Counter
c = Counter(lst)
return [k for (k, v) in c.items() if k and v > n]
def multi_filter_str(flt):
"""Yield readable conditional filter
"""
assert hasattr(flt, 'filters'), 'Conditional filter required'
yield name(flt)
log_filters = dict(_AndList='And', _OrList='Or')
log_invert = {'_Invert'}
kbm = KeyBindingManager.for_prompt()
ipy_bindings = kbm.registry.key_bindings
dummy_docs = [] # ignore bindings without proper documentation
common_docs = most_common([kb.handler.__doc__ for kb in ipy_bindings])
if common_docs:
dummy_docs.extend(common_docs)
dummy_docs = list(set(dummy_docs))
single_filter = dict()
multi_filter = dict()
for kb in ipy_bindings:
doc = kb.handler.__doc__
if not doc or doc in dummy_docs:
continue
shortcut = ' '.join([k if isinstance(k, string_types) else k.name for k in kb.keys])
shortcut += shortcut.endswith('\\') and '\\' or ''
if hasattr(kb.filter, 'filters'):
flt = ' '.join(multi_filter_str(kb.filter))
multi_filter[(shortcut, flt)] = sentencize(doc)
else:
single_filter[(shortcut, name(kb.filter))] = sentencize(doc)
if __name__ == '__main__':
sort_key = lambda k:(str(k[0][1]),str(k[0][0]))
here = abspath(dirname(__file__))
dest = join(here, 'source', 'config', 'shortcuts')
with open(join(dest, 'single_filtered.csv'), 'w') as csv:
for k, v in sorted(single_filter.items(), key=sort_key):
csv.write(':kbd:`{}`\t{}\t{}\n'.format(k[0], k[1], v))
with open(join(dest, 'multi_filtered.csv'), 'w') as csv:
for k, v in sorted(multi_filter.items(), key=sort_key):
csv.write(':kbd:`{}`\t{}\t{}\n'.format(k[0], k[1], v))