listpick 0.1.15.6__py3-none-any.whl → 0.1.15.8__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 +198 -83
- listpick/pane/pane_functions.py +23 -0
- listpick/ui/build_help.py +2 -1
- listpick/ui/keys.py +1 -0
- listpick/ui/picker_colours.py +1 -1
- listpick/utils/utils.py +1 -1
- {listpick-0.1.15.6.dist-info → listpick-0.1.15.8.dist-info}/METADATA +1 -1
- {listpick-0.1.15.6.dist-info → listpick-0.1.15.8.dist-info}/RECORD +12 -12
- {listpick-0.1.15.6.dist-info → listpick-0.1.15.8.dist-info}/WHEEL +0 -0
- {listpick-0.1.15.6.dist-info → listpick-0.1.15.8.dist-info}/entry_points.txt +0 -0
- {listpick-0.1.15.6.dist-info → listpick-0.1.15.8.dist-info}/licenses/LICENSE.txt +0 -0
- {listpick-0.1.15.6.dist-info → listpick-0.1.15.8.dist-info}/top_level.txt +0 -0
listpick/listpick_app.py
CHANGED
|
@@ -23,6 +23,7 @@ import logging
|
|
|
23
23
|
import tty
|
|
24
24
|
import select
|
|
25
25
|
|
|
26
|
+
from listpick.pane.pane_utils import get_file_attributes
|
|
26
27
|
from listpick.ui.picker_colours import get_colours, get_help_colours, get_notification_colours, get_theme_count, get_fallback_colours
|
|
27
28
|
from listpick.utils.options_selectors import default_option_input, output_file_option_selector, default_option_selector
|
|
28
29
|
from listpick.utils.table_to_list_of_lists import *
|
|
@@ -191,16 +192,8 @@ class Picker:
|
|
|
191
192
|
sheet_states: list = [{}],
|
|
192
193
|
|
|
193
194
|
split_right: bool = False,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
split_right_auto_refresh: bool = False,
|
|
197
|
-
split_right_refresh_data: Callable = lambda old_data, arg_dict: [],
|
|
198
|
-
split_right_refresh_data_timer: float = 1.0,
|
|
199
|
-
split_right_data: list = [],
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
195
|
+
right_panes: list = [],
|
|
196
|
+
right_pane_index: int = 0,
|
|
204
197
|
):
|
|
205
198
|
self.stdscr = stdscr
|
|
206
199
|
self.items = items
|
|
@@ -350,13 +343,8 @@ class Picker:
|
|
|
350
343
|
self.sheets = sheets
|
|
351
344
|
|
|
352
345
|
self.split_right = split_right
|
|
353
|
-
self.
|
|
354
|
-
self.
|
|
355
|
-
self.split_right_auto_refresh = split_right_auto_refresh
|
|
356
|
-
self.split_right_refresh_data = split_right_refresh_data
|
|
357
|
-
self.split_right_refresh_data_timer = split_right_refresh_data_timer
|
|
358
|
-
self.split_right_data = split_right_data
|
|
359
|
-
|
|
346
|
+
self.right_panes = right_panes
|
|
347
|
+
self.right_pane_index = right_pane_index
|
|
360
348
|
self.initialise_picker_state(reset_colours=self.reset_colours)
|
|
361
349
|
|
|
362
350
|
# Note: We have to set the footer after initialising the picker state so that the footer can use the get_function_data method
|
|
@@ -426,8 +414,9 @@ class Picker:
|
|
|
426
414
|
## self.top_space
|
|
427
415
|
h, w = self.stdscr.getmaxyx()
|
|
428
416
|
self.term_h, self.term_w = self.stdscr.getmaxyx()
|
|
429
|
-
if self.split_right and
|
|
430
|
-
|
|
417
|
+
if self.split_right and len(self.right_panes):
|
|
418
|
+
proportion = self.right_panes[self.right_pane_index]["proportion"]
|
|
419
|
+
self.rows_w, self.rows_h = int(self.term_w*proportion), self.term_h
|
|
431
420
|
else:
|
|
432
421
|
self.rows_w, self.rows_h = self.term_w, self.term_h
|
|
433
422
|
|
|
@@ -787,8 +776,9 @@ class Picker:
|
|
|
787
776
|
|
|
788
777
|
h, w = self.stdscr.getmaxyx()
|
|
789
778
|
self.term_h, self.term_w = self.stdscr.getmaxyx()
|
|
790
|
-
if self.split_right and
|
|
791
|
-
|
|
779
|
+
if self.split_right and len(self.right_panes):
|
|
780
|
+
proportion = self.right_panes[self.right_pane_index]["proportion"]
|
|
781
|
+
self.rows_w, self.rows_h = int(self.term_w*proportion), self.term_h
|
|
792
782
|
else:
|
|
793
783
|
self.rows_w, self.rows_h = self.term_w, self.term_h
|
|
794
784
|
|
|
@@ -881,15 +871,69 @@ class Picker:
|
|
|
881
871
|
# Highlight sort column
|
|
882
872
|
try:
|
|
883
873
|
if self.selected_column != None and self.selected_column not in self.hidden_columns:
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
874
|
+
# start of string is on screen
|
|
875
|
+
col_width = self.column_widths[self.selected_column]
|
|
876
|
+
number = f"{self.selected_column}. " if self.number_columns else ""
|
|
877
|
+
col_str = self.header[self.selected_column][:self.column_widths[self.selected_column]-len(number)]
|
|
878
|
+
highlighted_col_str = (number+f"{col_str:^{self.column_widths[self.selected_column]-len(number)}}") + self.separator
|
|
879
|
+
|
|
880
|
+
# Start of selected column is on the screen
|
|
881
|
+
if self.leftmost_char <= len(up_to_selected_col) and self.leftmost_char+self.rows_w-self.startx > len(up_to_selected_col):
|
|
882
|
+
x_pos = len(up_to_selected_col) - self.leftmost_char + self.startx
|
|
883
|
+
|
|
884
|
+
# Whole cell of the selected column is on the screen
|
|
885
|
+
if len(up_to_selected_col)+col_width - self.leftmost_char < self.rows_w-self.startx:
|
|
886
|
+
disp_str = highlighted_col_str
|
|
887
|
+
|
|
888
|
+
# Start of the cell is on the screen, but the end of the cell is not
|
|
889
|
+
else:
|
|
890
|
+
overflow = (len(up_to_selected_col)+len(highlighted_col_str)) - (self.leftmost_char+self.rows_w - self.startx)
|
|
891
|
+
disp_str = highlighted_col_str[:-overflow]
|
|
892
|
+
|
|
893
|
+
self.stdscr.addstr(header_ypos, x_pos , disp_str, curses.color_pair(self.colours_start+19) | curses.A_BOLD)
|
|
894
|
+
# Start of the cell is to the right of the screen
|
|
895
|
+
elif self.leftmost_char+self.rows_w <= len(up_to_selected_col):
|
|
896
|
+
pass
|
|
897
|
+
# The end of the cell is on the screen, the start of the cell is not
|
|
898
|
+
elif 0 <= len(up_to_selected_col)+col_width - self.leftmost_char <= self.rows_w :
|
|
899
|
+
x_pos = self.startx
|
|
900
|
+
beg = self.leftmost_char - len(up_to_selected_col)
|
|
901
|
+
disp_str = highlighted_col_str[beg:]
|
|
902
|
+
self.stdscr.addstr(header_ypos, x_pos , disp_str, curses.color_pair(self.colours_start+19) | curses.A_BOLD)
|
|
903
|
+
# The middle of the cell is on the screen, the start and end of the cell are not
|
|
904
|
+
elif self.leftmost_char <= len(up_to_selected_col) + col_width//2 <= self.leftmost_char+self.rows_w:
|
|
905
|
+
beg = self.leftmost_char - len(up_to_selected_col)
|
|
906
|
+
overflow = (len(up_to_selected_col)+len(highlighted_col_str)) - (self.leftmost_char+self.rows_w)
|
|
907
|
+
disp_str = highlighted_col_str[beg:-overflow]
|
|
908
|
+
|
|
909
|
+
x_pos = self.startx
|
|
910
|
+
self.stdscr.addstr(header_ypos, x_pos , disp_str, curses.color_pair(self.colours_start+19) | curses.A_BOLD)
|
|
911
|
+
# The cell is to the left of the screen
|
|
912
|
+
else:
|
|
913
|
+
pass
|
|
914
|
+
|
|
915
|
+
# elif self.leftmost_char:
|
|
916
|
+
# os.system(f"notify-send 'cell is to the right of the screen'")
|
|
917
|
+
|
|
918
|
+
#
|
|
919
|
+
#
|
|
920
|
+
# if len(self.header) > 1 and (len(up_to_selected_col)-self.leftmost_char) < self.rows_w:
|
|
921
|
+
# number = f"{self.selected_column}. " if self.number_columns else ""
|
|
922
|
+
# # number = f"{intStringToExponentString(self.selected_column)}. " if self.number_columns else ""
|
|
923
|
+
# # self.startx + len(up_to_selected_col) - self.leftmost_char
|
|
924
|
+
# highlighed_col_startx = max(self.startx, self.startx + len(up_to_selected_col) - self.leftmost_char)
|
|
925
|
+
#
|
|
926
|
+
#
|
|
927
|
+
# col_str = self.header[self.selected_column][:self.column_widths[self.selected_column]-len(number)]
|
|
928
|
+
# highlighted_col_str = (number+f"{col_str:^{self.column_widths[self.selected_column]}}") + self.separator
|
|
929
|
+
# end_of_highlighted_col_str = self.rows_w-(highlighed_col_startx+len(highlighted_col_str)) if (highlighed_col_startx+len(highlighted_col_str)) > self.rows_w else len(highlighted_col_str)
|
|
930
|
+
# if (highlighed_col_startx+len(highlighted_col_str)) > self.rows_w:
|
|
931
|
+
# end_of_highlighted_col_str = self.rows_w-(highlighed_col_startx+len(highlighted_col_str))
|
|
932
|
+
# else:
|
|
933
|
+
# end_of_highlighted_col_str = len(highlighted_col_str)
|
|
934
|
+
#
|
|
935
|
+
# start_of_highlighted_col_str = max(self.leftmost_char - len(up_to_selected_col), 0)
|
|
936
|
+
# self.stdscr.addstr(header_ypos, highlighed_col_startx , highlighted_col_str[start_of_highlighted_col_str:end_of_highlighted_col_str][:self.column_widths[self.selected_column]+len(self.separator)], curses.color_pair(self.colours_start+19) | curses.A_BOLD)
|
|
893
937
|
except:
|
|
894
938
|
pass
|
|
895
939
|
|
|
@@ -902,11 +946,14 @@ class Picker:
|
|
|
902
946
|
else:
|
|
903
947
|
self.stdscr.addstr(y, 0, f" {self.indexed_items[idx][0]} ", curses.color_pair(self.colours_start+4) | curses.A_BOLD)
|
|
904
948
|
|
|
905
|
-
|
|
949
|
+
|
|
950
|
+
def highlight_cell(row: int, col:int, visible_column_widths, colour_pair_number: int = 5, y:int = 0):
|
|
951
|
+
|
|
906
952
|
cell_pos = sum(visible_column_widths[:col])+col*len(self.separator)-self.leftmost_char + self.startx
|
|
907
953
|
# cell_width = self.column_widths[self.selected_column]
|
|
908
954
|
cell_width = visible_column_widths[col] + len(self.separator)
|
|
909
955
|
cell_max_width = self.rows_w-cell_pos
|
|
956
|
+
|
|
910
957
|
try:
|
|
911
958
|
# Start of cell is on screen
|
|
912
959
|
if self.startx <= cell_pos <= self.rows_w:
|
|
@@ -916,17 +963,23 @@ class Picker:
|
|
|
916
963
|
else:
|
|
917
964
|
cell_value = self.indexed_items[row][1][col] + self.separator
|
|
918
965
|
# cell_value = cell_value[:min(cell_width, cell_max_width)-len(self.separator)]
|
|
919
|
-
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)
|
|
920
|
-
cell_value = cell_value + self.separator
|
|
966
|
+
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width), self.centre_in_cols, self.unicode_char_width)
|
|
967
|
+
# cell_value = cell_value + self.separator
|
|
921
968
|
# cell_value = cell_value
|
|
922
969
|
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width), self.centre_in_cols, self.unicode_char_width)
|
|
923
970
|
self.stdscr.addstr(y, cell_pos, cell_value, curses.color_pair(self.colours_start+colour_pair_number) | curses.A_BOLD)
|
|
924
971
|
# Part of the cell is on screen
|
|
925
|
-
elif self.startx <= cell_pos+cell_width
|
|
972
|
+
elif self.startx <= cell_pos+cell_width and cell_pos < (self.rows_w):
|
|
926
973
|
cell_start = self.startx - cell_pos
|
|
927
|
-
self.stdscr.addstr(y, self.startx, ' '*(cell_width-cell_start), curses.color_pair(self.colours_start+colour_pair_number))
|
|
928
|
-
cell_value = self.indexed_items[row][1][col]
|
|
974
|
+
# self.stdscr.addstr(y, self.startx, ' '*(cell_width-cell_start), curses.color_pair(self.colours_start+colour_pair_number))
|
|
975
|
+
cell_value = self.indexed_items[row][1][col]
|
|
976
|
+
cell_value = f"{cell_value:^{self.column_widths[col]}}"
|
|
977
|
+
|
|
978
|
+
cell_value = cell_value[cell_start:visible_column_widths[col]][:self.rows_w-self.startx]
|
|
929
979
|
self.stdscr.addstr(y, self.startx, cell_value, curses.color_pair(self.colours_start+colour_pair_number) | curses.A_BOLD)
|
|
980
|
+
else:
|
|
981
|
+
pass
|
|
982
|
+
# if colour_pair_number == 5:
|
|
930
983
|
except:
|
|
931
984
|
pass
|
|
932
985
|
|
|
@@ -1009,7 +1062,17 @@ class Picker:
|
|
|
1009
1062
|
# row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))
|
|
1010
1063
|
row_str_orig = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
|
|
1011
1064
|
row_str_left_adj = clip_left(row_str_orig, self.leftmost_char)
|
|
1012
|
-
|
|
1065
|
+
# rowstr off screen
|
|
1066
|
+
# if self.leftmost_char > len(row_str_orig):
|
|
1067
|
+
# trunc_width = 0
|
|
1068
|
+
if self.leftmost_char + (self.rows_w-self.startx) <= len(row_str_orig):
|
|
1069
|
+
trunc_width = self.rows_w-self.startx
|
|
1070
|
+
elif self.leftmost_char <= len(row_str_orig):
|
|
1071
|
+
trunc_width = len(row_str_orig) - self.leftmost_char
|
|
1072
|
+
else:
|
|
1073
|
+
trunc_width = 0
|
|
1074
|
+
|
|
1075
|
+
row_str = truncate_to_display_width(row_str_left_adj, trunc_width, self.unicode_char_width)
|
|
1013
1076
|
# row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))[self.leftmost_char:]
|
|
1014
1077
|
|
|
1015
1078
|
## Display the standard row
|
|
@@ -1025,21 +1088,21 @@ class Picker:
|
|
|
1025
1088
|
# self.selected_cells_by_row = get_selected_cells_by_row(self.cell_selections)
|
|
1026
1089
|
if item[0] in self.selected_cells_by_row:
|
|
1027
1090
|
for j in self.selected_cells_by_row[item[0]]:
|
|
1028
|
-
highlight_cell(idx, j, visible_column_widths, colour_pair_number=25)
|
|
1091
|
+
highlight_cell(idx, j, visible_column_widths, colour_pair_number=25, y=y)
|
|
1029
1092
|
|
|
1030
1093
|
# Visually selected
|
|
1031
1094
|
if self.is_selecting:
|
|
1032
1095
|
if self.start_selection <= idx <= self.cursor_pos or self.start_selection >= idx >= self.cursor_pos:
|
|
1033
1096
|
x_interval = range(min(self.start_selection_col, self.selected_column), max(self.start_selection_col, self.selected_column)+1)
|
|
1034
1097
|
for col in x_interval:
|
|
1035
|
-
highlight_cell(idx, col, visible_column_widths, colour_pair_number=25)
|
|
1098
|
+
highlight_cell(idx, col, visible_column_widths, colour_pair_number=25, y=y)
|
|
1036
1099
|
|
|
1037
1100
|
# Visually deslected
|
|
1038
1101
|
if self.is_deselecting:
|
|
1039
1102
|
if self.start_selection >= idx >= self.cursor_pos or self.start_selection <= idx <= self.cursor_pos:
|
|
1040
1103
|
x_interval = range(min(self.start_selection_col, self.selected_column), max(self.start_selection_col, self.selected_column)+1)
|
|
1041
1104
|
for col in x_interval:
|
|
1042
|
-
highlight_cell(idx, col, visible_column_widths, colour_pair_number=26)
|
|
1105
|
+
highlight_cell(idx, col, visible_column_widths, colour_pair_number=26, y=y)
|
|
1043
1106
|
# Higlight cursor row and selected rows
|
|
1044
1107
|
elif self.highlight_full_row:
|
|
1045
1108
|
if self.selections[item[0]]:
|
|
@@ -1072,7 +1135,7 @@ class Picker:
|
|
|
1072
1135
|
# Draw cursor
|
|
1073
1136
|
if idx == self.cursor_pos:
|
|
1074
1137
|
if self.cell_cursor:
|
|
1075
|
-
highlight_cell(idx, self.selected_column, visible_column_widths)
|
|
1138
|
+
highlight_cell(idx, self.selected_column, visible_column_widths, colour_pair_number=5, y=y)
|
|
1076
1139
|
else:
|
|
1077
1140
|
self.stdscr.addstr(y, self.startx, row_str[:min(self.rows_w-self.startx, visible_columns_total_width)], curses.color_pair(self.colours_start+5) | curses.A_BOLD)
|
|
1078
1141
|
|
|
@@ -1116,8 +1179,10 @@ class Picker:
|
|
|
1116
1179
|
self.stdscr.addstr(self.term_h - 1, self.term_w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
|
|
1117
1180
|
self.stdscr.addstr(self.term_h - 1, self.term_w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
|
|
1118
1181
|
|
|
1119
|
-
if self.split_right and
|
|
1120
|
-
|
|
1182
|
+
if self.split_right and len(self.right_panes):
|
|
1183
|
+
draw_pane = self.right_panes[self.right_pane_index]["display"]
|
|
1184
|
+
data = self.right_panes[self.right_pane_index]["data"]
|
|
1185
|
+
draw_pane(
|
|
1121
1186
|
self.stdscr,
|
|
1122
1187
|
x = self.rows_w,
|
|
1123
1188
|
y = self.top_space - int(bool(self.show_header and self.header)),
|
|
@@ -1126,7 +1191,7 @@ class Picker:
|
|
|
1126
1191
|
state = self.get_function_data(),
|
|
1127
1192
|
row = self.indexed_items[self.cursor_pos] if self.indexed_items else [],
|
|
1128
1193
|
cell = self.indexed_items[self.cursor_pos][1][self.selected_column] if self.indexed_items else "",
|
|
1129
|
-
data=
|
|
1194
|
+
data=data,
|
|
1130
1195
|
)
|
|
1131
1196
|
|
|
1132
1197
|
self.stdscr.refresh()
|
|
@@ -1290,12 +1355,9 @@ class Picker:
|
|
|
1290
1355
|
"sheet_name": self.sheet_name,
|
|
1291
1356
|
"sheet_states": self.sheet_states,
|
|
1292
1357
|
"split_right": self.split_right,
|
|
1293
|
-
"
|
|
1294
|
-
"
|
|
1295
|
-
|
|
1296
|
-
"split_right_refresh_data_timer": self.split_right_refresh_data_timer,
|
|
1297
|
-
"split_right_refresh_data": self.split_right_refresh_data,
|
|
1298
|
-
"split_right_data": self.split_right_data,
|
|
1358
|
+
"right_panes": self.right_panes,
|
|
1359
|
+
"right_pane_index": self.right_pane_index,
|
|
1360
|
+
|
|
1299
1361
|
}
|
|
1300
1362
|
return function_data
|
|
1301
1363
|
|
|
@@ -1331,8 +1393,6 @@ class Picker:
|
|
|
1331
1393
|
"centre_in_cols",
|
|
1332
1394
|
"centre_in_terminal",
|
|
1333
1395
|
"split_right",
|
|
1334
|
-
"split_right_proportion",
|
|
1335
|
-
"split_right_function",
|
|
1336
1396
|
]
|
|
1337
1397
|
|
|
1338
1398
|
for var in variables:
|
|
@@ -1426,6 +1486,7 @@ class Picker:
|
|
|
1426
1486
|
"number_columns": False,
|
|
1427
1487
|
"reset_colours": False,
|
|
1428
1488
|
"split_right": False,
|
|
1489
|
+
"cell_cursor": False,
|
|
1429
1490
|
}
|
|
1430
1491
|
while True:
|
|
1431
1492
|
h, w = stdscr.getmaxyx()
|
|
@@ -1457,6 +1518,8 @@ class Picker:
|
|
|
1457
1518
|
|
|
1458
1519
|
if not message: message = "!!"
|
|
1459
1520
|
submenu_items = [" "+message[i*message_width:(i+1)*message_width] for i in range(len(message)//message_width+1)]
|
|
1521
|
+
for i in range(len(submenu_items)):
|
|
1522
|
+
submenu_items[i] = f"{submenu_items[i]:^{message_width}}"
|
|
1460
1523
|
|
|
1461
1524
|
notification_remap_keys = {
|
|
1462
1525
|
curses.KEY_RESIZE: curses.KEY_F5,
|
|
@@ -1482,6 +1545,7 @@ class Picker:
|
|
|
1482
1545
|
"cancel_is_back": True,
|
|
1483
1546
|
"reset_colours": False,
|
|
1484
1547
|
"split_right": False,
|
|
1548
|
+
"cell_cursor": False,
|
|
1485
1549
|
|
|
1486
1550
|
}
|
|
1487
1551
|
OptionPicker = Picker(submenu_win, **notification_data)
|
|
@@ -1622,6 +1686,9 @@ class Picker:
|
|
|
1622
1686
|
elif setting == "pane":
|
|
1623
1687
|
self.toggle_right_pane()
|
|
1624
1688
|
|
|
1689
|
+
elif setting == "pane_cycle":
|
|
1690
|
+
self.cycle_right_pane()
|
|
1691
|
+
|
|
1625
1692
|
elif setting.startswith("cwd="):
|
|
1626
1693
|
os.chdir(os.path.expandvars(os.path.expanduser(setting[len("cwd="):])))
|
|
1627
1694
|
elif setting.startswith("hl"):
|
|
@@ -2240,10 +2307,16 @@ class Picker:
|
|
|
2240
2307
|
self.load_sheet(self.loaded_file, sheet_number=self.sheet_index)
|
|
2241
2308
|
|
|
2242
2309
|
def toggle_right_pane(self):
|
|
2243
|
-
if
|
|
2310
|
+
if len(self.right_panes):
|
|
2244
2311
|
self.split_right = not self.split_right
|
|
2312
|
+
if self.right_panes[self.right_pane_index]["data"] in [[], None, {}]:
|
|
2313
|
+
self.right_panes[self.right_pane_index]["data"] = self.right_panes[self.right_pane_index]["get_data"](self.right_panes[self.right_pane_index]["data"], self.get_function_data())
|
|
2245
2314
|
|
|
2246
2315
|
|
|
2316
|
+
def cycle_right_pane(self, increment=1):
|
|
2317
|
+
if len(self.right_panes) > 1:
|
|
2318
|
+
self.right_pane_index = (self.right_pane_index+1)%len(self.right_panes)
|
|
2319
|
+
|
|
2247
2320
|
def run(self) -> Tuple[list[int], str, dict]:
|
|
2248
2321
|
""" Run the picker. """
|
|
2249
2322
|
self.logger.info(f"function: run()")
|
|
@@ -2257,7 +2330,7 @@ class Picker:
|
|
|
2257
2330
|
|
|
2258
2331
|
initial_time = time.time()
|
|
2259
2332
|
initial_time_footer = time.time()-self.footer_timer
|
|
2260
|
-
initial_split_time = time.time()-
|
|
2333
|
+
initial_split_time = time.time()-200
|
|
2261
2334
|
|
|
2262
2335
|
if self.startup_notification:
|
|
2263
2336
|
self.notification(self.stdscr, message=self.startup_notification)
|
|
@@ -2293,8 +2366,9 @@ class Picker:
|
|
|
2293
2366
|
|
|
2294
2367
|
h, w = self.stdscr.getmaxyx()
|
|
2295
2368
|
self.term_h, self.term_w = self.stdscr.getmaxyx()
|
|
2296
|
-
if self.split_right and
|
|
2297
|
-
|
|
2369
|
+
if self.split_right and len(self.right_panes):
|
|
2370
|
+
proportion = self.right_panes[self.right_pane_index]["proportion"]
|
|
2371
|
+
self.rows_w, self.rows_h = int(self.term_w*proportion), self.term_h
|
|
2298
2372
|
else:
|
|
2299
2373
|
self.rows_w, self.rows_h = self.term_w, self.term_h
|
|
2300
2374
|
def terminal_resized(old_w, old_h) -> bool:
|
|
@@ -2318,8 +2392,10 @@ class Picker:
|
|
|
2318
2392
|
|
|
2319
2393
|
h, w = self.stdscr.getmaxyx()
|
|
2320
2394
|
self.term_h, self.term_w = self.stdscr.getmaxyx()
|
|
2321
|
-
|
|
2322
|
-
|
|
2395
|
+
|
|
2396
|
+
if self.split_right and len(self.right_panes):
|
|
2397
|
+
proportion = self.right_panes[self.right_pane_index]["proportion"]
|
|
2398
|
+
self.rows_w, self.rows_h = int(self.term_w*proportion), self.term_h
|
|
2323
2399
|
else:
|
|
2324
2400
|
self.rows_w, self.rows_h = self.term_w, self.term_h
|
|
2325
2401
|
|
|
@@ -2374,8 +2450,10 @@ class Picker:
|
|
|
2374
2450
|
initial_time_footer = time.time()
|
|
2375
2451
|
self.draw_screen(self.indexed_items, self.highlights)
|
|
2376
2452
|
|
|
2377
|
-
if self.split_right and self.
|
|
2378
|
-
|
|
2453
|
+
if self.split_right and len(self.right_panes) and self.right_panes[self.right_pane_index]["auto_refresh"] and ((time.time() - initial_split_time) > self.right_panes[self.right_pane_index]["refresh_time"]):
|
|
2454
|
+
get_data = self.right_panes[self.right_pane_index]["get_data"]
|
|
2455
|
+
data = self.right_panes[self.right_pane_index]["data"]
|
|
2456
|
+
self.right_panes[self.right_pane_index]["data"] = get_data(data, self.get_function_data())
|
|
2379
2457
|
initial_split_time = time.time()
|
|
2380
2458
|
|
|
2381
2459
|
if self.check_key("help", key, self.keys_dict):
|
|
@@ -2870,8 +2948,8 @@ class Picker:
|
|
|
2870
2948
|
self.logger.info(f"key_function scroll_right")
|
|
2871
2949
|
if len(self.indexed_items):
|
|
2872
2950
|
row_width = sum(self.column_widths) + len(self.separator)*(len(self.column_widths)-1)
|
|
2873
|
-
if row_width-self.leftmost_char >= self.rows_w-self.startx:
|
|
2874
|
-
self.leftmost_char
|
|
2951
|
+
if row_width-self.leftmost_char >= self.rows_w-self.startx-5:
|
|
2952
|
+
self.leftmost_char += 5
|
|
2875
2953
|
|
|
2876
2954
|
elif self.check_key("scroll_left", key, self.keys_dict):
|
|
2877
2955
|
self.logger.info(f"key_function scroll_left")
|
|
@@ -2885,17 +2963,18 @@ class Picker:
|
|
|
2885
2963
|
elif self.check_key("scroll_far_right", key, self.keys_dict):
|
|
2886
2964
|
self.logger.info(f"key_function scroll_far_right")
|
|
2887
2965
|
longest_row_str_len = 0
|
|
2888
|
-
rows = self.get_visible_rows()
|
|
2889
|
-
for i in range(len(rows)):
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2966
|
+
# rows = self.get_visible_rows()
|
|
2967
|
+
# for i in range(len(rows)):
|
|
2968
|
+
# item = rows[i]
|
|
2969
|
+
# row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
|
|
2970
|
+
# if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
|
|
2971
|
+
longest_row_str_len = sum(self.column_widths) + (len(self.column_widths)-1)*len(self.separator)
|
|
2893
2972
|
# for i in range(len(self.indexed_items)):
|
|
2894
2973
|
# item = self.indexed_items[i]
|
|
2895
2974
|
# row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
|
|
2896
2975
|
# if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
|
|
2897
2976
|
# self.notification(self.stdscr, f"{longest_row_str_len}")
|
|
2898
|
-
self.leftmost_char = max(0, longest_row_str_len-self.rows_w+2+self.startx)
|
|
2977
|
+
self.leftmost_char = max(0, longest_row_str_len-self.rows_w+2+self.startx+5)
|
|
2899
2978
|
if len(self.items):
|
|
2900
2979
|
self.selected_column = len(self.items[0])-1
|
|
2901
2980
|
|
|
@@ -2990,7 +3069,6 @@ class Picker:
|
|
|
2990
3069
|
|
|
2991
3070
|
self.calculate_section_sizes()
|
|
2992
3071
|
self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=self.rows_w, unicode_char_width=self.unicode_char_width)
|
|
2993
|
-
|
|
2994
3072
|
self.draw_screen(self.indexed_items, self.highlights)
|
|
2995
3073
|
|
|
2996
3074
|
|
|
@@ -3243,6 +3321,9 @@ class Picker:
|
|
|
3243
3321
|
elif self.check_key("toggle_right_pane", key, self.keys_dict):
|
|
3244
3322
|
self.toggle_right_pane()
|
|
3245
3323
|
|
|
3324
|
+
elif self.check_key("cycle_right_pane", key, self.keys_dict):
|
|
3325
|
+
self.cycle_right_pane()
|
|
3326
|
+
|
|
3246
3327
|
elif self.check_key("pipe_input", key, self.keys_dict):
|
|
3247
3328
|
self.logger.info(f"key_function pipe_input")
|
|
3248
3329
|
# usrtxt = "xargs -d '\n' -I{} "
|
|
@@ -3766,20 +3847,54 @@ def main() -> None:
|
|
|
3766
3847
|
# function_data["debug"] = True
|
|
3767
3848
|
# function_data["debug_level"] = 1
|
|
3768
3849
|
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3850
|
+
function_data["split_right"] = False
|
|
3851
|
+
function_data["right_panes"] = [
|
|
3852
|
+
# Graph or random numbers generated each second
|
|
3853
|
+
{
|
|
3854
|
+
"proportion": 2/3,
|
|
3855
|
+
"auto_refresh": True,
|
|
3856
|
+
"get_data": data_refresh_randint,
|
|
3857
|
+
"display": right_split_graph,
|
|
3858
|
+
"data": [],
|
|
3859
|
+
"refresh_time": 1.0,
|
|
3860
|
+
},
|
|
3861
|
+
# list of numbers
|
|
3862
|
+
{
|
|
3863
|
+
"proportion": 2/3,
|
|
3864
|
+
"auto_refresh": False,
|
|
3865
|
+
"get_data": data_refresh_randint_title,
|
|
3866
|
+
"display": right_split_display_list,
|
|
3867
|
+
"data": ["Files", [str(x) for x in range(100)]],
|
|
3868
|
+
"refresh_time": 1.0,
|
|
3869
|
+
},
|
|
3870
|
+
# File attribures
|
|
3871
|
+
{
|
|
3872
|
+
"proportion": 2/3,
|
|
3873
|
+
"auto_refresh": False,
|
|
3874
|
+
"get_data": lambda data, state: [],
|
|
3875
|
+
"display": right_split_file_attributes,
|
|
3876
|
+
"data": ["Files", [str(x) for x in range(100)]],
|
|
3877
|
+
"refresh_time": 1.0,
|
|
3878
|
+
},
|
|
3879
|
+
# List of random numbers generated each second
|
|
3880
|
+
{
|
|
3881
|
+
"proportion": 1/2,
|
|
3882
|
+
"auto_refresh": True,
|
|
3883
|
+
"get_data": data_refresh_randint_title,
|
|
3884
|
+
"display": right_split_display_list,
|
|
3885
|
+
"data": ["Files", []],
|
|
3886
|
+
"refresh_time": 0.1,
|
|
3887
|
+
},
|
|
3888
|
+
# Nopane
|
|
3889
|
+
{
|
|
3890
|
+
"proportion": 1/3,
|
|
3891
|
+
"auto_refresh": False,
|
|
3892
|
+
"get_data": lambda data, state: [],
|
|
3893
|
+
"display": lambda scr, x, y, w, h, state, row, cell, data: [],
|
|
3894
|
+
"data": ["Files", []],
|
|
3895
|
+
"refresh_time": 0.1,
|
|
3896
|
+
},
|
|
3897
|
+
]
|
|
3783
3898
|
|
|
3784
3899
|
stdscr = start_curses()
|
|
3785
3900
|
try:
|
listpick/pane/pane_functions.py
CHANGED
|
@@ -29,6 +29,12 @@ def right_split_file_attributes(stdscr, x, y, w, h, state, row, cell, past_data:
|
|
|
29
29
|
for j in range(h):
|
|
30
30
|
stdscr.addstr(j+y, x, ' ', curses.color_pair(state["colours_start"]+16))
|
|
31
31
|
|
|
32
|
+
# Display pane count
|
|
33
|
+
pane_count = len(state["right_panes"])
|
|
34
|
+
pane_index = state["right_pane_index"]
|
|
35
|
+
if pane_count > 1:
|
|
36
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
37
|
+
stdscr.addstr(y+h-1, x+w-len(s)-1, s, curses.color_pair(state["colours_start"]+20))
|
|
32
38
|
|
|
33
39
|
# Filename/cursor cell value
|
|
34
40
|
stdscr.addstr(y+2, x+2, cell[:w-3])
|
|
@@ -58,6 +64,14 @@ def right_split_graph(stdscr, x, y, w, h, state, row, cell, past_data: list = []
|
|
|
58
64
|
for j in range(h):
|
|
59
65
|
stdscr.addstr(j+y, x, ' ', curses.color_pair(state["colours_start"]+16))
|
|
60
66
|
|
|
67
|
+
|
|
68
|
+
# Display pane count
|
|
69
|
+
pane_count = len(state["right_panes"])
|
|
70
|
+
pane_index = state["right_pane_index"]
|
|
71
|
+
if pane_count > 1:
|
|
72
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
73
|
+
stdscr.addstr(y+h-1, x+w-len(s)-1, s, curses.color_pair(state["colours_start"]+20))
|
|
74
|
+
|
|
61
75
|
try:
|
|
62
76
|
import plotille as plt
|
|
63
77
|
except:
|
|
@@ -66,6 +80,7 @@ def right_split_graph(stdscr, x, y, w, h, state, row, cell, past_data: list = []
|
|
|
66
80
|
return None
|
|
67
81
|
|
|
68
82
|
|
|
83
|
+
|
|
69
84
|
# x_vals, y_vals = list(range(100)), [x**2 for x in range(100)]
|
|
70
85
|
if data in [[], {}, None]:
|
|
71
86
|
return None
|
|
@@ -96,6 +111,14 @@ def right_split_display_list(stdscr, x, y, w, h, state, row, cell, past_data: li
|
|
|
96
111
|
for j in range(h):
|
|
97
112
|
stdscr.addstr(j+y, x, ' ', curses.color_pair(state["colours_start"]+16))
|
|
98
113
|
|
|
114
|
+
|
|
115
|
+
# Display pane count
|
|
116
|
+
pane_count = len(state["right_panes"])
|
|
117
|
+
pane_index = state["right_pane_index"]
|
|
118
|
+
if pane_count > 1:
|
|
119
|
+
s = f" {pane_index+1}/{pane_count} "
|
|
120
|
+
stdscr.addstr(y+h-1, x+w-len(s)-1, s, curses.color_pair(state["colours_start"]+20))
|
|
121
|
+
|
|
99
122
|
if data in [[], {}, None]:
|
|
100
123
|
return None
|
|
101
124
|
|
listpick/ui/build_help.py
CHANGED
|
@@ -143,11 +143,12 @@ def build_help_rows(keys_dict: dict, debug: bool = False) -> list[list[str]]:
|
|
|
143
143
|
"sheet_next": "Go to the next sheet.",
|
|
144
144
|
"sheet_prev": "Go to the previous sheet.",
|
|
145
145
|
"toggle_right_pane": "Toggle the right pane",
|
|
146
|
+
"cycle_right_pane": "Cycle through right panes",
|
|
146
147
|
}
|
|
147
148
|
sections = {
|
|
148
149
|
"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_far_right", "scroll_far_left" ],
|
|
149
150
|
"Selection:": [ "toggle_select", "select_all", "select_none", "visual_selection_toggle", "visual_deselection_toggle", "enter" ],
|
|
150
|
-
"UI:": [ "toggle_footer", "redraw_screen", "decrease_lines_per_page", "increase_lines_per_page", "increase_column_width", "decrease_column_width", "notification_toggle", "toggle_right_pane"],
|
|
151
|
+
"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"],
|
|
151
152
|
"Sort:": [ "cycle_sort_method", "cycle_sort_method_reverse", "cycle_sort_order", ] ,
|
|
152
153
|
"Data manipulation:": [ "delete", "delete_column", "edit", "edit_picker", "edit_ipython", "add_column_before", "add_column_after", "add_row_before", "add_row_after"],
|
|
153
154
|
"Filter and sort:": [ "filter_input", "search_input", "continue_search_forward", "continue_search_backward", ] ,
|
listpick/ui/keys.py
CHANGED
listpick/ui/picker_colours.py
CHANGED
|
@@ -340,7 +340,7 @@ def get_notification_colours(pick:int=0) -> Dict[str, int]:
|
|
|
340
340
|
else:
|
|
341
341
|
colours['background'] = 237
|
|
342
342
|
colours['unselected_bg'] = 237
|
|
343
|
-
colours['cursor_bg'] =
|
|
343
|
+
colours['cursor_bg'] = 238
|
|
344
344
|
colours['selected_bg'] = 237
|
|
345
345
|
|
|
346
346
|
return colours
|
listpick/utils/utils.py
CHANGED
|
@@ -34,7 +34,7 @@ def clip_left(text, n):
|
|
|
34
34
|
if width + char_width > n:
|
|
35
35
|
return text[i:]
|
|
36
36
|
width += char_width
|
|
37
|
-
return
|
|
37
|
+
return ""
|
|
38
38
|
|
|
39
39
|
def truncate_to_display_width(text: str, max_column_width: int, centre=False, unicode_char_width: bool = True) -> str:
|
|
40
40
|
"""
|
|
@@ -1,17 +1,17 @@
|
|
|
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=NAD1T5i2CDD_WOvHk5ZjJXRpdeN_76ZVRQA8cveK4hk,199678
|
|
4
4
|
listpick/pane/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
listpick/pane/get_data.py,sha256=21PTDXt9HP-4vZV4QUM8sidTqDEaKnKCDshl3-cSRCo,2255
|
|
6
|
-
listpick/pane/pane_functions.py,sha256=
|
|
6
|
+
listpick/pane/pane_functions.py,sha256=Hpc6wSFeiTmQTyO6n13muenarZMvzFw0OCmjJJy2lTY,3910
|
|
7
7
|
listpick/pane/pane_utils.py,sha256=tMp8KlFng6ZQgNjd8iFrl1zWZLPXMH_Y1A_QeuQYAk0,2537
|
|
8
8
|
listpick/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
listpick/ui/build_help.py,sha256=
|
|
9
|
+
listpick/ui/build_help.py,sha256=fDEURRb51slvK7rpk2iPWcJAwIAVigv8dp6T4cziZb4,10544
|
|
10
10
|
listpick/ui/footer.py,sha256=OH27JLGvvq9TlUsI30ODG6cHvjm7NTGSbXvF6lN1qiY,15089
|
|
11
11
|
listpick/ui/help_screen.py,sha256=zbfGIgb-IXtATpl4_Sx7nPbsnRXZ7eiMYlCKGS9EFmw,5608
|
|
12
12
|
listpick/ui/input_field.py,sha256=ylf3fiLXdAD4pueHWfzIrlwaRb9f5zm8f1UGkEPBxgM,30539
|
|
13
|
-
listpick/ui/keys.py,sha256=
|
|
14
|
-
listpick/ui/picker_colours.py,sha256=
|
|
13
|
+
listpick/ui/keys.py,sha256=nAmUn95UGuqh3QQMHWsPsXWW3or2oVMVlkzJV1t3zLQ,13559
|
|
14
|
+
listpick/ui/picker_colours.py,sha256=wq6FhXELejCoeBunWQgk9bsD0lLA3xM-I9WzZdWfWFE,12287
|
|
15
15
|
listpick/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
listpick/utils/clipboard_operations.py,sha256=ORdNm2kgGbfs51xJSvgJPERgoSmBgT11axuMkvSoP9A,3133
|
|
17
17
|
listpick/utils/config.py,sha256=MEnAZg2Rhfl38XofEIN0uoVAOY7I0ftc79Evk3fOiVw,1654
|
|
@@ -28,10 +28,10 @@ listpick/utils/searching.py,sha256=Xk5UIqamNHL2L90z3ACB_Giqdpi9iRKoAJ6pKaqaD7Q,3
|
|
|
28
28
|
listpick/utils/sorting.py,sha256=WZZiVlVA3Zkcpwji3U5SNFlQ14zVEk3cZJtQirBkecQ,5329
|
|
29
29
|
listpick/utils/table_to_list_of_lists.py,sha256=XBj7eGBDF15BRME-swnoXyOfZWxXCxrXp0pzsBfcJ5g,12224
|
|
30
30
|
listpick/utils/user_input.py,sha256=oyJZPAwA7UGAclPhdPL44tKnPIVNHWhX-tZEnCdBKC0,4318
|
|
31
|
-
listpick/utils/utils.py,sha256=
|
|
32
|
-
listpick-0.1.15.
|
|
33
|
-
listpick-0.1.15.
|
|
34
|
-
listpick-0.1.15.
|
|
35
|
-
listpick-0.1.15.
|
|
36
|
-
listpick-0.1.15.
|
|
37
|
-
listpick-0.1.15.
|
|
31
|
+
listpick/utils/utils.py,sha256=QptLnqT15Z3G7xoq-6Q8e4-aZRFClTdb3h0l42di11s,13810
|
|
32
|
+
listpick-0.1.15.8.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
|
|
33
|
+
listpick-0.1.15.8.dist-info/METADATA,sha256=RQbxnHkBzede_XRsNo2USmf9wigm9AZI6ACLsw5ZJBQ,8131
|
|
34
|
+
listpick-0.1.15.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
35
|
+
listpick-0.1.15.8.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
|
|
36
|
+
listpick-0.1.15.8.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
|
|
37
|
+
listpick-0.1.15.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|