bookmark updated
This commit is contained in:
@@ -152,8 +152,8 @@ MULTI-SELECT
|
|||||||
|
|
||||||
BOOKMARKS
|
BOOKMARKS
|
||||||
---------
|
---------
|
||||||
b Bookmark current directory (press again to remove)
|
b Open bookmark picker (j/k navigate, enter jump, del remove)
|
||||||
B Open bookmark picker (j/k navigate, enter jump)
|
B Bookmark current directory (press again to remove)
|
||||||
|
|
||||||
Bookmarks are saved to: ~/.config/sfm/bookmarks
|
Bookmarks are saved to: ~/.config/sfm/bookmarks
|
||||||
|
|
||||||
|
|||||||
@@ -151,11 +151,11 @@ Multi-select works with
|
|||||||
.SS Bookmarks
|
.SS Bookmarks
|
||||||
.TP
|
.TP
|
||||||
.B b
|
.B b
|
||||||
Bookmark the current directory. Press again to remove it.
|
Open the bookmark picker.
|
||||||
|
Use j/k to navigate, enter to jump, del to remove, esc to close.
|
||||||
.TP
|
.TP
|
||||||
.B B
|
.B B
|
||||||
Open the bookmark picker.
|
Bookmark the current directory. Press again to remove it.
|
||||||
Use j/k to navigate, enter to jump, esc to close.
|
|
||||||
|
|
||||||
.SS Other
|
.SS Other
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -333,8 +334,9 @@ private:
|
|||||||
// ── overlays ───────────────────────────────────────────────────────────
|
// ── overlays ───────────────────────────────────────────────────────────
|
||||||
bool confirm_overlay(const std::string &prompt);
|
bool confirm_overlay(const std::string &prompt);
|
||||||
std::string overlay_picker(const std::string &title,
|
std::string overlay_picker(const std::string &title,
|
||||||
const std::vector<std::string> &items,
|
std::vector<std::string> items,
|
||||||
bool allow_cancel = true);
|
bool allow_cancel = true,
|
||||||
|
const std::function<void(const std::string &)> &on_delete = nullptr);
|
||||||
|
|
||||||
// ── input ──────────────────────────────────────────────────────────────
|
// ── input ──────────────────────────────────────────────────────────────
|
||||||
bool handle_key(int key); // returns false to quit
|
bool handle_key(int key); // returns false to quit
|
||||||
@@ -1102,8 +1104,9 @@ bool FileManager::confirm_overlay(const std::string &prompt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string FileManager::overlay_picker(const std::string &title,
|
std::string FileManager::overlay_picker(const std::string &title,
|
||||||
const std::vector<std::string> &items,
|
std::vector<std::string> items,
|
||||||
bool allow_cancel) {
|
bool allow_cancel,
|
||||||
|
const std::function<void(const std::string &)> &on_delete) {
|
||||||
if (items.empty()) return "";
|
if (items.empty()) return "";
|
||||||
|
|
||||||
int nitems = static_cast<int>(items.size());
|
int nitems = static_cast<int>(items.size());
|
||||||
@@ -1205,6 +1208,14 @@ std::string FileManager::overlay_picker(const std::string &title,
|
|||||||
case 'q': case 'Q': case 'h':
|
case 'q': case 'Q': case 'h':
|
||||||
if (allow_cancel) { need_full_redraw_ = true; return ""; }
|
if (allow_cancel) { need_full_redraw_ = true; return ""; }
|
||||||
break;
|
break;
|
||||||
|
case KEY_DC:
|
||||||
|
if (on_delete && !items.empty()) {
|
||||||
|
on_delete(items[psel]);
|
||||||
|
items.erase(items.begin() + psel);
|
||||||
|
nitems = static_cast<int>(items.size());
|
||||||
|
if (nitems == 0) { need_full_redraw_ = true; return ""; }
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 27: need_full_redraw_ = true; return "";
|
case 27: need_full_redraw_ = true; return "";
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@@ -1621,8 +1632,8 @@ void FileManager::do_help() {
|
|||||||
{" + chmod +x (make executable)", false, false},
|
{" + chmod +x (make executable)", false, false},
|
||||||
{" - chmod -x (remove executable)", false, false},
|
{" - chmod -x (remove executable)", false, false},
|
||||||
{"", true, false},
|
{"", true, false},
|
||||||
{" b bookmark current dir", false, false},
|
{" b open bookmark picker", false, false},
|
||||||
{" B open bookmark picker", false, false},
|
{" B bookmark current dir", false, false},
|
||||||
{" c copy path to clipboard", false, false},
|
{" c copy path to clipboard", false, false},
|
||||||
{" ~ go to home directory", false, false},
|
{" ~ go to home directory", false, false},
|
||||||
{" ` jump to previous directory", false, false},
|
{" ` jump to previous directory", false, false},
|
||||||
@@ -2023,7 +2034,18 @@ void FileManager::do_bookmark_jump() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string chosen = overlay_picker(" BOOKMARKS", bookmarks);
|
auto remove_bookmark = [&](const std::string &path) {
|
||||||
|
std::vector<std::string> kept;
|
||||||
|
std::ifstream fin(bookmark_file_);
|
||||||
|
std::string l;
|
||||||
|
while (std::getline(fin, l))
|
||||||
|
if (l != path) kept.push_back(l);
|
||||||
|
fin.close();
|
||||||
|
std::ofstream fout(bookmark_file_, std::ios::trunc);
|
||||||
|
for (const auto &k : kept) fout << k << '\n';
|
||||||
|
flash_msg("bookmark removed: " + path);
|
||||||
|
};
|
||||||
|
std::string chosen = overlay_picker(" BOOKMARKS", bookmarks, true, remove_bookmark);
|
||||||
if (chosen.empty()) { need_full_redraw_ = true; return; }
|
if (chosen.empty()) { need_full_redraw_ = true; return; }
|
||||||
|
|
||||||
if (fs::is_directory(chosen)) {
|
if (fs::is_directory(chosen)) {
|
||||||
@@ -2443,8 +2465,8 @@ bool FileManager::handle_key(int key) {
|
|||||||
do_open(); break;
|
do_open(); break;
|
||||||
case 'h': case KEY_LEFT:
|
case 'h': case KEY_LEFT:
|
||||||
do_go_back(); break;
|
do_go_back(); break;
|
||||||
case 'b': do_bookmark_add(); break;
|
case 'b': do_bookmark_jump(); break;
|
||||||
case 'B': do_bookmark_jump(); break;
|
case 'B': do_bookmark_add(); break;
|
||||||
case '?': do_help(); break;
|
case '?': do_help(); break;
|
||||||
case 'R': load_entries(); flash_msg("refreshed"); break;
|
case 'R': load_entries(); flash_msg("refreshed"); break;
|
||||||
case '/': do_search(); break;
|
case '/': do_search(); break;
|
||||||
|
|||||||
@@ -912,8 +912,8 @@ do_help() {
|
|||||||
help_row 30 " + chmod +x (make executable)"
|
help_row 30 " + chmod +x (make executable)"
|
||||||
help_row 31 " - chmod -x (remove executable)"
|
help_row 31 " - chmod -x (remove executable)"
|
||||||
help_sep 32
|
help_sep 32
|
||||||
help_row 33 " b bookmark current dir"
|
help_row 33 " b open bookmark picker"
|
||||||
help_row 34 " B open bookmark picker"
|
help_row 34 " B bookmark current dir"
|
||||||
help_row 35 " c copy path to clipboard"
|
help_row 35 " c copy path to clipboard"
|
||||||
help_row 36 " ~ go to home directory"
|
help_row 36 " ~ go to home directory"
|
||||||
help_row 37 " \` jump to previous directory"
|
help_row 37 " \` jump to previous directory"
|
||||||
@@ -1674,6 +1674,19 @@ do_bookmark_jump() {
|
|||||||
fi
|
fi
|
||||||
return ;;
|
return ;;
|
||||||
'[D') NEED_FULL_REDRAW=1; return ;; # left — close
|
'[D') NEED_FULL_REDRAW=1; return ;; # left — close
|
||||||
|
'[3') # delete — remove selected bookmark
|
||||||
|
IFS= read -r -n1 -t 0.05 _rest 2>/dev/null # swallow trailing ~
|
||||||
|
_chosen=$(awk -v n="$_bsel" 'NR==n&&NF{print;exit}' "$BOOKMARK_FILE")
|
||||||
|
if [ -n "$_chosen" ]; then
|
||||||
|
_tmp=$(grep -vxF "$_chosen" "$BOOKMARK_FILE")
|
||||||
|
printf '%s\n' "$_tmp" > "$BOOKMARK_FILE"
|
||||||
|
INFO_MSG="bookmark removed: ${_chosen}"
|
||||||
|
_bc=$((_bc-1))
|
||||||
|
if [ "$_bc" -eq 0 ]; then NEED_FULL_REDRAW=1; return; fi
|
||||||
|
[ "$_bsel" -gt "$_bc" ] && _bsel=$_bc
|
||||||
|
[ "$_bsel" -lt "$_boff" ] && _boff=$_bsel
|
||||||
|
[ "$_bsel" -ge $((_boff + _bvis)) ] && _boff=$((_bsel - _bvis + 1))
|
||||||
|
fi ;;
|
||||||
*) NEED_FULL_REDRAW=1; return ;; # bare esc — close
|
*) NEED_FULL_REDRAW=1; return ;; # bare esc — close
|
||||||
esac ;;
|
esac ;;
|
||||||
"$(printf '\n')"|\
|
"$(printf '\n')"|\
|
||||||
@@ -1829,8 +1842,8 @@ while true; do
|
|||||||
l) do_open ;;
|
l) do_open ;;
|
||||||
"$(printf '\033[D')"|\
|
"$(printf '\033[D')"|\
|
||||||
h) do_go_back ;;
|
h) do_go_back ;;
|
||||||
b) do_bookmark_add ;;
|
b) do_bookmark_jump ;;
|
||||||
B) do_bookmark_jump ;;
|
B) do_bookmark_add ;;
|
||||||
'?') do_help ;;
|
'?') do_help ;;
|
||||||
R) load_entries; INFO_MSG="refreshed" ;;
|
R) load_entries; INFO_MSG="refreshed" ;;
|
||||||
/) do_search ;;
|
/) do_search ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user