listpick 0.1.16.7__py3-none-any.whl → 0.1.16.9__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.
Potentially problematic release.
This version of listpick might be problematic. Click here for more details.
- listpick/listpick_app.py +298 -75
- listpick/pane/left_pane_functions.py +198 -0
- listpick/pane/pane_functions_1.py +175 -0
- listpick/ui/build_help.py +8 -6
- listpick/ui/keys.py +5 -3
- {listpick-0.1.16.7.dist-info → listpick-0.1.16.9.dist-info}/METADATA +17 -16
- {listpick-0.1.16.7.dist-info → listpick-0.1.16.9.dist-info}/RECORD +11 -9
- {listpick-0.1.16.7.dist-info → listpick-0.1.16.9.dist-info}/WHEEL +0 -0
- {listpick-0.1.16.7.dist-info → listpick-0.1.16.9.dist-info}/entry_points.txt +0 -0
- {listpick-0.1.16.7.dist-info → listpick-0.1.16.9.dist-info}/licenses/LICENSE.txt +0 -0
- {listpick-0.1.16.7.dist-info → listpick-0.1.16.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/bin/python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
pane_functions.py
|
|
5
|
+
Functions which are run by a listpick Picker to display data in a pane.
|
|
6
|
+
|
|
7
|
+
Author: GrimAndGreedy
|
|
8
|
+
License: MIT
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import curses
|
|
12
|
+
import os
|
|
13
|
+
from listpick.pane.pane_utils import get_file_attributes, get_graph_string, escape_ansi
|
|
14
|
+
from listpick.pane.get_data import update_file_attributes
|
|
15
|
+
|
|
16
|
+
def left_start_pane(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
17
|
+
"""
|
|
18
|
+
Display file attributes in right pane.
|
|
19
|
+
"""
|
|
20
|
+
if test: return True
|
|
21
|
+
|
|
22
|
+
# Title
|
|
23
|
+
for i in range(h):
|
|
24
|
+
s = '*'*w
|
|
25
|
+
stdscr.addstr(y+i, x, s)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
stdscr.addstr(y, x, "+")
|
|
29
|
+
stdscr.addstr(y+h-1, x, "+")
|
|
30
|
+
stdscr.addstr(y, x+w-1, "+")
|
|
31
|
+
stdscr.addstr(y+h-1, x+w-1, "+")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
stdscr.addstr(y+1, x, f"{w},{h}")
|
|
35
|
+
|
|
36
|
+
return []
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def left_split_file_attributes(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
40
|
+
"""
|
|
41
|
+
Display file attributes in right pane.
|
|
42
|
+
"""
|
|
43
|
+
if test: return True
|
|
44
|
+
|
|
45
|
+
# Title
|
|
46
|
+
title = "File attributes"
|
|
47
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
48
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
49
|
+
|
|
50
|
+
# Separator
|
|
51
|
+
for j in range(h):
|
|
52
|
+
stdscr.addstr(j+y, x+w-1, ' ', curses.color_pair(state["colours_start"]+16))
|
|
53
|
+
|
|
54
|
+
# Display pane count
|
|
55
|
+
pane_count = len(state["right_panes"])
|
|
56
|
+
pane_index = state["right_pane_index"]
|
|
57
|
+
if pane_count > 1:
|
|
58
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
59
|
+
stdscr.addstr(y+h-1, x, s, curses.color_pair(state["colours_start"]+20))
|
|
60
|
+
|
|
61
|
+
# Filename/cursor cell value
|
|
62
|
+
stdscr.addstr(y+2, x+2, cell[:w-3])
|
|
63
|
+
|
|
64
|
+
attributes = get_file_attributes(cell)
|
|
65
|
+
for i, attr in enumerate(attributes):
|
|
66
|
+
stdscr.addstr(y+3+i, x+4, attr[:w-5])
|
|
67
|
+
|
|
68
|
+
return []
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def left_split_file_attributes_dynamic(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
72
|
+
"""
|
|
73
|
+
Display file attributes in right pane.
|
|
74
|
+
"""
|
|
75
|
+
if test: return True
|
|
76
|
+
|
|
77
|
+
# Title
|
|
78
|
+
title = "File attributes"
|
|
79
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
80
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
81
|
+
|
|
82
|
+
# Separator
|
|
83
|
+
for j in range(h):
|
|
84
|
+
stdscr.addstr(j+y, x+w-1, ' ', curses.color_pair(state["colours_start"]+16))
|
|
85
|
+
|
|
86
|
+
# Display pane count
|
|
87
|
+
pane_count = len(state["right_panes"])
|
|
88
|
+
pane_index = state["right_pane_index"]
|
|
89
|
+
if pane_count > 1:
|
|
90
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
91
|
+
stdscr.addstr(y+h-1, x, s, curses.color_pair(state["colours_start"]+20))
|
|
92
|
+
|
|
93
|
+
if len(state["indexed_items"]) == 0:
|
|
94
|
+
return []
|
|
95
|
+
|
|
96
|
+
# Filename/cursor cell value
|
|
97
|
+
stdscr.addstr(y+2, x+2, cell[:w-3])
|
|
98
|
+
|
|
99
|
+
# If the cursor-hovered file is different then reload the data
|
|
100
|
+
if data[1] != cell:
|
|
101
|
+
data[:] = update_file_attributes(data, state)
|
|
102
|
+
|
|
103
|
+
# attributes = get_file_attributes(cell)
|
|
104
|
+
if len(data) == 0: return []
|
|
105
|
+
attributes = data[0]
|
|
106
|
+
for i, attr in enumerate(attributes):
|
|
107
|
+
stdscr.addstr(y+3+i, x+4, attr[:w-5])
|
|
108
|
+
|
|
109
|
+
return []
|
|
110
|
+
|
|
111
|
+
def left_split_graph(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
112
|
+
"""
|
|
113
|
+
Display a graph of the data in right pane.
|
|
114
|
+
|
|
115
|
+
data[0] = x_vals
|
|
116
|
+
data[1] = y_vals
|
|
117
|
+
data[2] = id
|
|
118
|
+
"""
|
|
119
|
+
if test: return True
|
|
120
|
+
|
|
121
|
+
# Title
|
|
122
|
+
title = "Graph"
|
|
123
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
124
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
125
|
+
|
|
126
|
+
# Separator
|
|
127
|
+
for j in range(h):
|
|
128
|
+
stdscr.addstr(j+y, x+w-1, ' ', curses.color_pair(state["colours_start"]+16))
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# Display pane count
|
|
132
|
+
pane_count = len(state["right_panes"])
|
|
133
|
+
pane_index = state["right_pane_index"]
|
|
134
|
+
if pane_count > 1:
|
|
135
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
136
|
+
stdscr.addstr(y+h-1, x, s, curses.color_pair(state["colours_start"]+20))
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
import plotille as plt
|
|
140
|
+
except:
|
|
141
|
+
s = f"No module named 'plotille'"
|
|
142
|
+
stdscr.addstr(y+2, x+1, s[:w-2])
|
|
143
|
+
return None
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# x_vals, y_vals = list(range(100)), [x**2 for x in range(100)]
|
|
148
|
+
if data in [[], {}, None]:
|
|
149
|
+
return None
|
|
150
|
+
x_vals, y_vals = data[0], data[1]
|
|
151
|
+
graph_str = get_graph_string(x_vals, y_vals, width=w-3-10, height=h-3)
|
|
152
|
+
for i, s in enumerate(graph_str.split("\n")):
|
|
153
|
+
s = escape_ansi(s)
|
|
154
|
+
stdscr.addstr(y+2+i, x+1, s[:w-2])
|
|
155
|
+
|
|
156
|
+
return []
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def left_split_display_list(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
162
|
+
"""
|
|
163
|
+
data[0]:str = title
|
|
164
|
+
data[1]:list[str] = list of strings to display
|
|
165
|
+
"""
|
|
166
|
+
if test: return True
|
|
167
|
+
|
|
168
|
+
# Title
|
|
169
|
+
title = data[0]
|
|
170
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
171
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
172
|
+
|
|
173
|
+
# Separator
|
|
174
|
+
for j in range(h):
|
|
175
|
+
stdscr.addstr(j+y, x+w-1, ' ', curses.color_pair(state["colours_start"]+16))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
# Display pane count
|
|
179
|
+
pane_count = len(state["right_panes"])
|
|
180
|
+
pane_index = state["right_pane_index"]
|
|
181
|
+
if pane_count > 1:
|
|
182
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
183
|
+
stdscr.addstr(y+h-1, x, s, curses.color_pair(state["colours_start"]+20))
|
|
184
|
+
|
|
185
|
+
if data in [[], {}, None]:
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
items = data[1]
|
|
189
|
+
number_to_display = min(len(items), h-3)
|
|
190
|
+
for i in range(number_to_display):
|
|
191
|
+
s = items[i]
|
|
192
|
+
stdscr.addstr(y+1+i, x+2, s[:w-2])
|
|
193
|
+
|
|
194
|
+
if number_to_display < len(items):
|
|
195
|
+
stdscr.addstr(y+1+number_to_display, x+2, f" ... {len(items)-number_to_display} more"[:w-2])
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
return []
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/bin/python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
pane_functions.py
|
|
5
|
+
Functions which are run by a listpick Picker to display data in a pane.
|
|
6
|
+
|
|
7
|
+
Author: GrimAndGreedy
|
|
8
|
+
License: MIT
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import curses
|
|
12
|
+
import os
|
|
13
|
+
from listpick.pane.pane_utils import get_file_attributes, get_graph_string, escape_ansi
|
|
14
|
+
from listpick.pane.get_data import update_file_attributes
|
|
15
|
+
|
|
16
|
+
def right_split_file_attributes(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
17
|
+
"""
|
|
18
|
+
Display file attributes in right pane.
|
|
19
|
+
"""
|
|
20
|
+
if test: return True
|
|
21
|
+
|
|
22
|
+
# Title
|
|
23
|
+
title = "File attributes"
|
|
24
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
25
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
26
|
+
|
|
27
|
+
# Separator
|
|
28
|
+
for j in range(h):
|
|
29
|
+
stdscr.addstr(j+y, x, ' ', curses.color_pair(state["colours_start"]+16))
|
|
30
|
+
|
|
31
|
+
# Display pane count
|
|
32
|
+
pane_count = len(state["right_panes"])
|
|
33
|
+
pane_index = state["right_pane_index"]
|
|
34
|
+
if pane_count > 1:
|
|
35
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
36
|
+
stdscr.addstr(y+h-1, x+w-len(s)-1, s, curses.color_pair(state["colours_start"]+20))
|
|
37
|
+
|
|
38
|
+
# Filename/cursor cell value
|
|
39
|
+
stdscr.addstr(y+2, x+2, cell[:w-3])
|
|
40
|
+
|
|
41
|
+
attributes = get_file_attributes(cell)
|
|
42
|
+
for i, attr in enumerate(attributes):
|
|
43
|
+
stdscr.addstr(y+3+i, x+4, attr[:w-5])
|
|
44
|
+
|
|
45
|
+
return []
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def right_split_file_attributes_dynamic(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
49
|
+
"""
|
|
50
|
+
Display file attributes in right pane.
|
|
51
|
+
"""
|
|
52
|
+
if test: return True
|
|
53
|
+
|
|
54
|
+
# Title
|
|
55
|
+
title = "File attributes"
|
|
56
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
57
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
58
|
+
|
|
59
|
+
# Separator
|
|
60
|
+
for j in range(h):
|
|
61
|
+
stdscr.addstr(j+y, x, ' ', curses.color_pair(state["colours_start"]+16))
|
|
62
|
+
|
|
63
|
+
# Display pane count
|
|
64
|
+
pane_count = len(state["right_panes"])
|
|
65
|
+
pane_index = state["right_pane_index"]
|
|
66
|
+
if pane_count > 1:
|
|
67
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
68
|
+
stdscr.addstr(y+h-1, x+w-len(s)-1, s, curses.color_pair(state["colours_start"]+20))
|
|
69
|
+
|
|
70
|
+
if len(state["indexed_items"]) == 0:
|
|
71
|
+
return []
|
|
72
|
+
|
|
73
|
+
# Filename/cursor cell value
|
|
74
|
+
stdscr.addstr(y+2, x+2, cell[:w-3])
|
|
75
|
+
|
|
76
|
+
# If the cursor-hovered file is different then reload the data
|
|
77
|
+
if data[1] != cell:
|
|
78
|
+
data[:] = update_file_attributes(data, state)
|
|
79
|
+
|
|
80
|
+
# attributes = get_file_attributes(cell)
|
|
81
|
+
if len(data) == 0: return []
|
|
82
|
+
attributes = data[0]
|
|
83
|
+
for i, attr in enumerate(attributes):
|
|
84
|
+
stdscr.addstr(y+3+i, x+4, attr[:w-5])
|
|
85
|
+
|
|
86
|
+
return []
|
|
87
|
+
|
|
88
|
+
def right_split_graph(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
89
|
+
"""
|
|
90
|
+
Display a graph of the data in right pane.
|
|
91
|
+
|
|
92
|
+
data[0] = x_vals
|
|
93
|
+
data[1] = y_vals
|
|
94
|
+
data[2] = id
|
|
95
|
+
"""
|
|
96
|
+
if test: return True
|
|
97
|
+
|
|
98
|
+
# Title
|
|
99
|
+
title = "Graph"
|
|
100
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
101
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
102
|
+
|
|
103
|
+
# Separator
|
|
104
|
+
for j in range(h):
|
|
105
|
+
stdscr.addstr(j+y, x, ' ', curses.color_pair(state["colours_start"]+16))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# Display pane count
|
|
109
|
+
pane_count = len(state["right_panes"])
|
|
110
|
+
pane_index = state["right_pane_index"]
|
|
111
|
+
if pane_count > 1:
|
|
112
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
113
|
+
stdscr.addstr(y+h-1, x+w-len(s)-1, s, curses.color_pair(state["colours_start"]+20))
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
import plotille as plt
|
|
117
|
+
except:
|
|
118
|
+
s = f"No module named 'plotille'"
|
|
119
|
+
stdscr.addstr(y+2, x+2, s[:w-2])
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# x_vals, y_vals = list(range(100)), [x**2 for x in range(100)]
|
|
125
|
+
if data in [[], {}, None]:
|
|
126
|
+
return None
|
|
127
|
+
x_vals, y_vals = data[0], data[1]
|
|
128
|
+
graph_str = get_graph_string(x_vals, y_vals, width=w-3-10, height=h-3)
|
|
129
|
+
for i, s in enumerate(graph_str.split("\n")):
|
|
130
|
+
s = escape_ansi(s)
|
|
131
|
+
stdscr.addstr(y+2+i, x+2, s[:w-2])
|
|
132
|
+
|
|
133
|
+
return []
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def right_split_display_list(stdscr, x, y, w, h, state, row, cell, data: list = [], test: bool = False):
|
|
139
|
+
"""
|
|
140
|
+
data[0]:str = title
|
|
141
|
+
data[1]:list[str] = list of strings to display
|
|
142
|
+
"""
|
|
143
|
+
if test: return True
|
|
144
|
+
|
|
145
|
+
# Title
|
|
146
|
+
title = data[0]
|
|
147
|
+
if len(title) < w: title = f"{title:^{w}}"
|
|
148
|
+
stdscr.addstr(y, x,title[:w], curses.color_pair(state["colours_start"]+4) | curses.A_BOLD)
|
|
149
|
+
|
|
150
|
+
# Separator
|
|
151
|
+
for j in range(h):
|
|
152
|
+
stdscr.addstr(j+y, x, ' ', curses.color_pair(state["colours_start"]+16))
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# Display pane count
|
|
156
|
+
pane_count = len(state["right_panes"])
|
|
157
|
+
pane_index = state["right_pane_index"]
|
|
158
|
+
if pane_count > 1:
|
|
159
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
160
|
+
stdscr.addstr(y+h-1, x+w-len(s)-1, s, curses.color_pair(state["colours_start"]+20))
|
|
161
|
+
|
|
162
|
+
if data in [[], {}, None]:
|
|
163
|
+
return None
|
|
164
|
+
|
|
165
|
+
items = data[1]
|
|
166
|
+
number_to_display = min(len(items), h-3)
|
|
167
|
+
for i in range(number_to_display):
|
|
168
|
+
s = items[i]
|
|
169
|
+
stdscr.addstr(y+1+i, x+2, s[:w-2])
|
|
170
|
+
|
|
171
|
+
if number_to_display < len(items):
|
|
172
|
+
stdscr.addstr(y+1+number_to_display, x+2, f" ... {len(items)-number_to_display} more"[:w-2])
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
return []
|
listpick/ui/build_help.py
CHANGED
|
@@ -68,7 +68,7 @@ def build_help_rows(keys_dict: dict, debug: bool = False) -> list[list[str]]:
|
|
|
68
68
|
|
|
69
69
|
## Key descriptions
|
|
70
70
|
help_descriptions = {
|
|
71
|
-
"refresh": "Refresh
|
|
71
|
+
"refresh": "Refresh data.",
|
|
72
72
|
"help": "Open help.",
|
|
73
73
|
"exit": "Exit picker instance.",
|
|
74
74
|
"full_exit": "Immediate exit to terminal.",
|
|
@@ -119,7 +119,7 @@ def build_help_rows(keys_dict: dict, debug: bool = False) -> list[list[str]]:
|
|
|
119
119
|
"col_hide": "Hide column.",
|
|
120
120
|
"edit": "Edit cell.",
|
|
121
121
|
"edit_picker": "Edit cell from options dialogue.",
|
|
122
|
-
"edit_ipython": "
|
|
122
|
+
"edit_ipython": "Drop to ipython shell with environment as `self`",
|
|
123
123
|
"copy": "Copy selections.",
|
|
124
124
|
"paste": "Paste into picker.",
|
|
125
125
|
"save": "Save selections.",
|
|
@@ -145,17 +145,19 @@ def build_help_rows(keys_dict: dict, debug: bool = False) -> list[list[str]]:
|
|
|
145
145
|
"sheet_next": "Go to the next sheet.",
|
|
146
146
|
"sheet_prev": "Go to the previous sheet.",
|
|
147
147
|
"toggle_right_pane": "Toggle the right pane",
|
|
148
|
-
"cycle_right_pane": "Cycle through right
|
|
148
|
+
"cycle_right_pane": "Cycle through right pane views",
|
|
149
|
+
"toggle_left_pane": "Toggle the left pane",
|
|
150
|
+
"cycle_left_pane": "Cycle through left pane views",
|
|
149
151
|
}
|
|
150
152
|
sections = {
|
|
151
153
|
"Navigation:": [ "cursor_down", "cursor_up", "half_page_up", "half_page_down", "page_up", "page_down", "cursor_bottom", "cursor_top", "five_up", "five_down", "scroll_right", "scroll_left", "scroll_right_25", "scroll_left_25", "scroll_far_right", "scroll_far_left" ],
|
|
152
154
|
"Selection:": [ "toggle_select", "select_all", "select_none", "visual_selection_toggle", "visual_deselection_toggle", "enter" ],
|
|
153
|
-
"UI:": [ "toggle_footer", "redraw_screen", "decrease_lines_per_page", "increase_lines_per_page", "increase_column_width", "decrease_column_width", "notification_toggle", "toggle_right_pane", "cycle_right_pane"],
|
|
155
|
+
"UI:": [ "toggle_footer", "redraw_screen", "decrease_lines_per_page", "increase_lines_per_page", "increase_column_width", "decrease_column_width", "notification_toggle", "toggle_right_pane", "cycle_right_pane", "toggle_left_pane", "cycle_left_pane"],
|
|
154
156
|
"Sort:": [ "cycle_sort_method", "cycle_sort_method_reverse", "cycle_sort_order", ] ,
|
|
155
157
|
"Data manipulation:": [ "delete", "delete_column", "edit", "edit_picker", "edit_ipython", "add_column_before", "add_column_after", "add_row_before", "add_row_after"],
|
|
156
|
-
"Filter and
|
|
158
|
+
"Filter and search:": [ "filter_input", "search_input", "continue_search_forward", "continue_search_backward", ] ,
|
|
157
159
|
"Settings:": [ "settings_input", "settings_options" ],
|
|
158
|
-
"
|
|
160
|
+
"Options and modes:": [ "opts_input", "opts_select", "mode_next", "mode_prev", "pipe_input", "reset_opts", "col_select", "col_select_next", "col_select_prev", "col_hide" ],
|
|
159
161
|
"Save, load, copy and paste:": [ "save", "load", "open", "copy", "paste" ],
|
|
160
162
|
"Misc:": [ "redo", "undo", "refresh", "help", "exit", "full_exit", "move_column_left", "move_column_right" ],
|
|
161
163
|
}
|
listpick/ui/keys.py
CHANGED
|
@@ -51,7 +51,7 @@ picker_keys = {
|
|
|
51
51
|
"continue_search_forward": [ord('n')],
|
|
52
52
|
"continue_search_backward": [ord('N')],
|
|
53
53
|
"cancel": [27], # Escape key
|
|
54
|
-
"opts_input": [ord('
|
|
54
|
+
"opts_input": [ord('e')],
|
|
55
55
|
"opts_select": [ord('o')],
|
|
56
56
|
"mode_next": [9], # Tab key
|
|
57
57
|
"mode_prev": [353], # Shift+Tab key
|
|
@@ -90,6 +90,8 @@ picker_keys = {
|
|
|
90
90
|
# "sheet_prev": [],
|
|
91
91
|
"toggle_right_pane": [ord("'")],
|
|
92
92
|
"cycle_right_pane": [ord('"')],
|
|
93
|
+
"toggle_left_pane": [ord(";")],
|
|
94
|
+
"cycle_left_pane": [ord(':')],
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
|
|
@@ -104,8 +106,8 @@ help_keys = {
|
|
|
104
106
|
"page_down": [curses.KEY_NPAGE, 6],
|
|
105
107
|
"cursor_bottom": [ord('G'), curses.KEY_END],
|
|
106
108
|
"cursor_top": [ord('g'), curses.KEY_HOME],
|
|
107
|
-
"five_up": [ord('K')],
|
|
108
|
-
"five_down": [ord('J')],
|
|
109
|
+
"five_up": [ord('K'), keycodes.META_k],
|
|
110
|
+
"five_down": [ord('J'), keycodes.META_j],
|
|
109
111
|
"redraw_screen": [12], # Ctrl+l
|
|
110
112
|
"cycle_sort_method": [ord('s')],
|
|
111
113
|
"cycle_sort_method_reverse": [ord('S')],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: listpick
|
|
3
|
-
Version: 0.1.16.
|
|
3
|
+
Version: 0.1.16.9
|
|
4
4
|
Summary: Listpick is a powerful TUI data tool for creating TUI apps or viewing/comparing tabulated data.
|
|
5
5
|
Home-page: https://github.com/grimandgreedy/listpick
|
|
6
6
|
Author: Grim
|
|
@@ -41,7 +41,7 @@ Dynamic: requires-dist
|
|
|
41
41
|
Dynamic: requires-python
|
|
42
42
|
Dynamic: summary
|
|
43
43
|
|
|
44
|
-
# listpick
|
|
44
|
+
qq# listpick
|
|
45
45
|
|
|
46
46
|
listpick is a TUI tool which displays a tabulated list of rows and allows the user to operate upon these rows--select, copy, pipe. A very simple concept but also, I hope, a powerful tool that will make it easier for people to develop TUI apps.
|
|
47
47
|
|
|
@@ -102,31 +102,32 @@ The application allows you to:
|
|
|
102
102
|
## Examples
|
|
103
103
|
|
|
104
104
|
|
|
105
|
-
### Identify video duplicates (./examples/data_generation//video_duplicates.toml):
|
|
106
|
-
```python
|
|
107
|
-
listpick -g ./examples/data_generation/video_duplicates.toml
|
|
108
|
-
```
|
|
109
|
-
- From the list of commands in the toml file we generate the properties we will use to identify the duplicates.
|
|
110
105
|
|
|
111
|
-
|
|
106
|
+
### Aria2TUI
|
|
112
107
|
|
|
108
|
+
[Aria2TUI](https://github.com/grimandgreedy/Aria2TUI) is implemented using listpick. This is a good example of how listpick can be used for menus, data viewing, and active data retrieval.
|
|
113
109
|
|
|
114
|
-
|
|
110
|
+
<div align="center"> <img src="assets/aria2tui_graph_screenshot.png" alt="Aria2TUI" width="70%"> </div>
|
|
115
111
|
|
|
116
|
-
|
|
112
|
+
### lpfman
|
|
113
|
+
[lpfman](https://github.com/grimandgreedy/lpfman) is a terminal file manager with extensive column support.
|
|
117
114
|
|
|
115
|
+
<div align="center"> <img src="https://github.com/grimandgreedy/lpfman/blob/master/assets/lpfman_image_preview.png?raw=true" alt="lpfman" width="70%"> </div>
|
|
118
116
|
|
|
119
|
-
### Aria2TUI
|
|
120
117
|
|
|
121
|
-
|
|
118
|
+
### Data generation from toml file
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
listpick -g ./examples/data_generation/video_duplicates.toml
|
|
122
|
+
```
|
|
123
|
+
- From the list of commands in the toml file we generate the properties we will use to identify the duplicates.
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
- In the example file we set the directory and get the files with a simle `eza` (`ls`) command. We could also use `find` or `cat` from a list of files.
|
|
124
126
|
|
|
125
|
-
### lpfman
|
|
126
|
-
[lpfman](https://github.com/grimandgreedy/lpfman) is a basic file manager created for the purposes of illustrating how easy TUI apps can be developed with the use of listpick. In 20 minutes and <100 lines of code we made a very basic file manager.
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
- We get the SHA1 hash to identify identical files; we also get the size, duration, resolution, and bitrate so that we can identify a video duplicate that may have the same duration but a lower resolution.
|
|
129
129
|
|
|
130
|
+
<div align="center"> <img src="assets/file_compare.png" alt="Video Compare" width="70%"> </div>
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
## Description
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
listpick/__init__.py,sha256=ExXc97-bibodH--wlwpQivl0zCNR5D1hvpvrf7OBofU,154
|
|
2
2
|
listpick/__main__.py,sha256=wkCjDdqw093W27yWwnlC3nG_sMRKaIad7hHHWy0RBgY,193
|
|
3
|
-
listpick/listpick_app.py,sha256=
|
|
3
|
+
listpick/listpick_app.py,sha256=t690QmA4_fJ-zi2PhmRrwjMUr2oKOvxEScdDner2mr0,212136
|
|
4
4
|
listpick/pane/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
listpick/pane/get_data.py,sha256=l12mHIb6qoZWIfW5zZZY8K8EqNcyIcRiHgtRaM2CVGs,2735
|
|
6
|
+
listpick/pane/left_pane_functions.py,sha256=SVIW4Ef8uNPBQRk4hL67mEFL3pfgChSFZSMRz06CVzw,5543
|
|
6
7
|
listpick/pane/pane_functions.py,sha256=_dL9jHpd3sT0enL9H_bMcUsBlMELXdtP9dtKFSC2KPQ,5117
|
|
8
|
+
listpick/pane/pane_functions_1.py,sha256=_dL9jHpd3sT0enL9H_bMcUsBlMELXdtP9dtKFSC2KPQ,5117
|
|
7
9
|
listpick/pane/pane_utils.py,sha256=cnuzBH52wdWoKrHR6iMBF4N-uhwpXYpHDnrglk21pqg,2539
|
|
8
10
|
listpick/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
listpick/ui/build_help.py,sha256=
|
|
11
|
+
listpick/ui/build_help.py,sha256=DJm_WxgdfrI6nJ8yjdraBrI6bECvNrXp1vU-kHxCczo,10961
|
|
10
12
|
listpick/ui/draw_screen.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
13
|
listpick/ui/footer.py,sha256=NcdH1uO_ma91m0qCczyQZ3zGrexfkiEnwDf5E4tHSMk,15089
|
|
12
14
|
listpick/ui/help_screen.py,sha256=zbfGIgb-IXtATpl4_Sx7nPbsnRXZ7eiMYlCKGS9EFmw,5608
|
|
13
15
|
listpick/ui/input_field.py,sha256=scJjvmSS0QqeDbCky7_0Zgt35Aki7gezRJkrQROlLg4,30034
|
|
14
|
-
listpick/ui/keys.py,sha256=
|
|
16
|
+
listpick/ui/keys.py,sha256=FlpdWqX1lTP7K6gqHn9jfH2MmuloigeOA7EMzYhaJV8,13845
|
|
15
17
|
listpick/ui/picker_colours.py,sha256=FFsyny_q0mGO6u7B1n7anuReBtP7Jw6LrgX5ycN-MRM,13413
|
|
16
18
|
listpick/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
19
|
listpick/utils/clipboard_operations.py,sha256=ORdNm2kgGbfs51xJSvgJPERgoSmBgT11axuMkvSoP9A,3133
|
|
@@ -31,9 +33,9 @@ listpick/utils/sorting.py,sha256=WZZiVlVA3Zkcpwji3U5SNFlQ14zVEk3cZJtQirBkecQ,532
|
|
|
31
33
|
listpick/utils/table_to_list_of_lists.py,sha256=XBj7eGBDF15BRME-swnoXyOfZWxXCxrXp0pzsBfcJ5g,12224
|
|
32
34
|
listpick/utils/user_input.py,sha256=L3ylI7nnuFM_TP1XKwpiKpxUSkNb2W5cr7mJjTmv_6E,4582
|
|
33
35
|
listpick/utils/utils.py,sha256=nsR6orCBQy3rTXrCweq8cV-RzRVU15v3J9NclPeAOJk,13741
|
|
34
|
-
listpick-0.1.16.
|
|
35
|
-
listpick-0.1.16.
|
|
36
|
-
listpick-0.1.16.
|
|
37
|
-
listpick-0.1.16.
|
|
38
|
-
listpick-0.1.16.
|
|
39
|
-
listpick-0.1.16.
|
|
36
|
+
listpick-0.1.16.9.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
|
|
37
|
+
listpick-0.1.16.9.dist-info/METADATA,sha256=S_kppW9DHyjThJf01PtkuKOA2EAQQVh3J31Oe8iE_Hc,8024
|
|
38
|
+
listpick-0.1.16.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
39
|
+
listpick-0.1.16.9.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
|
|
40
|
+
listpick-0.1.16.9.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
|
|
41
|
+
listpick-0.1.16.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|