Skip to content

Commit 535563b

Browse files
brenns10osandov
authored andcommitted
contrib: ptdrgn: Improve Object completion
Completion of drgn Objects *is* already possible in ptpython, but unfortunately the list of completions is alphabetical (except for underscored attributes, which are last). This means that default Object fields like "absent_" and "type_" are not distinguished from the Object member fields. Resolve this by detecting when the first completion is "absent_" and then moving all the non-default completions to the beginning of the list. The result is that Object members are enumerated first, followed by the default Object fields. Signed-off-by: Stephen Brennan <[email protected]>
1 parent aa851c8 commit 535563b

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

contrib/ptdrgn.py

+38-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#!/usr/bin/python3
12
# Copyright (c) 2023, Oracle and/or its affiliates.
23
# Copyright (c) Meta Platforms, Inc. and affiliates.
34
# SPDX-License-Identifier: LGPL-2.1-or-later
@@ -9,18 +10,19 @@
910
makes it worth sharing.
1011
1112
Requires: "pip install ptpython" which brings in pygments and prompt_toolkit
12-
13-
Future work:
14-
- Completion of drgn.Object member names (see ptpython.completer.DictCompleter)
1513
"""
14+
import functools
1615
import importlib
1716
import os
1817
import shutil
1918
import sys
20-
from typing import Any, Callable, Dict, Optional
19+
from typing import Any, Callable, Dict, Optional, Set
2120

21+
from prompt_toolkit.completion import Completion, Completer
2222
from prompt_toolkit.formatted_text import PygmentsTokens
23+
from prompt_toolkit.formatted_text import fragment_list_to_text, to_formatted_text
2324
from ptpython import embed
25+
from ptpython.completer import DictionaryCompleter
2426
from ptpython.repl import run_config
2527
from pygments.lexers.c_cpp import CLexer
2628

@@ -62,6 +64,36 @@ def _maybe_c_format(s):
6264
return to_format
6365

6466

67+
@functools.lru_cache(maxsize=1)
68+
def _object_fields() -> Set[str]:
69+
return set(dir(drgn.Object))
70+
71+
72+
class ReorderDrgnObjectCompleter(Completer):
73+
"""A completer which puts Object member fields above Object defaults"""
74+
75+
def __init__(self, c: Completer):
76+
self.c = c
77+
78+
def get_completions(self, document, complete_event):
79+
completions = list(self.c.get_completions(document, complete_event))
80+
if not completions:
81+
return completions
82+
text = completions[0].text
83+
member_fields = []
84+
# If the first completion is "absent_", it is *very likely* that we are
85+
# now looking at the completion of on Object. Move the default Object
86+
# attributes to the end of the list so that we get the struct attributes
87+
if text == "absent_":
88+
fields = _object_fields()
89+
for i in reversed(range(len(completions))):
90+
text = completions[i].text
91+
if text not in fields:
92+
member_fields.append(completions[i])
93+
del completions[i]
94+
return list(reversed(member_fields)) + completions
95+
return completions
96+
6597

6698
def configure(repl) -> None:
6799
"""
@@ -88,6 +120,8 @@ def _format_result_output(result: object):
88120

89121
repl._format_result_output = _format_result_output
90122
run_config(repl)
123+
repl._completer = ReorderDrgnObjectCompleter(repl._completer)
124+
repl.completer = ReorderDrgnObjectCompleter(repl.completer)
91125

92126

93127
def run_interactive(

0 commit comments

Comments
 (0)