vappman 0.7__tar.gz → 0.9__tar.gz
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-0.7/src/vappman.egg-info → vappman-0.9}/PKG-INFO +8 -4
- {vappman-0.7 → vappman-0.9}/README.md +7 -3
- {vappman-0.7 → vappman-0.9}/pyproject.toml +1 -1
- {vappman-0.7 → vappman-0.9}/src/vappman/PowerWindow.py +1 -1
- {vappman-0.7 → vappman-0.9}/src/vappman/main.py +157 -12
- {vappman-0.7 → vappman-0.9/src/vappman.egg-info}/PKG-INFO +8 -4
- {vappman-0.7 → vappman-0.9}/LICENSE +0 -0
- {vappman-0.7 → vappman-0.9}/setup.cfg +0 -0
- {vappman-0.7 → vappman-0.9}/src/vappman/__init__.py +0 -0
- {vappman-0.7 → vappman-0.9}/src/vappman.egg-info/SOURCES.txt +0 -0
- {vappman-0.7 → vappman-0.9}/src/vappman.egg-info/dependency_links.txt +0 -0
- {vappman-0.7 → vappman-0.9}/src/vappman.egg-info/entry_points.txt +0 -0
- {vappman-0.7 → vappman-0.9}/src/vappman.egg-info/requires.txt +0 -0
- {vappman-0.7 → vappman-0.9}/src/vappman.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vappman
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9
|
|
4
4
|
Summary: A visual wrapper for appman
|
|
5
5
|
Author-email: Joe Defen <joedef@google.com>
|
|
6
6
|
License: MIT
|
|
@@ -41,7 +41,7 @@ But it does NOT cover:
|
|
|
41
41
|
* (-v) version of appman
|
|
42
42
|
* --force-latest to get the most recent stable release AND
|
|
43
43
|
all other options and unmentioned commands.
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
## Usage
|
|
46
46
|
* Run `vappman` from the command line.
|
|
47
47
|
* It presents some keys available on the top line.
|
|
@@ -67,13 +67,15 @@ But it does NOT cover:
|
|
|
67
67
|
* `ESC` clears the filter and jumps to the top of the listing.
|
|
68
68
|
* Each time the filter is changed, the position jumps to the top of the listing.
|
|
69
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.
|
|
70
|
+
* Use `t` to "test" an installed app. This launches a terminal emulator and then the app so you can see issues. This is not for daily use obviously, but for after install or when having unknown issues and you wish to start the investigation.
|
|
70
71
|
|
|
71
|
-
## Example Screenshot
|
|
72
|
+
## Example Screenshot (of v0.7 ... current release will vary slightly)
|
|
72
73
|
.
|
|
73
74
|
|
|
74
75
|
---
|
|
75
76
|
|
|
76
77
|
NOTES: in this example:
|
|
78
|
+
* keys to the left of `❚` apply to the highlighted app; keys to the right apply globally.
|
|
77
79
|
* the filter is `card` so it shows app lines with words starting with `card`.
|
|
78
80
|
* the reverse video, current position is on `glabels`;
|
|
79
81
|
thus if `i` (or ENTER) is typed, `appman install glabels` is run.
|
|
@@ -81,6 +83,8 @@ NOTES: in this example:
|
|
|
81
83
|
all the filtered apps; otherwise, the decoration suggests where you are in the
|
|
82
84
|
partial view of the filtered apps.
|
|
83
85
|
* the matching installed app has the '✔✔✔' prefix.
|
|
84
|
-
* the fixed top line shows
|
|
86
|
+
* the fixed top line shows mos of the available action keys (e.g., `q` quits the app)
|
|
85
87
|
* use `?` to open the help screen describing all keys (including navigation)
|
|
86
88
|
|
|
89
|
+
## Screen Recording (Intro to vappman based on v0.7)
|
|
90
|
+
[](https://youtu.be/NUHYN9_DZtA)
|
|
@@ -23,7 +23,7 @@ But it does NOT cover:
|
|
|
23
23
|
* (-v) version of appman
|
|
24
24
|
* --force-latest to get the most recent stable release AND
|
|
25
25
|
all other options and unmentioned commands.
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
## Usage
|
|
28
28
|
* Run `vappman` from the command line.
|
|
29
29
|
* It presents some keys available on the top line.
|
|
@@ -49,13 +49,15 @@ But it does NOT cover:
|
|
|
49
49
|
* `ESC` clears the filter and jumps to the top of the listing.
|
|
50
50
|
* Each time the filter is changed, the position jumps to the top of the listing.
|
|
51
51
|
* 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.
|
|
52
|
+
* Use `t` to "test" an installed app. This launches a terminal emulator and then the app so you can see issues. This is not for daily use obviously, but for after install or when having unknown issues and you wish to start the investigation.
|
|
52
53
|
|
|
53
|
-
## Example Screenshot
|
|
54
|
+
## Example Screenshot (of v0.7 ... current release will vary slightly)
|
|
54
55
|
.
|
|
55
56
|
|
|
56
57
|
---
|
|
57
58
|
|
|
58
59
|
NOTES: in this example:
|
|
60
|
+
* keys to the left of `❚` apply to the highlighted app; keys to the right apply globally.
|
|
59
61
|
* the filter is `card` so it shows app lines with words starting with `card`.
|
|
60
62
|
* the reverse video, current position is on `glabels`;
|
|
61
63
|
thus if `i` (or ENTER) is typed, `appman install glabels` is run.
|
|
@@ -63,6 +65,8 @@ NOTES: in this example:
|
|
|
63
65
|
all the filtered apps; otherwise, the decoration suggests where you are in the
|
|
64
66
|
partial view of the filtered apps.
|
|
65
67
|
* the matching installed app has the '✔✔✔' prefix.
|
|
66
|
-
* the fixed top line shows
|
|
68
|
+
* the fixed top line shows mos of the available action keys (e.g., `q` quits the app)
|
|
67
69
|
* use `?` to open the help screen describing all keys (including navigation)
|
|
68
70
|
|
|
71
|
+
## Screen Recording (Intro to vappman based on v0.7)
|
|
72
|
+
[](https://youtu.be/NUHYN9_DZtA)
|
|
@@ -588,7 +588,7 @@ class Window:
|
|
|
588
588
|
def alert(self, title='ALERT', message='', height=1, width=80):
|
|
589
589
|
"""Alert box"""
|
|
590
590
|
def mod_key(key):
|
|
591
|
-
return 7 if key
|
|
591
|
+
return 7 if key in (10, curses.KEY_ENTER) else key
|
|
592
592
|
|
|
593
593
|
# need 3 extra cols for rectangle (so we don't draw in southeast corner)
|
|
594
594
|
# and 3 rows (top/prompt/bottom)
|
|
@@ -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
|
-
# pylint: disable=consider-using-in
|
|
9
|
+
# pylint: disable=consider-using-in,too-many-nested-blocks
|
|
10
10
|
# pylint: disable=wrong-import-position,disable=wrong-import-order
|
|
11
11
|
# import VirtEnv
|
|
12
12
|
# VirtEnv.ensure_venv(__name__)
|
|
@@ -14,6 +14,7 @@ Interactive, visual thin layer atop appman
|
|
|
14
14
|
import os
|
|
15
15
|
import sys
|
|
16
16
|
import re
|
|
17
|
+
import glob
|
|
17
18
|
import shutil
|
|
18
19
|
import subprocess
|
|
19
20
|
import traceback
|
|
@@ -34,7 +35,7 @@ class Vappman:
|
|
|
34
35
|
spin.add_key('help_mode', '? - toggle help screen', vals=[False, True])
|
|
35
36
|
|
|
36
37
|
# EXPAND
|
|
37
|
-
other = '
|
|
38
|
+
other = 'airtbou/qxscU'
|
|
38
39
|
other_keys = set(ord(x) for x in other)
|
|
39
40
|
other_keys.add(cs.KEY_ENTER)
|
|
40
41
|
other_keys.add(27) # ESCAPE
|
|
@@ -49,6 +50,9 @@ class Vappman:
|
|
|
49
50
|
self.check_preqreqs()
|
|
50
51
|
self.apps = self.cmd_dict('appman list')
|
|
51
52
|
self.installs = self.get_installed() # dict keyed by app
|
|
53
|
+
self.appman_dir = self.get_appman_dir()
|
|
54
|
+
self.dot_desktop_dir = self.get_dot_desktop_dir()
|
|
55
|
+
self.terminal_emulator = None
|
|
52
56
|
self.win = Window(head_line=True, body_rows=len(self.apps)+20, head_rows=10,
|
|
53
57
|
keys=spin.keys ^ other_keys, mod_pick=self.mod_pick)
|
|
54
58
|
|
|
@@ -94,6 +98,43 @@ class Vappman:
|
|
|
94
98
|
rv = self.cmd_dict('appman files --byname')
|
|
95
99
|
return rv
|
|
96
100
|
|
|
101
|
+
@staticmethod
|
|
102
|
+
def get_appman_dir():
|
|
103
|
+
""" Try to figure out where the apps are stored. """
|
|
104
|
+
|
|
105
|
+
appman_dir = None, None
|
|
106
|
+
try:
|
|
107
|
+
config_dir = os.getenv('XDG_CONFIG_HOME')
|
|
108
|
+
if not config_dir:
|
|
109
|
+
config_dir = os.path.join(os.getenv('HOME'), '.config')
|
|
110
|
+
config_file = os.path.join(config_dir, 'appman', 'appman-config')
|
|
111
|
+
with open(config_file, 'r', encoding='utf-8') as fh:
|
|
112
|
+
appman_dir = fh.read().strip()
|
|
113
|
+
appman_dir = os.path.join(os.getenv('HOME'), appman_dir)
|
|
114
|
+
os.listdir(appman_dir)
|
|
115
|
+
return appman_dir
|
|
116
|
+
except Exception as exc:
|
|
117
|
+
print(f'NOTE: cannot get appman dir; tried below {appman_dir!r}; {exc}')
|
|
118
|
+
print(' Check if contents of ~/config/appman/appman-config'
|
|
119
|
+
+ ' is the subdir of $HOME w your appman apps')
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
@staticmethod
|
|
123
|
+
def get_dot_desktop_dir():
|
|
124
|
+
""" Try to figure out where the .desktop files are stored. """
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
data_dir = os.getenv('XDG_DATA_HOME')
|
|
128
|
+
if not data_dir:
|
|
129
|
+
data_dir = os.path.join(os.getenv('HOME'), '.local', 'share')
|
|
130
|
+
dot_dir = os.path.join(data_dir, 'applications')
|
|
131
|
+
os.listdir(dot_dir)
|
|
132
|
+
return dot_dir
|
|
133
|
+
except Exception as exc:
|
|
134
|
+
print(f'NOTE: cannot get .desktop dir; tried below {data_dir!r}; {exc}')
|
|
135
|
+
print(' Check if contents of ~/.local/share/applications for .desktop files')
|
|
136
|
+
return None
|
|
137
|
+
|
|
97
138
|
def main_loop(self):
|
|
98
139
|
""" TBD """
|
|
99
140
|
|
|
@@ -106,20 +147,21 @@ class Vappman:
|
|
|
106
147
|
# EXPAND
|
|
107
148
|
lines = [
|
|
108
149
|
'ALWAYS AVAILABLE:',
|
|
109
|
-
' q - quit program (CTL-C disabled)',
|
|
110
150
|
' a - about (more info about app)',
|
|
111
151
|
' s - sync (update appman itself)',
|
|
112
152
|
' c - clean (remove unneeded files/folters)',
|
|
113
153
|
' U - update ALL installed apps',
|
|
114
|
-
'
|
|
115
|
-
'
|
|
154
|
+
' q or x - quit program (CTL-C disabled)',
|
|
155
|
+
' / - filter apps by keywords or regex',
|
|
116
156
|
' ESC = clear filter and jump to top',
|
|
157
|
+
' ENTER = install, remove, or return from help',
|
|
117
158
|
'CONTEXT SENSITIVE:',
|
|
118
159
|
' i - install uninstalled app',
|
|
119
160
|
' r - remove installed app',
|
|
120
|
-
' b - backup installed app',
|
|
121
161
|
' u - update installed app',
|
|
162
|
+
' b - backup installed app',
|
|
122
163
|
' o - overwrite app from its backup',
|
|
164
|
+
' t - test by opening a terminal emulator and launching the app',
|
|
123
165
|
|
|
124
166
|
]
|
|
125
167
|
for line in lines:
|
|
@@ -127,6 +169,12 @@ class Vappman:
|
|
|
127
169
|
else:
|
|
128
170
|
def wanted(line):
|
|
129
171
|
return not self.filter or self.filter.search(line)
|
|
172
|
+
def version_of(app):
|
|
173
|
+
# ◆ krita | 5.2.2 | appimage-type2 | 355 MiB
|
|
174
|
+
fields = self.installs[app].split('|')
|
|
175
|
+
if len(fields) >= 2:
|
|
176
|
+
return fields[1].strip()
|
|
177
|
+
return '?version?'
|
|
130
178
|
|
|
131
179
|
# self.win.set_pick_mode(self.opts.pick_mode, self.opts.pick_size)
|
|
132
180
|
self.win.set_pick_mode(True)
|
|
@@ -135,7 +183,7 @@ class Vappman:
|
|
|
135
183
|
if app in self.apps:
|
|
136
184
|
line = self.apps[app]
|
|
137
185
|
if wanted(line[2:]):
|
|
138
|
-
line = '✔✔✔
|
|
186
|
+
line = f'✔✔✔ {app} [{version_of(app)}] :{line.split(':', maxsplit=1)[1]}'
|
|
139
187
|
self.win.add_body(line)
|
|
140
188
|
for app, line in self.apps.items():
|
|
141
189
|
if app not in self.installs and wanted(line[2:]):
|
|
@@ -155,7 +203,7 @@ class Vappman:
|
|
|
155
203
|
else:
|
|
156
204
|
line += f' {key}:{verb}'
|
|
157
205
|
# or EXPAND
|
|
158
|
-
line += f'
|
|
206
|
+
line += f' about ❚ sync clean Upd quit ?:help /{self.prev_filter} '
|
|
159
207
|
# for action in self.actions:
|
|
160
208
|
# line += f' {action[0]}:{action}'
|
|
161
209
|
return line[1:]
|
|
@@ -171,9 +219,10 @@ class Vappman:
|
|
|
171
219
|
# EXPAND
|
|
172
220
|
if self.pick_is_installed:
|
|
173
221
|
actions['r'] = 'rmv'
|
|
222
|
+
actions['u'] = 'upd'
|
|
174
223
|
actions['b'] = 'bkup'
|
|
175
224
|
actions['o'] = 'overwr'
|
|
176
|
-
actions['
|
|
225
|
+
actions['t'] = 'test'
|
|
177
226
|
else:
|
|
178
227
|
actions['i'] = 'install'
|
|
179
228
|
|
|
@@ -192,6 +241,9 @@ class Vappman:
|
|
|
192
241
|
wds = parts[0].split()
|
|
193
242
|
this.win.head.pad.move(0, 0)
|
|
194
243
|
for wd in wds:
|
|
244
|
+
if wd[0]in ('<', '|', '❚'):
|
|
245
|
+
this.win.add_header(wd + ' ', resume=True)
|
|
246
|
+
continue
|
|
195
247
|
if wd:
|
|
196
248
|
this.win.add_header(wd[0], attr=cs.A_BOLD|cs.A_UNDERLINE, resume=True)
|
|
197
249
|
if wd[1:]:
|
|
@@ -213,6 +265,95 @@ class Vappman:
|
|
|
213
265
|
self.installs = self.get_installed()
|
|
214
266
|
Window._start_curses()
|
|
215
267
|
|
|
268
|
+
@staticmethod
|
|
269
|
+
def launch_desktop_file(desktop_file_path):
|
|
270
|
+
""" Launch the .desktop file using xdg-open in a detached process """
|
|
271
|
+
try:
|
|
272
|
+
trial = ['xdg-open', desktop_file_path]
|
|
273
|
+
subprocess.Popen(trial,
|
|
274
|
+
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, close_fds=True)
|
|
275
|
+
return None
|
|
276
|
+
except Exception:
|
|
277
|
+
return trial
|
|
278
|
+
|
|
279
|
+
def launch_in_terminal(self, executable):
|
|
280
|
+
""" Find a terminal emulator"""
|
|
281
|
+
if not self.terminal_emulator:
|
|
282
|
+
maybes = [
|
|
283
|
+
[ 'konsole', '--noclose', '-e', '"{command}"'],
|
|
284
|
+
[ 'gnome-terminal', '--', 'bash', '-c', '"{command}"; exec bash' ],
|
|
285
|
+
[ 'xfce4-terminal', '--hold', '--command="{command}"' ],
|
|
286
|
+
[ 'lxterminal', '-e', """bash -c '"{command}"; echo; read -p "Press Enter to close..."'"""],
|
|
287
|
+
# [ terminator', ],
|
|
288
|
+
# [ alacritty', ],
|
|
289
|
+
# [ termite', ],
|
|
290
|
+
# [ urxvt', ],
|
|
291
|
+
# [ sakura', ],
|
|
292
|
+
# [ tilix', ],
|
|
293
|
+
# [ kitty', ],
|
|
294
|
+
# [ hyper', ],
|
|
295
|
+
# [ guake', ],
|
|
296
|
+
# [ yakuake', ],
|
|
297
|
+
]
|
|
298
|
+
for maybe in maybes:
|
|
299
|
+
if shutil.which(maybe[0]):
|
|
300
|
+
self.terminal_emulator = maybe
|
|
301
|
+
break
|
|
302
|
+
if self.terminal_emulator:
|
|
303
|
+
try:
|
|
304
|
+
trial = []
|
|
305
|
+
for wd in self.terminal_emulator:
|
|
306
|
+
trial.append(wd.replace('{command}', executable))
|
|
307
|
+
subprocess.Popen(trial)
|
|
308
|
+
return None
|
|
309
|
+
except Exception:
|
|
310
|
+
return trial
|
|
311
|
+
return trial
|
|
312
|
+
|
|
313
|
+
def launch_app(self, app):
|
|
314
|
+
""" Try to run an app."""
|
|
315
|
+
# First dig out where it might be installed as a .desktop file
|
|
316
|
+
# by searching the 'remove' script
|
|
317
|
+
def get_unique_words_from_file(file_path):
|
|
318
|
+
seen_words = set()
|
|
319
|
+
with open(file_path, 'r', encoding='utf-8') as file:
|
|
320
|
+
for line in file:
|
|
321
|
+
line_words = line.split()
|
|
322
|
+
for word in line_words:
|
|
323
|
+
if word not in seen_words:
|
|
324
|
+
seen_words.add(word)
|
|
325
|
+
return seen_words
|
|
326
|
+
|
|
327
|
+
failures = []
|
|
328
|
+
executables = []
|
|
329
|
+
try:
|
|
330
|
+
for globname in get_unique_words_from_file(
|
|
331
|
+
os.path.join(self.appman_dir, app, 'remove')):
|
|
332
|
+
results = glob.glob(globname)
|
|
333
|
+
if '/share/applications/AM-ZZZ' in globname:
|
|
334
|
+
for result in results:
|
|
335
|
+
if result.endswith('.desktop'):
|
|
336
|
+
failure = self.launch_desktop_file(result)
|
|
337
|
+
if failure:
|
|
338
|
+
failures.append(' '.join(failure))
|
|
339
|
+
return
|
|
340
|
+
elif '/.local/bin/' in globname:
|
|
341
|
+
for result in results:
|
|
342
|
+
if os.access(result, os.X_OK):
|
|
343
|
+
executables.append(result)
|
|
344
|
+
for executable in executables:
|
|
345
|
+
failure = self.launch_in_terminal(executable)
|
|
346
|
+
if failure:
|
|
347
|
+
failures.append(' '.join(failure))
|
|
348
|
+
return
|
|
349
|
+
except Exception as exc:
|
|
350
|
+
failures += f'cannot find .desktop/executable to run [{exc}]'
|
|
351
|
+
if failures:
|
|
352
|
+
message = ' '.join([f'Cannot launch {app}'] + failures)
|
|
353
|
+
self.win.alert(message=message)
|
|
354
|
+
|
|
355
|
+
self.launch_app(self.pick_app)
|
|
356
|
+
|
|
216
357
|
def do_key(self, key):
|
|
217
358
|
""" TBD """
|
|
218
359
|
if not key:
|
|
@@ -222,21 +363,21 @@ class Vappman:
|
|
|
222
363
|
self.opts.help_mode = False
|
|
223
364
|
return True
|
|
224
365
|
if self.pick_is_installed:
|
|
225
|
-
key = ord('r') #
|
|
366
|
+
key = ord('r') # remove installed app
|
|
226
367
|
else:
|
|
227
368
|
key = ord('i') # install uninstalled app
|
|
228
369
|
|
|
229
370
|
if key in self.spin.keys:
|
|
230
371
|
value = self.spin.do_key(key, self.win)
|
|
231
372
|
return value
|
|
232
|
-
|
|
373
|
+
|
|
233
374
|
if key == 27: # ESCAPE
|
|
234
375
|
self.prev_filter = ''
|
|
235
376
|
self.filter = None
|
|
236
377
|
self.win.pick_pos = 0
|
|
237
378
|
return None
|
|
238
379
|
|
|
239
|
-
if key
|
|
380
|
+
if key in (ord('q'), ord('x')):
|
|
240
381
|
self.win.stop_curses()
|
|
241
382
|
os.system('clear; stty sane')
|
|
242
383
|
sys.exit(0)
|
|
@@ -249,6 +390,10 @@ class Vappman:
|
|
|
249
390
|
self.run_appman(f'appman remove {self.pick_app}')
|
|
250
391
|
return None
|
|
251
392
|
|
|
393
|
+
if key == ord('t') and self.pick_is_installed:
|
|
394
|
+
self.launch_app(self.pick_app)
|
|
395
|
+
return None
|
|
396
|
+
|
|
252
397
|
if key == ord('s'):
|
|
253
398
|
self.run_appman('appman sync')
|
|
254
399
|
if key == ord('c'):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vappman
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9
|
|
4
4
|
Summary: A visual wrapper for appman
|
|
5
5
|
Author-email: Joe Defen <joedef@google.com>
|
|
6
6
|
License: MIT
|
|
@@ -41,7 +41,7 @@ But it does NOT cover:
|
|
|
41
41
|
* (-v) version of appman
|
|
42
42
|
* --force-latest to get the most recent stable release AND
|
|
43
43
|
all other options and unmentioned commands.
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
## Usage
|
|
46
46
|
* Run `vappman` from the command line.
|
|
47
47
|
* It presents some keys available on the top line.
|
|
@@ -67,13 +67,15 @@ But it does NOT cover:
|
|
|
67
67
|
* `ESC` clears the filter and jumps to the top of the listing.
|
|
68
68
|
* Each time the filter is changed, the position jumps to the top of the listing.
|
|
69
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.
|
|
70
|
+
* Use `t` to "test" an installed app. This launches a terminal emulator and then the app so you can see issues. This is not for daily use obviously, but for after install or when having unknown issues and you wish to start the investigation.
|
|
70
71
|
|
|
71
|
-
## Example Screenshot
|
|
72
|
+
## Example Screenshot (of v0.7 ... current release will vary slightly)
|
|
72
73
|
.
|
|
73
74
|
|
|
74
75
|
---
|
|
75
76
|
|
|
76
77
|
NOTES: in this example:
|
|
78
|
+
* keys to the left of `❚` apply to the highlighted app; keys to the right apply globally.
|
|
77
79
|
* the filter is `card` so it shows app lines with words starting with `card`.
|
|
78
80
|
* the reverse video, current position is on `glabels`;
|
|
79
81
|
thus if `i` (or ENTER) is typed, `appman install glabels` is run.
|
|
@@ -81,6 +83,8 @@ NOTES: in this example:
|
|
|
81
83
|
all the filtered apps; otherwise, the decoration suggests where you are in the
|
|
82
84
|
partial view of the filtered apps.
|
|
83
85
|
* the matching installed app has the '✔✔✔' prefix.
|
|
84
|
-
* the fixed top line shows
|
|
86
|
+
* the fixed top line shows mos of the available action keys (e.g., `q` quits the app)
|
|
85
87
|
* use `?` to open the help screen describing all keys (including navigation)
|
|
86
88
|
|
|
89
|
+
## Screen Recording (Intro to vappman based on v0.7)
|
|
90
|
+
[](https://youtu.be/NUHYN9_DZtA)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|