0
# Code Navigation
1
2
Advanced code navigation including reference finding, symbol search, context analysis, and help lookup. Provides IDE-level navigation capabilities across entire projects with sophisticated scope analysis and cross-reference tracking.
3
4
## Capabilities
5
6
### Reference Finding
7
8
Find all references to a symbol across the project or within a file, with options for controlling scope and builtin inclusion.
9
10
```python { .api }
11
def get_references(self, line=None, column=None, *, include_builtins=True, scope='project'):
12
"""
13
Find all references to the symbol at cursor position.
14
15
Parameters:
16
- line (int, optional): Line number (1-based).
17
- column (int, optional): Column number (0-based).
18
- include_builtins (bool): Include builtin references. Default True.
19
- scope (str): Search scope - 'project' or 'file'. Default 'project'.
20
21
Returns:
22
List of Name objects representing references.
23
"""
24
```
25
26
**Usage Example:**
27
```python
28
import jedi
29
30
code = '''
31
class Calculator:
32
def add(self, a, b):
33
return a + b
34
35
calc = Calculator()
36
result = calc.add(1, 2)
37
print(calc.add)
38
'''
39
40
script = jedi.Script(code=code, path='example.py')
41
42
# Find all references to 'add' method
43
references = script.get_references(line=2, column=8) # At 'add' definition
44
45
for ref in references:
46
print(f"Reference at line {ref.line}, column {ref.column}")
47
print(f"Type: {ref.type}")
48
print(f"Context: {ref.get_line_code()}")
49
print(f"Is definition: {ref.is_definition()}")
50
print("---")
51
52
# Find references in current file only
53
file_refs = script.get_references(line=2, column=8, scope='file')
54
55
# Exclude builtin references
56
no_builtins = script.get_references(line=2, column=8, include_builtins=False)
57
```
58
59
### Symbol Search
60
61
Search for symbols by name within the current file, supporting both exact and fuzzy matching.
62
63
```python { .api }
64
def search(self, string, *, all_scopes=False):
65
"""
66
Search for names in the current file.
67
68
Parameters:
69
- string (str): Search string pattern.
70
- all_scopes (bool): Search in all scopes, not just module level. Default False.
71
72
Returns:
73
Generator of Name objects matching the search.
74
"""
75
```
76
77
**Usage Example:**
78
```python
79
import jedi
80
81
code = '''
82
class DataProcessor:
83
def process_data(self, data):
84
processed_result = self.transform_data(data)
85
return processed_result
86
87
def transform_data(self, data):
88
return data.upper()
89
90
def process_file(filename):
91
processor = DataProcessor()
92
return processor.process_data(filename)
93
'''
94
95
script = jedi.Script(code=code, path='example.py')
96
97
# Search for names containing 'process'
98
results = list(script.search('process'))
99
for result in results:
100
print(f"Found: {result.name} at line {result.line}")
101
print(f"Type: {result.type}")
102
print(f"Full name: {result.full_name}")
103
104
# Search in all scopes (including function/class internals)
105
all_results = list(script.search('data', all_scopes=True))
106
for result in all_results:
107
print(f"Found: {result.name} in {result.parent().name if result.parent() else 'global'}")
108
```
109
110
### Completion Search
111
112
Search with completion-style fuzzy matching for symbol discovery.
113
114
```python { .api }
115
def complete_search(self, string, *, all_scopes=False, fuzzy=False):
116
"""
117
Search with completion-style matching.
118
119
Parameters:
120
- string (str): Search string pattern.
121
- all_scopes (bool): Search in all scopes. Default False.
122
- fuzzy (bool): Enable fuzzy matching. Default False.
123
124
Returns:
125
Generator of Completion objects.
126
"""
127
```
128
129
**Usage Example:**
130
```python
131
import jedi
132
133
code = '''
134
def calculate_average(numbers):
135
return sum(numbers) / len(numbers)
136
137
def calculate_median(numbers):
138
sorted_nums = sorted(numbers)
139
return sorted_nums[len(sorted_nums) // 2]
140
141
def calc_standard_deviation(numbers):
142
avg = calculate_average(numbers)
143
return (sum((x - avg) ** 2 for x in numbers) / len(numbers)) ** 0.5
144
'''
145
146
script = jedi.Script(code=code, path='example.py')
147
148
# Fuzzy search for calculation functions
149
completions = list(script.complete_search('calc', fuzzy=True))
150
for comp in completions:
151
print(f"Match: {comp.name}")
152
print(f"Complete: {comp.complete}")
153
print(f"Type: {comp.type}")
154
155
# Search for all functions
156
functions = list(script.complete_search('', all_scopes=True))
157
functions = [f for f in functions if f.type == 'function']
158
```
159
160
### Context Analysis
161
162
Get the current scope context at a specific position, determining the enclosing function, class, or module.
163
164
```python { .api }
165
def get_context(self, line=None, column=None):
166
"""
167
Get the scope context at cursor position.
168
169
Parameters:
170
- line (int, optional): Line number (1-based).
171
- column (int, optional): Column number (0-based).
172
173
Returns:
174
Name object representing the current scope context.
175
"""
176
```
177
178
**Usage Example:**
179
```python
180
import jedi
181
182
code = '''
183
class WebServer:
184
def __init__(self, port):
185
self.port = port
186
187
def handle_request(self, request):
188
if request.method == 'GET':
189
return self.handle_get(request)
190
elif request.method == 'POST':
191
# cursor position here
192
return self.handle_post(request)
193
194
def handle_get(self, request):
195
return "GET response"
196
'''
197
198
script = jedi.Script(code=code, path='example.py')
199
200
# Get context at different positions
201
contexts = [
202
script.get_context(line=3, column=20), # Inside __init__
203
script.get_context(line=8, column=12), # Inside handle_request
204
script.get_context(line=12, column=8), # Inside handle_get
205
script.get_context(line=1, column=0), # Module level
206
]
207
208
for i, context in enumerate(contexts):
209
print(f"Context {i+1}: {context.name} (type: {context.type})")
210
# Get parent context
211
parent = context.parent() if context.type != 'module' else None
212
if parent:
213
print(f" Parent: {parent.name} (type: {parent.type})")
214
```
215
216
### Help and Documentation
217
218
Get help information for symbols, including keyword and operator help.
219
220
```python { .api }
221
def help(self, line=None, column=None):
222
"""
223
Get help information for the symbol at cursor position.
224
225
Parameters:
226
- line (int, optional): Line number (1-based).
227
- column (int, optional): Column number (0-based).
228
229
Returns:
230
List of Name objects with help information.
231
"""
232
```
233
234
**Usage Example:**
235
```python
236
import jedi
237
238
code = '''
239
import json
240
json.loads("test")
241
for item in range(10):
242
if item > 5:
243
break
244
'''
245
246
script = jedi.Script(code=code, path='example.py')
247
248
# Get help for function
249
help_info = script.help(line=2, column=5) # At 'loads'
250
for info in help_info:
251
print(f"Help for: {info.name}")
252
print(f"Type: {info.type}")
253
print(f"Docstring: {info.docstring()[:100]}...")
254
255
# Get help for keywords
256
keyword_help = script.help(line=3, column=0) # At 'for'
257
for info in keyword_help:
258
if info.is_keyword:
259
print(f"Keyword: {info.name}")
260
print(f"Help: {info.docstring()}")
261
262
# Get help for operators
263
break_help = script.help(line=5, column=8) # At 'break'
264
```
265
266
### Cross-Reference Navigation
267
268
Navigate between definitions and references with detailed relationship information.
269
270
**Usage Example:**
271
```python
272
import jedi
273
274
code = '''
275
class DatabaseConnection:
276
def __init__(self, host, port):
277
self.host = host
278
self.port = port
279
self.connection = None
280
281
def connect(self):
282
self.connection = f"Connected to {self.host}:{self.port}"
283
return self.connection
284
285
def disconnect(self):
286
if self.connection:
287
self.connection = None
288
289
# Usage
290
db = DatabaseConnection("localhost", 5432)
291
conn = db.connect()
292
print(conn)
293
db.disconnect()
294
'''
295
296
script = jedi.Script(code=code, path='example.py')
297
298
# Navigate from usage to definition
299
usage_pos = (17, 5) # At 'db' in db.connect()
300
definitions = script.goto(*usage_pos)
301
for definition in definitions:
302
print(f"Definition: {definition.name} at line {definition.line}")
303
304
# Find all references from definition
305
definition_pos = (16, 0) # At 'db = DatabaseConnection...'
306
references = script.get_references(*definition_pos)
307
for ref in references:
308
print(f"Reference: line {ref.line}, column {ref.column}")
309
print(f" Code: {ref.get_line_code().strip()}")
310
print(f" Is definition: {ref.is_definition()}")
311
312
# Get related definitions (methods of the class)
313
class_methods = script.goto(line=1, column=6) # At 'DatabaseConnection'
314
if class_methods:
315
class_def = class_methods[0]
316
methods = class_def.defined_names()
317
print("Class methods:")
318
for method in methods:
319
if method.type == 'function':
320
print(f" {method.name} at line {method.line}")
321
```
322
323
### Advanced Navigation Patterns
324
325
Complex navigation scenarios for IDE-level functionality.
326
327
**Multi-file Navigation:**
328
```python
329
import jedi
330
from jedi import Project
331
332
# Set up project for cross-file navigation
333
project = Project("/path/to/project")
334
335
# File 1: models.py
336
models_code = '''
337
class User:
338
def __init__(self, name, email):
339
self.name = name
340
self.email = email
341
'''
342
343
# File 2: main.py
344
main_code = '''
345
from models import User
346
347
user = User("John", "john@example.com")
348
print(user.name)
349
'''
350
351
# Analyze with project context
352
script = jedi.Script(code=main_code, path="main.py", project=project)
353
354
# Navigate from usage to definition across files
355
definitions = script.goto(line=3, column=7, follow_imports=True) # At 'User'
356
for definition in definitions:
357
print(f"Found definition in: {definition.module_path}")
358
print(f"At line: {definition.line}")
359
```
360
361
**Inheritance Navigation:**
362
```python
363
code = '''
364
class Animal:
365
def speak(self):
366
pass
367
368
class Dog(Animal):
369
def speak(self):
370
return "Woof!"
371
372
class Cat(Animal):
373
def speak(self):
374
return "Meow!"
375
376
dog = Dog()
377
sound = dog.speak() # Navigate to Dog.speak, not Animal.speak
378
'''
379
380
script = jedi.Script(code=code, path='example.py')
381
382
# Navigate to the actual implementation, not the base class
383
definitions = script.goto(line=13, column=12) # At 'speak'
384
for definition in definitions:
385
print(f"Actual implementation: {definition.parent().name}.{definition.name}")
386
print(f"At line: {definition.line}")
387
```