mptre / pick Goto Github PK
View Code? Open in Web Editor NEWA fuzzy search tool for the command-line
License: MIT License
A fuzzy search tool for the command-line
License: MIT License
The highlighting of the selected match isn't visible under tmux with several colorschemes I have tried. I am having this issue using the base Thoughtbot tmux configuration with no customizations. The issue happens both in and outside of Vim. Everything works fine if I'm not in tmux.
I have a feeling there's an easy way to fix the color profiles (it works in Solarized Dark, but not in Jellybeans), but after fiddling with the colors in my profiles I'm still having trouble figuring out what attribute I should change to enable the highlighting.
Compiling from e79f95b.
When running make check
, the first test fails and the rest don't get tested.
test-suite.log:
==================================
pick 1.3.0: ./test-suite.log
==================================
# TOTAL: 1
# PASS: 0
# SKIP: 0
# XFAIL: 0
# FAIL: 1
# XPASS: 0
# ERROR: 0
.. contents:: :depth: 2
FAIL: tests/test.sh
===================
./tests/01.in: wrong exit code
test: read: Input/output error
FAIL tests/test.sh (exit status: 1)
Pick itself works fine, from what I can tell.
For the record, I've checked this against a fresh install of Arch under docker (pritunl/archlinux), and I get the same result.
Apologies if this is a total noob question, but the make
and sudo make install
steps of the installation both output several messages that look like errors. Apparently they're just warnings, since the binary is still installed correctly, but is there anything that should be done to suppress or fix them?
Here's what I see. This is on a Mac running 10.9.5.
$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking locale.h usability... yes
checking locale.h presence... yes
checking for locale.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking for unistd.h... (cached) yes
checking for size_t... yes
checking for ssize_t... yes
checking for stdlib.h... (cached) yes
checking for GNU libc compatible malloc... yes
checking for stdlib.h... (cached) yes
checking for GNU libc compatible realloc... yes
checking for memmove... yes
checking for setlocale... yes
checking for strdup... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating man/Makefile
config.status: creating config.h
config.status: executing depfiles commands
$ make
/Applications/Xcode.app/Contents/Developer/usr/bin/make all-recursive
Making all in src
gcc -DHAVE_CONFIG_H -I. -I.. -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -MT choice.o -MD -MP -MF .deps/choice.Tpo -c -o choice.o choice.c
mv -f .deps/choice.Tpo .deps/choice.Po
gcc -DHAVE_CONFIG_H -I. -I.. -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -MT choices.o -MD -MP -MF .deps/choices.Tpo -c -o choices.o choices.c
mv -f .deps/choices.Tpo .deps/choices.Po
gcc -DHAVE_CONFIG_H -I. -I.. -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -MT io.o -MD -MP -MF .deps/io.Tpo -c -o io.o io.c
mv -f .deps/io.Tpo .deps/io.Po
gcc -DHAVE_CONFIG_H -I. -I.. -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I. -I.. -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -MT ui.o -MD -MP -MF .deps/ui.Tpo -c -o ui.o ui.c
mv -f .deps/ui.Tpo .deps/ui.Po
gcc -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -lncurses -o pick choice.o choices.o io.o main.o ui.o
Making all in man
make[2]: Nothing to be done for `all'.
make[2]: Nothing to be done for `all-am'.
$ sudo make install
Making install in src
.././install-sh -c -d '/usr/local/bin'
/usr/bin/install -c pick '/usr/local/bin'
make[2]: Nothing to be done for `install-data-am'.
Making install in man
make[2]: Nothing to be done for `install-exec-am'.
.././install-sh -c -d '/usr/local/share/man/man1'
/usr/bin/install -c -m 644 man1/pick.1 '/usr/local/share/man/man1'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
$
Really useful tool !! I must say. I have an issue regarding viewing logs. When I do something like
cat syslog | pick
# type something
fuzzy search happens
# delete what you typed
weird sorted content shows up
Initially stuff looks good. as soon as you type and erase what you typed the content in the "pick buffer" gets sorted. It would be useful if the text in pick buffer remains the same.
I had a friend beta test pick and he came back with some bugs. I'll spend some time verifying and coming up with specific issues from these when I get a chance. For reference he uses fzf
The default sort is good for some use cases, but if you're trying to filter things that are in chronological order (like git commits) it becomes a bit lackluster. Having an option for stable sorting would be very valuable for picking things from an externally-ordered list.
It would be quite useful if pick
had a bind that used what the user currently has entered.
dmenu
and some of its clones like rofi
do this with Control+Enter
or Shift+Enter
, though those keys won't work well in the terminal.
This would let users select things that are not in the list. Consider the following example, which lists local branches in a git repo:
git branch | cut -c 3- | pick | xargs git checkout
With the proposed feature, users could type in a commit hash or a tag, which would not be present in the list but are valid refs to checkout. Or if a user has a bind like I do to "check out a branch if it exists, and otherwise make it", this would then be possible with pick
alone.
From the current HEAD after fixing issue #14 locally. I get
make all-recursive
make[1]: Entering directory `/home/ecerulm/tmp/pick'
Making all in src
make[2]: Entering directory `/home/ecerulm/tmp/pick/src'
gcc -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -lncurses -lbsd -o pick choice.o choices.o io.o main.o ui.o
ui.o: In function `start_curses':
/home/ecerulm/tmp/pick/src/ui.c:56: undefined reference to `initscr'
The -lncurses -lbsd
options are misplaced they should appear after the object files. Im using Ubuntu 14.04.
Steps to reproduce
cat file | pick
I can still switch tmux panes while pick runs in a shell, but if I run vim and then bring up pick inside it, I can no longer navigate to another pane using the vim-tmux-navigator key bindings. I'm guessing this might be because the value of pane_current_command
changes while pick is up?
Other fuzzy finders like ctrlp and fzf highlight the matched portion of items, i.e. if I have an item README.md
in the input list and my search is mm
, the substring ME.m
will be highlighted in a different color. This can be useful visual feedback when searching large numbers of entries, to see why a particular search is matching something unexpected.
Below is the result of entering the key codes by hitting ^V
and each arrow key (up, down, right, left) in vim.
fresh vim startup, before running pick:
^[0A^[0B^[0C^[0D
after running pick and exiting either successfully or via interrupt:
^[[A^[[B^[[C^[[D
This messes up any vim mappings set for the arrow keys.
This should be possible using wchar_t
arrays for storing strings instead of char
arrays and by linking against ncursesw
instead of ncurses
.
Should empty input be ignored or handled in some other way? Currently only CTRL+C will exit.
To reproduce:
echo -ne "" | pick
After running pick from vim and exiting vim, the screen isn't cleared. (OS X, iTerm)
The link for the AUR tarball https://aur.archlinux.org/packages/pi/pick/pick.tar.gz
gives a 404.
When I run pick
from within Vim using the code below, when exiting Vim, the terminal state is not restored. Instead, the screen Vim drew is still visible.
function! PickCommand(choices_command, pick_args, vim_command)
try
let selection = system(a:choices_command . " | pick " . a:pick_args)
catch /Vim:Interrupt/
redraw!
return
endtry
redraw!
exec a:vim_command . " " . selection
endfunction
nnoremap <leader>p :call PickCommand("find * -type f", "", ":e")<cr>
It would be great if someone else could replicate this. I don't know if this is a bug in pick, Vim or my terminal emulator.
... It's probably in pick.
I've been struggling to use pick
in the fish shell, which unfortunately has a bug when it comes to handling commands that block for input inside a command substitution (see fish-shell/fish-shell#1362).
There's a workaround though. For instance, instead of typing this command (which does not work properly in fish due to the aforementioned bug)
rake (rake -T | cut -f2 -d' ' | pick)
We can instead type this:
rake -T | cut -f2 -d' ' | pick | xargs rake
So I think it is more general that in the documentation this form of using pick
might be preferred over the command substitution alternative, whenever possible.
However, there are some cases where this xargs
workaround doesn't work. I've found just one, but there could be more:
find . -type d | pick | xargs cd
The reason this does not work may have something to do with this.
Any ideas of how to work around this problem with the cd
command?
pick must read its input entirely before the filtering interface becomes responsive. For an example, in a directory with a large number of entries (say > 150,000), compare find . -type f | pick
, which will take at least seconds to become responsive, and find . -type f | less
, which is immediately responsive. fzf is one example of a fuzzy finder that handles this well by searching over entries received so far and streaming in new entries as they match.
The man page currently states the following:
When the -d option is supplied, input lines will be split into two parts by the last occurrence of IFS.
However, the observed behavior is the opposite of that (split by the first occurrence):
$ pick -d <<< "foo bar baz qux"
foo
I’ll be happy to help modify io_read_choices
to match the documented behavior, if you’d like to fix that in the code.
P.S. There is also a typo in word "occurrence" in this man page.
To compile pick locally on OS X I had to remove the bsd
specific code. This is the diff:
diff --git i/src/Makefile.am w/src/Makefile.am
index 7709758..1b10f31 100644
--- i/src/Makefile.am
+++ w/src/Makefile.am
@@ -1,4 +1,4 @@
-AM_LDFLAGS=-lncurses -lbsd
+AM_LDFLAGS=-lncurses
AM_CFLAGS=-Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror
bin_PROGRAMS=pick
dist_pick_SOURCES=choice.c choice.h choices.c choices.h io.c io.h main.c ui.c ui.h compat/queue.h
diff --git i/src/ui.c w/src/ui.c
index 23a765c..fea3ab9 100644
--- i/src/ui.c
+++ w/src/ui.c
@@ -7,7 +7,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <bsd/string.h>
#ifdef HAVE_FULL_QUEUE_H
#include <sys/queue.h>
I haven't noticed any side effects of this but I'm sure this was in there for other platforms. Can we move this to somewhere it doesn't cause issue?
I had a script working in v1.2.1 that is useful for selecting from recently checked out git branches. I was using color to divide some of the columns. I've narrowed the issue down to being color specifically. This occurs in both bash and zsh for me. Here's an example that produces odd output:
RED='\033[0;31m'
NC='\033[0m'
printf "${RED}pick${NC} is the handiest\n${RED}pick${NC} is the handiest\n${RED}pick${NC} is the handiest\n${RED}pick${NC} is the handiest\n${RED}pick${NC} is the handiest\n${RED}pick${NC} is the handiest\n${RED}pick${NC} is the handiest\n${RED}pick${NC} is the handiest\n" | pick
So, you can see we've created a list of colorized items to pipe to pick. Here is what the output looks like on my system for some reason. The issue first came up after installing v1.3.
Thank you guys so very much for this great tool, I've applied it to all sorts of things, and makes my work merrier several times a day. You guys rock!
Looks like several of the branches are no longer in use.
I don't know about you guys but I use Pick primarily in Vim and I find it quite frustrating to not be able to exit it via ESC. I know very little about terminal programming but it seems like this would be possible and good.
Just an idea.
Hi, just a little constructive note on some C code containing the expression sizeof(char)
Writing it is unnecessary, practically never used, and a bit confusing.
From ISO C11
6.5.3.4.4
"When sizeof is applied to an operand that has type char, unsigned char, or
signed char, (or a qualified version thereof) the result is 1"
By definition sizeof measures size in chars.
On the other hand,
line = calloc(sizeof(line[0]), line_length);
or
line = calloc(sizeof(*line), line_length);
make more sense than
line = calloc(sizeof(char), line_length);
As it is right now, control-c
exits. However it exits with a non-zero status code (which is expected), and thus if another program had launched pick
(such as tig
) it closes said program as well. I know this is expected, and is very useful in other situations. selecta
does the same thing.
selecta
also has a mapping to "cancel" the selection, though, which exits with a status of 0
. In the tig
example above this just closes selecta
and brings you back into tig
.
Is this feasible for pick
?
When allocating memory using malloc
there is a risk for multiplication overflow if the call looks anything like malloc(sizeof(whatever) * n)
. To prevent this calloc(sizeof(whatever), n)
can be used instead.
Similarly, calls like realloc(sizeof(whatever) * n)
suffers from the same problems and can be replaced with calls to reallocarray
. reallocarray
is implemented in OpenBSDs stdlib and can be added to compat/
for portability.
When piping unknown results to pick, e.g.:
ag -l 'foo.*bar' | pick
an empty search result appears to hang pick. Crl-c is the only escape; alternatively, creating a bash function like:
pipe_if_not_empty () {
input=$(cat; echo a);
if [ "x$input" != x"a" ]; then
{ printf %s "${input%a}"; } | "$@"
fi
}
then one can resort to a solution like:
ag -l 'foo.*bar' | pipe_if_not_empty pick
However, pick should handle this itself.
If we resize the terminal after pick is initiated, the choices doesn't print as expected.
This may be because the variables 'lines', 'columns' are not getting updated, if the terminal size is disturbed after 'setupterm' been executed.
One possible solution may be to capture the event SIGWINCH and update the variables accordingly.
How can I use it to append to the output file?
I am using
pick history | grep ffmpeg | pick -o > this.txt
- this always creates a new file. Can there be an argument which appends to the end of this.txt
?
Hi
I was trying to install from source.
`2. Configure the distribution.
./configure`
But there is no configure file present in the directory.
The homebrew formula currently has the wrong sha1 checksum.
$ brew install pick
==> Installing pick from thoughtbot/homebrew-formulae
==> Downloading https://github.com/thoughtbot/pick/releases/download/v1.1.0/pick-1.1.0.tar.gz
Already downloaded: /Library/Caches/Homebrew/pick-1.1.0.tar.gz
Error: SHA1 mismatch
Expected: cec167acc776065c055ab13a918d4e0300dca2f8
Actual: 8b035e64cc5faea407e73cce01ca039e3ce3b4ac
Archive: /Library/Caches/Homebrew/pick-1.1.0.tar.gz
To retry an incomplete download, remove the file above.
I wonder if the @DIST_SHA@
directive in the homebrew template needs to specify the .tag.gz
file?
Giving pick a list of 200.000 strings and then typing really fast into pick's search field makes pick crash with the error message pick: getc: Illegal seek
.
To reproduce run the following and type really fast:
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 200000 | pick
on CentOS I needed to give an additional flag to wget
wget --output-document=pick-1.1.1.tar.gz.asc https://github.com/thoughtbot/pick/releases/download/v1.1.1/pick-1.1.1.tar.gz.asc
wget --output-document=pick-1.1.1.tar.gz https://github.com/thoughtbot/pick/releases/download/v1.1.1/pick-1.1.1.tar.gz
for those that want to just copy pasta what I did for the CentOS install, continue from the above:
gpg --verify pick-1.1.1.tar.gz.asc
tar -xzf pick-1.1.1.tar.gz
cd pick-1.1.1
./configure
make
sudo make install
I intend to package and maintain pick for Debian.
All files are licensed with the MIT license?
The -X
option which fixes #32 isn't documented under pick --help
Would you like to add more error handling for return values from functions like the following?
when running pick inside tmux, the white background that shows the current selection (which can be advanced with Ctrl+N) cannot be seen. The selection does change, but the white background is not visible. Works fine when not inside a tmux session. Am I missing a configuration setting or something?
System: Fedora 22 x64
Gary Bernhardt was good enough to mention this.
https://twitter.com/garybernhardt/status/575379182684766208
I've not looked into the code, but a possible solution could be a short wait before filtering after a character is typed while you look for more characters, sort of like a buffered filter? Also, threads.
Can pick
be used to pick multiple lines ? May be run pick -i
(pick interactive - to pick as many as we want?)
Am I doing something wrong, or it's a limitation of pick
– it shows only one screen of options.
So that the only way to select the items that didn't fit into the screen is to adjust the query?
// mac, homebrew, pick 1.4.0
Previously: Stable sorting?
Besides https://github.com/thoughtbot/pick.vim, my most common use case is a fuzzy project finder that sorts by most recent. However once I start typing, the original sort order appears to be lost.
I think the unstable sort probably makes sense as a default for performance reasons, but perhaps a stable sort option would be appropriate?
What do you think about adding a homebrew recipe for easy installation on OS X? I'd imagine it would go a long way towards attracting new users.
Hi,
I tried to compile in the current HEAD on Ubuntu 14.04 and Im getting
make all-recursive
make[1]: Entering directory `/home/ecerulm/tmp/pick'
Making all in src
make[2]: Entering directory `/home/ecerulm/tmp/pick/src'
gcc -DHAVE_CONFIG_H -I. -I.. -Wall -Wextra -pedantic-errors -Wno-unused-parameter -Werror -g -O2 -MT ui.o -MD -MP -MF .deps/ui.Tpo -c -o ui.o ui.c
ui.c: In function ‘start_curses’:
ui.c:48:9: error: ignoring return value of ‘freopen’, declared with attribute warn_unused_result [-Werror=unused-result]
freopen("/dev/tty", "r", stdin);
^
cc1: all warnings being treated as errors
make[2]: *** [ui.o] Error 1
make[2]: Leaving directory `/home/ecerulm/tmp/pick/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/ecerulm/tmp/pick'
make: *** [all] Error 2
I guess that the freopen
call should be wrapped in an assert()
When entering text in pick, one can use the left/right arrow keys to insert and delete characters in the middle of the entry. However, there's no visual indication of the cursor, so it's very difficult to do this accurately. 😉
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.