Skip to content

Commit f993da2

Browse files
committed
Feat: Add sorting options
Adds a new option for `@fzf-url-sort-by`, defaulting to `alphabetical` as before, and adding `recency` to sort urls by recency in the scrollback history. Most of the time when I use this plugin, I want to open the url that just got printed (usually a github PR). Sorting be recency makes it so 9/10 times, I invoke the plugin and hit enter to oepn it right away.
1 parent 16381dc commit f993da2

File tree

3 files changed

+54
-12
lines changed

3 files changed

+54
-12
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,23 @@ You can use custom fzf options by defining `@fzf-url-fzf-options`.
5656
set -g @fzf-url-fzf-options '-w 50% -h 50% --multi -0 --no-preview --no-border'
5757
```
5858

59+
You can control how URLs are sorted by setting `@fzf-url-sort-by`:
60+
61+
```tmux
62+
# Sort URLs alphabetically (default)
63+
set -g @fzf-url-sort-by 'alphabetical'
64+
65+
# Sort URLs by recency - most recent URLs closest to search bar
66+
set -g @fzf-url-sort-by 'recency'
67+
```
68+
69+
**Smart Layout Detection**: When using recency sorting, the plugin automatically detects your fzf layout and adjusts the sort order to keep the most recent URLs closest to the search bar:
70+
71+
- **Default layout** (search at bottom): Recent URLs appear first (top of list)
72+
- **Reverse layout** (with `--reverse` option): Recent URLs appear last (bottom of list)
73+
74+
This ensures optimal accessibility regardless of your preferred fzf layout.
75+
5976
By default, `tmux-fzf-url` will use `xdg-open`, `open`, or the `BROWSER`
6077
environment variable to open the url, respectively. If you want to use a
6178
different command, you can set `@fzf-url-open` to the command you want to use.

fzf-url.sh

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fzf_filter() {
1616
}
1717

1818
custom_open=$3
19+
sort_by=$4
1920
open_url() {
2021
if [[ -n $custom_open ]]; then
2122
$custom_open "$@"
@@ -37,21 +38,44 @@ else
3738
content="$(tmux capture-pane -J -p -e -S -"$limit" |sed -r 's/\x1B\[[0-9;]*[mK]//g'))"
3839
fi
3940

40-
urls=$(echo "$content" |grep -oE '(https?|ftp|file):/?//[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]')
41-
wwws=$(echo "$content" |grep -oE '(http?s://)?www\.[a-zA-Z](-?[a-zA-Z0-9])+\.[a-zA-Z]{2,}(/\S+)*' | grep -vE '^https?://' |sed 's/^\(.*\)$/http:\/\/\1/')
42-
ips=$(echo "$content" |grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(:[0-9]{1,5})?(/\S+)*' |sed 's/^\(.*\)$/http:\/\/\1/')
43-
gits=$(echo "$content" |grep -oE '(ssh://)?git@\S*' | sed 's/:/\//g' | sed 's/^\(ssh\/\/\/\)\{0,1\}git@\(.*\)$/https:\/\/\2/')
44-
gh=$(echo "$content" |grep -oE "['\"]([_A-Za-z0-9-]*/[_.A-Za-z0-9-]*)['\"]" | sed "s/['\"]//g" | sed 's#.#https://github.com/&#')
41+
# Extract URLs with line numbers to preserve position
42+
urls=$(echo "$content" | grep -noE '(https?|ftp|file):/?//[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]')
43+
wwws=$(echo "$content" | grep -noE '(http?s://)?www\.[a-zA-Z](-?[a-zA-Z0-9])+\.[a-zA-Z]{2,}(/\S+)*' | grep -vE ':[0-9]*:https?://' | sed 's/^\([0-9]*\):\(.*\)$/\1:http:\/\/\2/')
44+
ips=$(echo "$content" | grep -noE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(:[0-9]{1,5})?(/\S+)*' | sed 's/^\([0-9]*\):\(.*\)$/\1:http:\/\/\2/')
45+
gits=$(echo "$content" | grep -noE '(ssh://)?git@\S*' | sed 's/:/\//g' | sed 's/^\([0-9]*\)\/\/\(ssh\/\/\/\)\{0,1\}git@\(.*\)$/\1:https:\/\/\3/')
46+
gh=$(echo "$content" | grep -noE "['\"]([_A-Za-z0-9-]*/[_.A-Za-z0-9-]*)['\"]" | sed "s/['\"]//g" | sed 's/^\([0-9]*\):\(.*\)$/\1:https:\/\/github.com\/\2/')
4547

4648
if [[ $# -ge 1 && "$1" != '' ]]; then
47-
extras=$(echo "$content" |eval "$1")
49+
extras=$(echo "$content" | nl -nln | eval "$1" | sed 's/^\([0-9]*\)\t\(.*\)$/\1:\2/')
4850
fi
4951

50-
items=$(printf '%s\n' "${urls[@]}" "${wwws[@]}" "${gh[@]}" "${ips[@]}" "${gits[@]}" "${extras[@]}" |
51-
grep -v '^$' |
52-
sort -u |
53-
nl -w3 -s ' '
54-
)
52+
# Combine all URLs with their line numbers
53+
all_urls=$(printf '%s\n' "${urls[@]}" "${wwws[@]}" "${gh[@]}" "${ips[@]}" "${gits[@]}" "${extras[@]}" | grep -v '^$')
54+
55+
# Sort and deduplicate based on sort_by option
56+
if [[ "$sort_by" == "recency" ]]; then
57+
# Recency behavior: adjust sort order based on fzf layout
58+
fzf_options="$(get_fzf_options)"
59+
if [[ "$fzf_options" == *"--reverse"* ]]; then
60+
# Reverse layout (search at top): oldest URLs first so recent ones are closest to search
61+
sort_order="-n"
62+
else
63+
# Default layout (search at bottom): newest URLs first so recent ones are closest to search
64+
sort_order="-nr"
65+
fi
66+
67+
items=$(echo "$all_urls" | awk -F: '
68+
{
69+
url = substr($0, index($0, ":") + 1)
70+
if (!seen[url]) {
71+
seen[url] = 1
72+
print $1 ":" url
73+
}
74+
}' | sort $sort_order | cut -d: -f2- | nl -w3 -s ' ')
75+
else
76+
# Default alphabetical behavior: sort alphabetically and remove duplicates
77+
items=$(echo "$all_urls" | cut -d: -f2- | sort -u | nl -w3 -s ' ')
78+
fi
5579
[ -z "$items" ] && tmux display 'tmux-fzf-url: no URLs found' && exit
5680

5781
fzf_filter <<< "$items" | awk '{print $2}' | \

fzf-url.tmux

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ key="$(tmux_get '@fzf-url-bind' 'u')"
1818
history_limit="$(tmux_get '@fzf-url-history-limit' 'screen')"
1919
extra_filter="$(tmux_get '@fzf-url-extra-filter' '')"
2020
custom_open="$(tmux_get '@fzf-url-open' '')"
21+
sort_by="$(tmux_get '@fzf-url-sort-by' 'alphabetical')"
2122
echo "$extra_filter" > /tmp/filter
2223

23-
tmux bind-key "$key" run -b "$SCRIPT_DIR/fzf-url.sh '$extra_filter' $history_limit '$custom_open'";
24+
tmux bind-key "$key" run -b "$SCRIPT_DIR/fzf-url.sh '$extra_filter' $history_limit '$custom_open' '$sort_by'";

0 commit comments

Comments
 (0)