summaryrefslogtreecommitdiffstats
path: root/buku
diff options
context:
space:
mode:
authorArun <engineerarun@gmail.com>2024-10-22 22:47:24 +0530
committerGitHub <noreply@github.com>2024-10-22 22:47:24 +0530
commit48bf29e0f03b754c5d2810a101911e02708b277f (patch)
treedf370cf051cc74fa9df75a46f423d3ff13311101 /buku
parent1f6c1a8fe168314d38651e500e5cf0584f3657a1 (diff)
parentde8bc94b4095c9ca18f4e26a6a58b3f7d7f28551 (diff)
Merge pull request #789 from LeXofLeviafan/swap-indices
Bookmark index swapping
Diffstat (limited to 'buku')
-rwxr-xr-xbuku57
1 files changed, 55 insertions, 2 deletions
diff --git a/buku b/buku
index a38cc01..20c82c0 100755
--- a/buku
+++ b/buku
@@ -1791,6 +1791,40 @@ class BukuDb:
return search_results
return filter_from(search_results, self.searchdb(without, deep=deep, markers=markers), exclude=True)
+ def swap_recs(self, index1: int, index2: int, *, lock: bool = True, delay_commit: bool = False):
+ """Swaps two records with given indices
+
+ Parameters
+ ----------
+ index1 : int
+ Index of the 1st record to be exchanged.
+ index2 : int
+ Index of the 2nd record to be exchanged.
+ lock : bool
+ Whether to restrict concurrent access (True by default).
+ delay_commit : bool
+ True if record should not be committed to the DB,
+ leaving commit responsibility to caller. Default is False.
+
+ Returns
+ -------
+ bool
+ True on success, False on failure.
+ """
+ if lock:
+ with self.lock:
+ return self.swap_recs(index1, index2, lock=False, delay_commit=delay_commit)
+
+ max_id = self.get_max_id()
+ if not max_id or index1 == index2 or not all(0 < x <= max_id for x in [index1, index2]):
+ return False
+
+ self.cur.executemany('UPDATE bookmarks SET id = ? WHERE id = ?',
+ [(max_id+1, index1), (index1, index2), (index2, max_id+1)])
+ if not delay_commit:
+ self.conn.commit()
+ return True
+
def compactdb(self, index: int, delay_commit: bool = False):
"""When an entry at index is deleted, move the
last entry in DB to index, if index is lesser.
@@ -3362,6 +3396,7 @@ PROMPT KEYS:
1-N browse search result indices and/or ranges
R [N] print out N random search results
(or random bookmarks if negative or N/A)
+ ^ id1 id2 swap two records at specified indices
O [id|range [...]] open search results/indices in GUI browser
toggle try GUI browser if no arguments
a open all results in browser
@@ -4705,7 +4740,7 @@ def prompt(obj, results, noninteractive=False, deep=False, listtags=False, sugge
if nav == 'n':
continue
- if (m := re.match(r'^R(?: (-)?([0-9]+))?$', nav)) and (n := int(m[2] or 1)) > 0:
+ if (m := re.match(r'^R(?: (-)?([0-9]+))?$', nav.rstrip())) and (n := int(m[2] or 1)) > 0:
skip_print = True
if results and not m[1]: # from search results
picked = random.sample(results, min(n, len(results)))
@@ -4716,6 +4751,14 @@ def prompt(obj, results, noninteractive=False, deep=False, listtags=False, sugge
print_single_rec(row, columns=columns)
continue
+ if (m := re.match(r'^\^ ([1-9][0-9]*) ([1-9][0-9]*)$', nav.rstrip())):
+ index1, index2 = map(int, m.group(1, 2))
+ if bdb.swap_recs(index1, index2):
+ bdb.print_rec({index1, index2})
+ else:
+ print('Failed to swap records #%d and #%d' % (index1, index2))
+ continue
+
# search ANY match with new keywords
if nav.startswith('s '):
keywords = (nav[2:].split() if not markers else split_by_marker(nav[2:]))
@@ -5881,13 +5924,15 @@ POSITIONAL ARGUMENTS:
-c, --comment [...] notes or description of the bookmark
clears description, if no arguments
--immutable N disable web-fetch during auto-refresh
- N=0: mutable (default), N=1: immutable''')
+ N=0: mutable (default), N=1: immutable
+ --swap N M swap two records at specified indices''')
addarg = edit_grp.add_argument
addarg('--url', nargs=1, help=hide)
addarg('--tag', nargs='*', help=hide)
addarg('--title', nargs='*', help=hide)
addarg('-c', '--comment', nargs='*', help=hide)
addarg('--immutable', type=int, choices={0, 1}, help=hide)
+ addarg('--swap', nargs=2, type=int, help=hide)
_bool = lambda x: x if x is None else bool(x)
_immutable = lambda args: _bool(args.immutable)
@@ -6181,6 +6226,14 @@ POSITIONAL ARGUMENTS:
colorize=not args.nc
)
+ if args.swap:
+ index1, index2 = args.swap
+ if bdb.swap_recs(index1, index2):
+ bdb.print_rec({index1, index2})
+ else:
+ LOGERR('Failed to swap records #%d and #%d', index1, index2)
+ bdb.close_quit(0)
+
# Editor mode
if args.write is not None:
if not is_editor_valid(args.write):