Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

""" 

@file 

@brief A custom way to add auto completion to IPython 

""" 

 

import os 

 

 

class AutoCompletion: 

 

""" 

You can add auto completion object to IPython by adding member 

to an instance of this class. 

 

All members must begin by ``_`` 

""" 

 

def __init__(self, value=None): 

""" 

constructor 

 

@param value any value of object 

""" 

self._value = value 

 

@property 

def _(self): 

""" 

return the value 

""" 

return self._value 

 

def _add(self, member, value): 

""" 

add a member to this class, add an ``AutoCompletion`` instance, 

creates one if value is not from ``AutoCompletion`` type 

 

@param member name of the new member 

@param value value to add 

@return (AutoCompletion) 

""" 

if member in self.__dict__: 

raise NameError( 

"unable to add member {0} because it already exists".format(member)) 

if member.startswith("_"): 

raise NameError("a member cannot start by _: {0}".format(member)) 

if isinstance(value, AutoCompletion): 

self.__dict__[member] = value 

return value 

else: 

value = AutoCompletion(value) 

self.__dict__[member] = value 

return value 

 

@property 

def _members(self): 

""" 

returns all the members 

""" 

return [_ for _ in self.__dict__ if not _.startswith("_")] 

 

def __len__(self): 

""" 

returns the number of elements 

""" 

return 1 + sum(len(self.__dict__[_]) for _ in self._members) 

 

def __str__(self): 

""" 

returns a string 

""" 

ch = self._members 

if len(ch) == 0: 

return "" 

rows = [] 

for i, c in enumerate(sorted(ch)): 

pref = " | " if i < len(ch) - 1 else " " 

name = " |- " + c 

rows.append(name) 

sub = str(self.__dict__[c]) 

if len(sub) > 0: 

lin = sub.split("\n") 

lin = [(pref + _) for _ in lin] 

rows.extend(lin) 

return "\n".join(rows) 

 

 

class AutoCompletionFile(AutoCompletion): 

 

""" 

builds a tree based on a list of files, 

the class adds ``A__`` before every folder or file starting with ``_`` 

 

.. exref:: 

:title: File autocompletion in IPython 

 

The following code: 

 

:: 

 

from pyquickhelper.ipythonhelper import AutoCompletionFile 

d = AutoCompletionFile(".") 

 

Will produce the following auto completion picture: 

 

@image images/completion.png 

""" 

 

def __init__(self, value): 

""" 

constructor 

 

@param value directory 

""" 

if not os.path.exists(value): 

raise FileNotFoundError("{0} does not exists".format(value)) 

AutoCompletion.__init__(self, os.path.normpath(os.path.abspath(value))) 

self._populate() 

 

def _filter(self, s): 

""" 

remove unexpected characters for a file name 

 

@param s filename 

@return cleaned filename 

""" 

s = s.replace("'", "_") \ 

.replace('"', "_") \ 

.replace('(', "_") \ 

.replace(')', "_") \ 

.replace('[', "_") \ 

.replace(']', "_") \ 

.replace('{', "_") \ 

.replace('}', "_") \ 

.replace('.', "_") \ 

.replace(':', "_") \ 

.replace('/', "_") \ 

.replace('\\', "_") \ 

.replace('!', "_") \ 

.replace('$', "_") \ 

.replace('-', "_") \ 

.replace('#', "_") \ 

.replace('*', "_") 

if s.startswith("_"): 

s = "A__" + s 

return s 

 

def _populate(self): 

""" 

populate the class with files and folder in the folder 

this class holds 

""" 

if os.path.isdir(self._): 

files = os.listdir(self._) 

for file in files: 

fullname = os.path.join(self._, file) 

obj = AutoCompletionFile(fullname) 

self._add(self._filter(file), obj)