-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathpycmd_public.py
200 lines (160 loc) · 6.99 KB
/
pycmd_public.py
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
"""
Public constants, objects and utilities exported by PyCmd.
These are meant to be used in init.py files; users can rely on them being kept
unchanged (interface-wise) throughout later versions.
"""
import os, sys, common, console
def abbrev_path(path = None):
"""
Abbreviate a full path (or the current path, if None is provided) to make
it shorter, yet still unambiguous.
This function takes a directory path and tries to abbreviate it as much as
possible while making sure that the resulting shortened path is not
ambiguous: a path element is only abbreviated if its shortened form is
unique in its directory (in other words, if a sybling would have the same
abbreviation, the original name is kept).
The abbreviation is performed by keeping only the first letter of each
"word" composing a path element. "Words" are defined by CamelCase,
underscore_separation or "whitespace separation".
"""
if not path:
path = os.getcwd() # .decode(sys.getfilesystemencoding())
path = path[0].upper() + path[1:]
return path
current_dir = path[ : 3]
path = path[3 : ]
path_abbrev = current_dir[ : 2]
for elem in path.split('\\')[ : -1]:
elem_abbrev = common.abbrev_string(elem)
for other in os.listdir(current_dir):
if os.path.isdir(current_dir + '\\' + other) and common.abbrev_string(other).lower() == elem_abbrev.lower() and other.lower() != elem.lower():
# Found other directory with the same abbreviation
# In this case, we use the entire name
elem_abbrev = elem
break
current_dir += '\\' + elem
path_abbrev += '\\' + elem_abbrev
return path_abbrev + '\\' + path.split('\\')[-1]
def abbrev_path_prompt():
"""
Return a prompt containg the current path (abbreviated)
This is the default PyCmd prompt. It uses the abbrev_path() function to
obtain the shortened path and appends the typical '> '.
"""
return abbrev_path() + u'> '
class color(object):
"""
Constants for color manipulation within PyCmd.
These constants are similar to ANSI escape sequences, only more powerful in
the sense that they support setting, resetting and toggling of individual R,
G, B components
"""
class Fore(object):
"""Color constants for the foreground"""
# For individually setting a RGB field
SET_RED = chr(27) + 'FSR'
SET_GREEN = chr(27) + 'FSG'
SET_BLUE = chr(27) + 'FSB'
SET_BRIGHT = chr(27) +'FSX'
# For individually clearing a RGB field
CLEAR_RED = chr(27) + 'FCR'
CLEAR_GREEN = chr(27) + 'FCG'
CLEAR_BLUE = chr(27) + 'FCB'
CLEAR_BRIGHT = chr(27) + 'FCX'
# For individually toggling a RGB field
TOGGLE_RED = chr(27) + 'FTR'
TOGGLE_GREEN = chr(27) + 'FTG'
TOGGLE_BLUE = chr(27) + 'FTB'
TOGGLE_BRIGHT = chr(27) + 'FTX'
# Standard colors defined as combinations of the RGB constants
RED = SET_RED + CLEAR_GREEN + CLEAR_BLUE
GREEN = CLEAR_RED + SET_GREEN + CLEAR_BLUE
YELLOW = SET_RED + SET_GREEN + CLEAR_BLUE
BLUE = CLEAR_RED + CLEAR_GREEN + SET_BLUE
MAGENTA = SET_RED + CLEAR_GREEN + SET_BLUE
CYAN = CLEAR_RED + SET_GREEN + SET_BLUE
WHITE = SET_RED + SET_GREEN + SET_BLUE
# Default terminal color
DEFAULT = console.get_current_foreground()
class Back(object):
"""Color constants for the background"""
# For individually setting a RGB field
SET_RED = chr(27) + 'BSR'
SET_GREEN = chr(27) + 'BSG'
SET_BLUE = chr(27) + 'BSB'
SET_BRIGHT = chr(27) +'BSX'
# For individually clearing a RGB field
CLEAR_RED = chr(27) + 'BCR'
CLEAR_GREEN = chr(27) + 'BCG'
CLEAR_BLUE = chr(27) + 'BCB'
CLEAR_BRIGHT = chr(27) + 'BCX'
# For individually toggling a RGB field
TOGGLE_RED = chr(27) + 'BTR'
TOGGLE_GREEN = chr(27) + 'BTG'
TOGGLE_BLUE = chr(27) + 'BTB'
TOGGLE_BRIGHT = chr(27) + 'BTX'
# Standard colors defined as combinations of the RGB constants
RED = SET_RED + CLEAR_GREEN + CLEAR_BLUE
GREEN = CLEAR_RED + SET_GREEN + CLEAR_BLUE
YELLOW = SET_RED + SET_GREEN + CLEAR_BLUE
BLUE = CLEAR_RED + CLEAR_GREEN + SET_BLUE
MAGENTA = SET_RED + CLEAR_GREEN + SET_BLUE
CYAN = CLEAR_RED + SET_GREEN + SET_BLUE
WHITE = SET_RED + SET_GREEN + SET_BLUE
# Default terminal color
DEFAULT = console.get_current_background()
class _Settings(object):
"""
Generic settings class; extend this to create a "group" of options
(accessible as instance members in the settings.py files)
"""
def sanitize(self):
"""Make sure the settings have sane values"""
pass
class _Appearance(_Settings):
"""Appearance settings"""
class _ColorSettings(_Settings):
"""Color-related settings"""
def __init__(self):
self.text = ''
self.prompt = color.Fore.TOGGLE_BRIGHT
self.selection = (color.Fore.TOGGLE_RED +
color.Fore.TOGGLE_GREEN +
color.Fore.TOGGLE_BLUE +
color.Back.TOGGLE_RED +
color.Back.TOGGLE_GREEN +
color.Back.TOGGLE_BLUE)
self.search_filter = (color.Back.TOGGLE_RED +
color.Back.TOGGLE_BLUE +
color.Fore.TOGGLE_BRIGHT)
self.completion_match = color.Fore.TOGGLE_RED
self.dir_history_selection = (color.Fore.TOGGLE_BRIGHT +
color.Back.TOGGLE_BRIGHT)
def __init__(self):
# Prompt function (should return a string)
self.prompt = abbrev_path_prompt
# Color configuration
self.colors = self._ColorSettings()
def sanitize(self):
if not callable(self.prompt):
print('Prompt function doesn\'t look like a callable; reverting to PyCmd\'s default prompt')
self.prompt = abbrev_path_prompt
class Behavior(_Settings):
"""Behavior settings"""
def __init__(self):
# Skip splash message (welcome and bye).
# This can be also overriden with the '-Q' command line argument'
self.quiet_mode = False
# Select the completion mode; currently supported: 'bash'
self.completion_mode = 'bash'
def sanitize(self):
if not self.completion_mode in ['bash']:
print('Invalid setting "' + self.completion_mode + '" for "completion_mode" -- using default "bash"')
self.completion_mode = 'bash'
# Initialize global configuration instances with default values
#
# These objects are directly manipulated by the settings.py files, executed via
# apply_settings(). Then, they are directly used by PyCmd.py to get the current
# configuration settings
appearance = _Appearance()
behavior = Behavior()