From 240eef90ab769a25100eb9f2c4247d775e6c160c 2015-02-19 20:12:45 From: Min RK Date: 2015-02-19 20:12:45 Subject: [PATCH] prioritize function token for inspection foo(a=str.| will find `foo` instead of `str` --- diff --git a/IPython/utils/tests/test_tokenutil.py b/IPython/utils/tests/test_tokenutil.py index be9cb57..ff3efc7 100644 --- a/IPython/utils/tests/test_tokenutil.py +++ b/IPython/utils/tests/test_tokenutil.py @@ -48,13 +48,28 @@ def test_multiline(): start = cell.index(expected) + 1 for i in range(start, start + len(expected)): expect_token(expected, cell, i) - expected = 'there' + expected = 'hello' start = cell.index(expected) + 1 for i in range(start, start + len(expected)): expect_token(expected, cell, i) +def test_nested_call(): + cell = "foo(bar(a=5), b=10)" + expected = 'foo' + start = cell.index('bar') + 1 + for i in range(start, start + 3): + expect_token(expected, cell, i) + expected = 'bar' + start = cell.index('a=') + for i in range(start, start + 3): + expect_token(expected, cell, i) + expected = 'foo' + start = cell.index(')') + 1 + for i in range(start, len(cell)-1): + expect_token(expected, cell, i) + def test_attrs(): - cell = "foo(a=obj.attr.subattr)" + cell = "a = obj.attr.subattr" expected = 'obj' idx = cell.find('obj') + 1 for i in range(idx, idx + 3): diff --git a/IPython/utils/tokenutil.py b/IPython/utils/tokenutil.py index 48cc82c..f0040bf 100644 --- a/IPython/utils/tokenutil.py +++ b/IPython/utils/tokenutil.py @@ -58,6 +58,9 @@ def token_at_cursor(cell, cursor_pos=0): Used for introspection. + Function calls are prioritized, so the token for the callable will be returned + if the cursor is anywhere inside the call. + Parameters ---------- @@ -70,6 +73,7 @@ def token_at_cursor(cell, cursor_pos=0): names = [] tokens = [] offset = 0 + call_names = [] for tup in generate_tokens(StringIO(cell).readline): tok = Token(*tup) @@ -93,6 +97,11 @@ def token_at_cursor(cell, cursor_pos=0): if tok.text == '=' and names: # don't inspect the lhs of an assignment names.pop(-1) + if tok.text == '(' and names: + # if we are inside a function call, inspect the function + call_names.append(names[-1]) + elif tok.text == ')' and call_names: + call_names.pop(-1) if offset + end_col > cursor_pos: # we found the cursor, stop reading @@ -102,7 +111,9 @@ def token_at_cursor(cell, cursor_pos=0): if tok.token == tokenize2.NEWLINE: offset += len(tok.line) - if names: + if call_names: + return call_names[-1] + elif names: return names[-1] else: return ''