Skip to content

Commit 9f95f12

Browse files
committed
Merge pull request #16 from khamer/add-combined-grep-find (plus tweaks)
Add combined grep/find as search
2 parents d7ff4f3 + 5713b4a commit 9f95f12

File tree

3 files changed

+146
-2
lines changed

3 files changed

+146
-2
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ Searches note filenames and paths for the given string, and returns every single
6767

6868
Searches all note content for the given string and returns all the matches. Shorthand alias also available with `notes g`.
6969

70+
### `notes search <part-of-a-note-name-or-note-content>`
71+
72+
Searches all note content and note filenames for the given string and returns all the matches. Shorthand alias also available with `notes s`.
73+
7074
### `notes ls <directory>`
7175

7276
Lists note names and note directories at a single level. Lists all top level notes and directories if no path is provided, or the top-level contents of a directory if one is provided.
@@ -91,7 +95,6 @@ Combine these together! This opens each matching note in your `$EDITOR` in turn.
9195

9296
All the above works. Here's what's coming next:
9397

94-
- [ ] Combining find and grep, to match either one (https://github.com/pimterry/notes/issues/16)
9598
- [ ] More interesting and nicer looking file/grep search result formatting, perhaps only when not piping? (https://github.com/pimterry/notes/issues/27)
9699
- [ ] Make the file extension optional (https://github.com/pimterry/notes/issues/24)
97100
- [ ] zsh command and note name autocompletion (https://github.com/pimterry/notes/issues/25)

notes

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22

33
# Look for configuration file at ~/.config/notes/config and use it
4-
if [ -f ~/.config/notes/config ]; then
4+
if [ -f ~/.config/notes/config ]; then
55
. ~/.config/notes/config
66
fi
77

@@ -38,6 +38,28 @@ ls_notes() {
3838
fi
3939
}
4040

41+
search_filenames_and_contents() {
42+
if [ "$#" -gt 0 ]; then
43+
find_output=$(find "$notes_dir" -type f -exec bash -c \
44+
"shopt -s nocasematch
45+
grep -il \"$*\" \"{}\" || if [[ \"{}\" =~ \"$*\" ]]; then
46+
echo \"{}\";
47+
fi" \;\
48+
)
49+
else
50+
find_output=$(find "$notes_dir" -type f)
51+
fi
52+
find_result=$?
53+
formatted_output=$(printf "$find_output" | without_notes_dir)
54+
55+
if [[ $find_result == 0 && "$formatted_output" ]]; then
56+
printf "$formatted_output\n"
57+
return 0
58+
else
59+
return 2
60+
fi
61+
}
62+
4163
find_notes() {
4264
local find_output=$(find "$notes_dir" -ipath "$notes_dir/*$**" -type f 2>&1)
4365
local find_result=$?
@@ -130,6 +152,7 @@ Usage:
130152
notes ls <pattern> # List notes by path
131153
notes find|f [pattern] # Search notes by filename and path
132154
notes grep|g <pattern> # Search notes by content
155+
notes search|s [pattern] # Search notes by filename or content
133156
notes open|o # Open your notes directory
134157
notes open|o <name> # Open a note for editing by full name
135158
notes rm [-r | --recursive] <name> # Remove note, or folder if -r or --recursive is given
@@ -160,6 +183,9 @@ main() {
160183
"ls" )
161184
cmd="ls_notes"
162185
;;
186+
"search"|"s" )
187+
cmd="search_filenames_and_contents"
188+
;;
163189
"find"|"f" )
164190
cmd="find_notes"
165191
;;

test/test-search.bats

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!./libs/bats/bin/bats
2+
3+
load 'libs/bats-support/load'
4+
load 'libs/bats-assert/load'
5+
load 'helpers'
6+
7+
setup() {
8+
setupNotesEnv
9+
}
10+
11+
teardown() {
12+
teardownNotesEnv
13+
}
14+
15+
notes="./notes"
16+
17+
@test "Should output nothing and return non-zero if there are no notes to search" {
18+
run $notes search
19+
20+
assert_failure
21+
echo $output
22+
assert_equal $(echo $output | wc -w) 0
23+
}
24+
25+
@test "Should show all notes found if no pattern is provided to search" {
26+
touch $NOTES_DIRECTORY/note1.md
27+
touch $NOTES_DIRECTORY/note2.md
28+
29+
run $notes search
30+
assert_success
31+
assert_line "note1.md"
32+
assert_line "note2.md"
33+
}
34+
35+
@test "Should search notes when using the search shorthand alias" {
36+
touch $NOTES_DIRECTORY/note.md
37+
38+
run $notes s
39+
assert_success
40+
assert_line "note.md"
41+
}
42+
43+
@test "Should show matching notes only if a pattern is provided to search" {
44+
touch $NOTES_DIRECTORY/match-note1.md
45+
touch $NOTES_DIRECTORY/hide-note2.md
46+
47+
run $notes search "match"
48+
49+
assert_success
50+
assert_line "match-note1.md"
51+
refute_line "hide-note2.md"
52+
}
53+
54+
@test "Should match notes case insensitively with search" {
55+
touch $NOTES_DIRECTORY/MATCH-note1.md
56+
touch $NOTES_DIRECTORY/hide-note2.md
57+
58+
run $notes search "match"
59+
60+
assert_success
61+
assert_line "MATCH-note1.md"
62+
refute_line "hide-note2.md"
63+
}
64+
65+
@test "Should match subdirectory or file names with search" {
66+
touch "$NOTES_DIRECTORY/hide-note.md"
67+
mkdir "$NOTES_DIRECTORY/match-directory"
68+
touch "$NOTES_DIRECTORY/match-directory/note.md"
69+
70+
run $notes search "match"
71+
72+
assert_success
73+
assert_output "match-directory/note.md"
74+
}
75+
76+
# These are the 'grep' tests.
77+
78+
@test "Should match only the files containing the given pattern when searching" {
79+
echo "my-pattern" > $NOTES_DIRECTORY/matching-note.md
80+
echo "some-other-pattern" > $NOTES_DIRECTORY/non-matching-note.md
81+
82+
run $notes search my-pattern
83+
84+
assert_success
85+
assert_line "matching-note.md"
86+
refute_line "non-matching-note.md"
87+
}
88+
89+
@test "Should search notes when using the search shorthand alias" {
90+
echo "my-pattern" > $NOTES_DIRECTORY/matching-note.md
91+
92+
run $notes s my-pattern
93+
94+
assert_success
95+
assert_line "matching-note.md"
96+
}
97+
98+
@test "Should search case-insensitively" {
99+
echo "LETTERS" > $NOTES_DIRECTORY/matching-note.md
100+
101+
run $notes search letter
102+
103+
assert_success
104+
assert_line "matching-note.md"
105+
}
106+
107+
@test "Should search files with paths including spaces" {
108+
mkdir "$NOTES_DIRECTORY/path with spaces"
109+
echo 'match' > "$NOTES_DIRECTORY/path with spaces/note file.md"
110+
111+
run $notes search match
112+
113+
assert_success
114+
assert_output "path with spaces/note file.md"
115+
}

0 commit comments

Comments
 (0)