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 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
- split_right_proportion: float = 1/2,
195
- split_right_function: Callable = lambda stdscr, x, y, w, h, state, row, cell, data, test: False,
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.split_right_proportion = split_right_proportion
354
- self.split_right_function = split_right_function
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 self.split_right_function(self.stdscr, 0,0,0,0,{},[],[],"",test=True):
430
- self.rows_w, self.rows_h = int(self.term_w*self.split_right_proportion), self.term_h
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 self.split_right_function(self.stdscr, 0,0,0,0,{},[],[],"",test=True):
791
- self.rows_w, self.rows_h = int(self.term_w*self.split_right_proportion), self.term_h
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
- if len(self.header) > 1 and (len(up_to_selected_col)-self.leftmost_char) < self.rows_w:
885
- number = f"{self.selected_column}. " if self.number_columns else ""
886
- # number = f"{intStringToExponentString(self.selected_column)}. " if self.number_columns else ""
887
- # self.startx + len(up_to_selected_col) - self.leftmost_char
888
- highlighed_col_startx = max(self.startx, self.startx + len(up_to_selected_col) - self.leftmost_char)
889
- highlighted_col_str = (number+f"{self.header[self.selected_column]:^{self.column_widths[self.selected_column]-len(number)}}") + self.separator
890
- 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)
891
- start_of_highlighted_col_str = max(self.leftmost_char - len(up_to_selected_col), 0)
892
- 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)
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
- def highlight_cell(row: int, col:int, visible_column_widths, colour_pair_number: int = 5):
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)-len(self.separator), self.centre_in_cols, self.unicode_char_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 <= self.rows_w:
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][cell_start:visible_column_widths[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
- row_str = truncate_to_display_width(row_str_left_adj, min(self.rows_w-self.startx, visible_columns_total_width), self.unicode_char_width)
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 self.split_right_function(self.stdscr, 0,0,0,0,{},[],[],"",test=True):
1120
- self.right_pane_previous_data = self.split_right_function(
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=self.split_right_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
- "split_right_proportion": self.split_right_proportion,
1294
- "split_right_function": self.split_right_function,
1295
- "split_right_auto_refresh": self.split_right_auto_refresh,
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 self.split_right_function(self.stdscr, 0,0,0,0,{},[],[],"",test=True):
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()-self.split_right_refresh_data_timer
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 self.split_right_function(self.stdscr, 0,0,0,0,{},[],[],"",test=True):
2297
- self.rows_w, self.rows_h = int(self.term_w*self.split_right_proportion), self.term_h
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
- if self.split_right and self.split_right_function(self.stdscr, 0,0,0,0,{},[],[],"",test=True):
2322
- self.rows_w, self.rows_h = int(self.term_w*self.split_right_proportion), self.term_h
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.split_right_auto_refresh and ((time.time() - initial_split_time) > self.split_right_refresh_data_timer):
2378
- self.split_right_data = self.split_right_refresh_data(self.split_right_data, self.get_function_data())
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 = self.leftmost_char+5
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
- item = rows[i]
2891
- row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
2892
- if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
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
- # function_data["split_right"] = True
3771
- # function_data["split_right_proportion"] = 2/3
3772
- # function_data["split_right_refresh_data"] = data_refresh_randint_title
3773
- # function_data["split_right_function"] = right_split_display_list
3774
- # function_data["split_right_data"] = ["Files", [str(x) for x in range(100)]]
3775
-
3776
-
3777
- # function_data["split_right_refresh_data"] = get_dl
3778
-
3779
-
3780
- # function_data["split_right_function"] = right_split_file_attributes
3781
- # function_data["split_right_auto_refresh"] = True
3782
- # function_data["split_right_function"] = right_split_graph
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:
@@ -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
@@ -87,6 +87,7 @@ picker_keys = {
87
87
  # "sheet_next": [],
88
88
  # "sheet_prev": [],
89
89
  "toggle_right_pane": [ord("'")],
90
+ "cycle_right_pane": [ord('"')],
90
91
  }
91
92
 
92
93
 
@@ -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'] = 237
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 text # If the total width is less than n, return the full string
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: listpick
3
- Version: 0.1.15.6
3
+ Version: 0.1.15.8
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
@@ -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=AYZNXy4Gc-_F4kLXiPB1-321mkfl3WxP9IRkM3VcYfk,194065
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=7xynpd3HjZnt6s9W0ZsJlrmYvGCMstAI5OJ7EuQSzdg,3092
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=NY-bDVV5NYQ2mEJo3-tTUsFpG7R6hwROPZPgc8NGfA0,10451
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=82uzU_cMo6NFHVi3P6cP0uE2ZN0h1EaVLYIVKuB26AU,13494
14
- listpick/ui/picker_colours.py,sha256=wftDxmUI6tGmOIPwBe4rUUsrPTtpFGgztptCifa_tqA,12287
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=McOl9uT3jh7l4TIWeSd8ZGjK_e7r0YZF0Gl20yI6fl0,13873
32
- listpick-0.1.15.6.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
33
- listpick-0.1.15.6.dist-info/METADATA,sha256=NHtilLmI6XfhHiraJOWmAddA8c-3vvpgGUW496LE5CU,8131
34
- listpick-0.1.15.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- listpick-0.1.15.6.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
36
- listpick-0.1.15.6.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
37
- listpick-0.1.15.6.dist-info/RECORD,,
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,,