vappman 0.6__py3-none-any.whl → 0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
vappman/main.py CHANGED
@@ -6,7 +6,7 @@ Interactive, visual thin layer atop appman
6
6
  # pylint: disable=broad-exception-caught,consider-using-with
7
7
  # pylint: disable=too-many-instance-attributes,too-many-branches
8
8
  # pylint: disable=too-many-return-statements,too-many-statements
9
-
9
+ # pylint: disable=consider-using-in
10
10
  # pylint: disable=wrong-import-position,disable=wrong-import-order
11
11
  # import VirtEnv
12
12
  # VirtEnv.ensure_venv(__name__)
@@ -17,10 +17,7 @@ import re
17
17
  import shutil
18
18
  import subprocess
19
19
  import traceback
20
- import copy
21
- import shutil
22
20
  import curses as cs
23
- from types import SimpleNamespace
24
21
  from vappman.PowerWindow import Window, OptionSpinner
25
22
 
26
23
 
@@ -40,6 +37,7 @@ class Vappman:
40
37
  other = 'airbou/qscU'
41
38
  other_keys = set(ord(x) for x in other)
42
39
  other_keys.add(cs.KEY_ENTER)
40
+ other_keys.add(27) # ESCAPE
43
41
  other_keys.add(10) # another form of ENTER
44
42
  self.opts = spin.default_obj
45
43
 
@@ -115,6 +113,7 @@ class Vappman:
115
113
  ' U - update ALL installed apps',
116
114
  ' / - filter apps',
117
115
  ' ENTER = install, remove, or return from help',
116
+ ' ESC = clear filter and jump to top',
118
117
  'CONTEXT SENSITIVE:',
119
118
  ' i - install uninstalled app',
120
119
  ' r - remove installed app',
@@ -135,11 +134,11 @@ class Vappman:
135
134
  for app, line in self.installs.items():
136
135
  if app in self.apps:
137
136
  line = self.apps[app]
138
- if wanted(line):
137
+ if wanted(line[2:]):
139
138
  line = '✔✔✔' + line[1:]
140
139
  self.win.add_body(line)
141
140
  for app, line in self.apps.items():
142
- if app not in self.installs and wanted(line):
141
+ if app not in self.installs and wanted(line[2:]):
143
142
  self.win.add_body(line)
144
143
  self.win.render()
145
144
 
@@ -149,15 +148,17 @@ class Vappman:
149
148
  def get_keys_line(self):
150
149
  """ TBD """
151
150
  # EXPAND
152
- filt = self.prev_filter if self.prev_filter else '{No-Filt}'
153
- line = 'KEYS:'
151
+ line = ''
154
152
  for key, verb in self.actions.items():
155
- line += f' {key}:{verb}'
153
+ if key[0] == verb[0]:
154
+ line += f' {verb}'
155
+ else:
156
+ line += f' {key}:{verb}'
156
157
  # or EXPAND
157
- line += f' ?:help q:quit a:about s:sync c:clean U:upd /{filt} '
158
+ line += f' ?:help quit about sync clean Upd /{self.prev_filter} '
158
159
  # for action in self.actions:
159
160
  # line += f' {action[0]}:{action}'
160
- return line
161
+ return line[1:]
161
162
 
162
163
  def get_actions(self, line):
163
164
  """ Determine the type of the current line and available commands."""
@@ -185,27 +186,30 @@ class Vappman:
185
186
  """
186
187
  this = Vappman.singleton
187
188
  this.pick_app, this.actions = this.get_actions(line)
188
- keys_line = this.get_keys_line().ljust(this.win.get_pad_width())
189
- this.win.head.pad.addstr(0, 0, keys_line, cs.A_BOLD)
190
-
189
+ header = this.get_keys_line()
190
+ # ASSUME line ends in /....
191
+ parts = header.split('/', maxsplit=1)
192
+ wds = parts[0].split()
193
+ this.win.head.pad.move(0, 0)
194
+ for wd in wds:
195
+ if wd:
196
+ this.win.add_header(wd[0], attr=cs.A_BOLD|cs.A_UNDERLINE, resume=True)
197
+ if wd[1:]:
198
+ this.win.add_header(wd[1:] + ' ', resume=True)
199
+
200
+ this.win.add_header('/', attr=cs.A_BOLD+cs.A_UNDERLINE, resume=True)
201
+ if len(parts) > 1 and parts[1]:
202
+ this.win.add_header(f'{parts[1]}', resume=True)
203
+ _, col = this.win.head.pad.getyx()
204
+ pad = ' ' * (this.win.get_pad_width()-col)
205
+ this.win.add_header(pad, resume=True)
191
206
  return line
192
- # #IF WE WANT TO DO SOMETHING ON THE LINE...
193
- # suffix = ''
194
- # for action in actions:
195
- # suffix += f' {action[0]}:{action}'
196
- # block_char = "\u2588"
197
- # suffix = f'{block_char*5} {suffix}'
198
- # over = len(line) + len(suffix) - this.win.get_pad_width()
199
- # if over < 0:
200
- # line += ' '*(-over)
201
- # elif over > 0:
202
- # line = line[0:-over]
203
-
204
- # return line + suffix
207
+
205
208
  def run_appman(self, cmd):
209
+ """ Run a 'appman' command """
206
210
  Window.stop_curses()
207
211
  os.system(f'clear; stty sane; {cmd};'
208
- + ' /bin/echo -e "\n\n===== Press ENTER for menu ====> \c"; read FOO')
212
+ + r' /bin/echo -e "\n\n===== Press ENTER for menu ====> \c"; read FOO')
209
213
  self.installs = self.get_installed()
210
214
  Window._start_curses()
211
215
 
@@ -217,7 +221,7 @@ class Vappman:
217
221
  if self.opts.help_mode:
218
222
  self.opts.help_mode = False
219
223
  return True
220
- elif self.pick_is_installed:
224
+ if self.pick_is_installed:
221
225
  key = ord('r') # removed installed app
222
226
  else:
223
227
  key = ord('i') # install uninstalled app
@@ -226,6 +230,12 @@ class Vappman:
226
230
  value = self.spin.do_key(key, self.win)
227
231
  return value
228
232
 
233
+ if key == 27: # ESCAPE
234
+ self.prev_filter = ''
235
+ self.filter = None
236
+ self.win.pick_pos = 0
237
+ return None
238
+
229
239
  if key == ord('q'):
230
240
  self.win.stop_curses()
231
241
  os.system('clear; stty sane')
@@ -252,11 +262,12 @@ class Vappman:
252
262
  if key == ord('u'):
253
263
  self.run_appman(f'appman update {self.pick_app}')
254
264
  if key == ord('U'):
255
- self.run_appman(f'appman update')
265
+ self.run_appman('appman update')
256
266
  # EXPAND
257
267
 
258
268
  if key == ord('/'):
259
269
  # pylint: disable=protected-access
270
+ start_filter = self.prev_filter
260
271
 
261
272
  prefix = ''
262
273
  while True:
@@ -266,18 +277,22 @@ class Vappman:
266
277
  pattern.strip()
267
278
  if not pattern:
268
279
  self.filter = None
269
- return None
280
+ break
270
281
 
271
282
  try:
272
283
  if re.match(r'^[\-\w\s]*$', pattern):
273
284
  words = pattern.split()
274
- self.filter = re.compile(r'\b' + r'\b.*'.join(words), re.IGNORECASE)
275
- return None
285
+ self.filter = re.compile(r'\b' + r'(|.*\b)'.join(words), re.IGNORECASE)
286
+ break
276
287
  self.filter = re.compile(pattern, re.IGNORECASE)
277
- return None
288
+ break
278
289
  except Exception:
279
290
  prefix = 'Bad regex: '
280
291
 
292
+ if start_filter != self.prev_filter:
293
+ # when filter changes, move to top
294
+ self.win.pick_pos = 0
295
+
281
296
  return None
282
297
  return None
283
298
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vappman
3
- Version: 0.6
3
+ Version: 0.7
4
4
  Summary: A visual wrapper for appman
5
5
  Author-email: Joe Defen <joedef@google.com>
6
6
  License: MIT
@@ -56,10 +56,16 @@ But it does NOT cover:
56
56
  * Installed apps have prefix '✔✔✔' (i.e., three checks).
57
57
  * Uninstalled apps have prefix '◆' (i.e., a solid diamond).
58
58
  * Enter `/` to enter a "filter" for installed/uninstalled apps, if you wish.
59
- * If you enter plain ole "words", then those words must match the beginning of words
60
- of the apps or descriptions (in order, but not contiguously).
61
- * Or you can enter an regular expression acceptable to python (e.g., `\b` means word
62
- boundary, etc.)
59
+ * If you enter plain ole "words", then those words must match:
60
+ * the start of words on the apps line (in order, but not contiguously) and/or
61
+ * the start of the remainder of the previous word match
62
+ (i.e., `/bit fight` matches `bitfighter`).
63
+ * Or you can enter an regular expression acceptable to python; e.g.,
64
+ * `^` matches the line starting with the app name
65
+ * `\b` matches a word boundary; and so forth.
66
+ * NOTES:
67
+ * `ESC` clears the filter and jumps to the top of the listing.
68
+ * Each time the filter is changed, the position jumps to the top of the listing.
63
69
  * Use `i` to install apps, and `r` to remove apps. When you install or remove an app, `appman` drops out of `curses` mode, runs the `appman` command so you can see the result, and then prompts your to hit ENTER to return to `vappman.
64
70
 
65
71
  ## Example Screenshot
@@ -75,4 +81,6 @@ NOTES: in this example:
75
81
  all the filtered apps; otherwise, the decoration suggests where you are in the
76
82
  partial view of the filtered apps.
77
83
  * the matching installed app has the '✔✔✔' prefix.
84
+ * the fixed top line shows some of the available action keys (e.g., `q` quits the app)
85
+ * use `?` to open the help screen describing all keys (including navigation)
78
86
 
@@ -0,0 +1,9 @@
1
+ vappman/PowerWindow.py,sha256=OLCX-RkbJZ2wwaY7M-4Eo9PQuR95TWrGNIY8DdVRpsE,28567
2
+ vappman/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ vappman/main.py,sha256=8I97lvSqpkPzQ51q_NDPb6dL18Th-ZHm_PRTT6BE9Ec,11105
4
+ vappman-0.7.dist-info/LICENSE,sha256=qB9OdnyyF6WYHiEIXVm0rOSdcf8e2ctorrtWs6CC5lU,1062
5
+ vappman-0.7.dist-info/METADATA,sha256=_xoExbsd16j5PAWgJrvaSw3uiW18aWY8tRfeJ53HLnM,4360
6
+ vappman-0.7.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
7
+ vappman-0.7.dist-info/entry_points.txt,sha256=7_1MiUvkCJoElLePOCJYqhkQN4xmadBRQCKupOwzt90,46
8
+ vappman-0.7.dist-info/top_level.txt,sha256=5_Gb5oZh7s2-i62gLXZ6INVALAV9D0-yqh0TvNqpPC4,8
9
+ vappman-0.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- vappman/PowerWindow.py,sha256=OLCX-RkbJZ2wwaY7M-4Eo9PQuR95TWrGNIY8DdVRpsE,28567
2
- vappman/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- vappman/main.py,sha256=rSWpH_l_IgH3jR4HSG-H8lvmuuAZWStPo-AMtSIsZYY,10483
4
- vappman-0.6.dist-info/LICENSE,sha256=qB9OdnyyF6WYHiEIXVm0rOSdcf8e2ctorrtWs6CC5lU,1062
5
- vappman-0.6.dist-info/METADATA,sha256=pWiQZo-R_ePgEX3Yz9oAcNty2XBmYCArV--3ErQd_HI,3850
6
- vappman-0.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
7
- vappman-0.6.dist-info/entry_points.txt,sha256=7_1MiUvkCJoElLePOCJYqhkQN4xmadBRQCKupOwzt90,46
8
- vappman-0.6.dist-info/top_level.txt,sha256=5_Gb5oZh7s2-i62gLXZ6INVALAV9D0-yqh0TvNqpPC4,8
9
- vappman-0.6.dist-info/RECORD,,
File without changes