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@file 

3@brief A custom way to add auto completion to IPython 

4""" 

5 

6import os 

7 

8 

9class AutoCompletion: 

10 

11 """ 

12 You can add auto completion object to IPython by adding member 

13 to an instance of this class. 

14 

15 All members must begin by ``_`` 

16 """ 

17 

18 def __init__(self, value=None): 

19 """ 

20 constructor 

21 

22 @param value any value of object 

23 """ 

24 self._value = value 

25 

26 @property 

27 def _(self): 

28 """ 

29 return the value 

30 """ 

31 return self._value 

32 

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 

37 

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 "Unable to add member {0} because it already exists".format( 

45 member)) 

46 if member.startswith("_"): 

47 raise NameError( # pragma: no cover 

48 "A member cannot start by _: {0}".format(member)) 

49 if isinstance(value, AutoCompletion): 

50 self.__dict__[member] = value 

51 return value 

52 value = AutoCompletion(value) 

53 self.__dict__[member] = value 

54 return value 

55 

56 @property 

57 def _members(self): 

58 """ 

59 returns all the members 

60 """ 

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

62 

63 def __len__(self): 

64 """ 

65 returns the number of elements 

66 """ 

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

68 

69 def __str__(self): 

70 """ 

71 returns a string 

72 """ 

73 ch = self._members 

74 if len(ch) == 0: 

75 return "" 

76 rows = [] 

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

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

79 name = " |- " + c 

80 rows.append(name) 

81 sub = str(self.__dict__[c]) 

82 if len(sub) > 0: 

83 lin = sub.split("\n") 

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

85 rows.extend(lin) 

86 return "\n".join(rows) 

87 

88 

89class AutoCompletionFile(AutoCompletion): 

90 

91 """ 

92 builds a tree based on a list of files, 

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

94 

95 .. exref:: 

96 :title: File autocompletion in IPython 

97 

98 The following code: 

99 

100 :: 

101 

102 from pyquickhelper.ipythonhelper import AutoCompletionFile 

103 d = AutoCompletionFile(".") 

104 

105 Will produce the following auto completion picture: 

106 

107 @image images/completion.png 

108 """ 

109 

110 def __init__(self, value): 

111 """ 

112 constructor 

113 

114 @param value directory 

115 """ 

116 if not os.path.exists(value): 

117 raise FileNotFoundError( # pragma: no cover 

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

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

120 self._populate() 

121 

122 def _filter(self, s): 

123 """ 

124 Removes unexpected characters for a file name. 

125 

126 @param s filename 

127 @return cleaned filename 

128 """ 

129 s = s.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 .replace('*', "_") 

146 if s.startswith("_"): 

147 s = "A__" + s 

148 return s 

149 

150 def _populate(self): 

151 """ 

152 populate the class with files and folder in the folder 

153 this class holds 

154 """ 

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

156 files = os.listdir(self._) 

157 for file in files: 

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

159 obj = AutoCompletionFile(fullname) 

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