Coverage for pyquickhelper/ipythonhelper/kindofcompletion.py: 100%
53 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
1"""
2@file
3@brief A custom way to add auto completion to IPython
4"""
6import os
9class AutoCompletion:
11 """
12 You can add auto completion object to IPython by adding member
13 to an instance of this class.
15 All members must begin by ``_``
16 """
18 def __init__(self, value=None):
19 """
20 constructor
22 @param value any value of object
23 """
24 self._value = value
26 @property
27 def _(self):
28 """
29 return the value
30 """
31 return self._value
33 def _add(self, member, value):
34 """
35 add a member to this class, add an ``AutoCompletion`` instance,
36 creates one if value is not from ``AutoCompletion`` type
38 @param member name of the new member
39 @param value value to add
40 @return (AutoCompletion)
41 """
42 if member in self.__dict__:
43 raise NameError( # pragma: no cover
44 f"Unable to add member {member} because it already exists")
45 if member.startswith("_"):
46 raise NameError( # pragma: no cover
47 f"A member cannot start by _: {member}")
48 if isinstance(value, AutoCompletion):
49 self.__dict__[member] = value
50 return value
51 value = AutoCompletion(value)
52 self.__dict__[member] = value
53 return value
55 @property
56 def _members(self):
57 """
58 returns all the members
59 """
60 return [_ for _ in self.__dict__ if not _.startswith("_")]
62 def __len__(self):
63 """
64 returns the number of elements
65 """
66 return 1 + sum(len(self.__dict__[_]) for _ in self._members)
68 def __str__(self):
69 """
70 returns a string
71 """
72 ch = self._members
73 if len(ch) == 0:
74 return ""
75 rows = []
76 for i, c in enumerate(sorted(ch)):
77 pref = " | " if i < len(ch) - 1 else " "
78 name = " |- " + c
79 rows.append(name)
80 sub = str(self.__dict__[c])
81 if len(sub) > 0:
82 lin = sub.split("\n")
83 lin = [(pref + _) for _ in lin]
84 rows.extend(lin)
85 return "\n".join(rows)
88class AutoCompletionFile(AutoCompletion):
90 """
91 builds a tree based on a list of files,
92 the class adds ``A__`` before every folder or file starting with ``_``
94 .. exref::
95 :title: File autocompletion in IPython
97 The following code:
99 ::
101 from pyquickhelper.ipythonhelper import AutoCompletionFile
102 d = AutoCompletionFile(".")
104 Will produce the following auto completion picture:
106 @image images/completion.png
107 """
109 def __init__(self, value):
110 """
111 constructor
113 @param value directory
114 """
115 if not os.path.exists(value):
116 raise FileNotFoundError( # pragma: no cover
117 f"{value} does not exists")
118 AutoCompletion.__init__(self, os.path.normpath(os.path.abspath(value)))
119 self._populate()
121 def _filter(self, s):
122 """
123 Removes unexpected characters for a file name.
125 @param s filename
126 @return cleaned filename
127 """
128 s = s.replace("'", "_") \
129 .replace('"', "_") \
130 .replace('(', "_") \
131 .replace(')', "_") \
132 .replace('[', "_") \
133 .replace(']', "_") \
134 .replace('{', "_") \
135 .replace('}', "_") \
136 .replace('.', "_") \
137 .replace(':', "_") \
138 .replace('/', "_") \
139 .replace('\\', "_") \
140 .replace('!', "_") \
141 .replace('$', "_") \
142 .replace('-', "_") \
143 .replace('#', "_") \
144 .replace('*', "_")
145 if s.startswith("_"):
146 s = "A__" + s
147 return s
149 def _populate(self):
150 """
151 populate the class with files and folder in the folder
152 this class holds
153 """
154 if os.path.isdir(self._):
155 files = os.listdir(self._)
156 for file in files:
157 fullname = os.path.join(self._, file)
158 obj = AutoCompletionFile(fullname)
159 self._add(self._filter(file), obj)