Skip to content

Commit 1933100

Browse files
committed
add combined grep/find as search
1 parent d7ff4f3 commit 1933100

File tree

3 files changed

+146
-2
lines changed

3 files changed

+146
-2
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ Searches all note content for the given string and returns all the matches. Shor
7171

7272
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.
7373

74+
### `notes search <part-of-a-note-name-or-note-content>`
75+
76+
Searches all note content and note filenames for the given string and returns all the matches. Shorthand alias also available with `notes s`.
77+
7478
### `notes open`
7579

7680
Opens your notes folder in your default configured file explorer. Shorthand alias also available with `notes o`.
@@ -91,7 +95,7 @@ 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)
98+
- [x] Combining find and grep, to match either one (https://github.com/pimterry/notes/issues/16)
9599
- [ ] More interesting and nicer looking file/grep search result formatting, perhaps only when not piping? (https://github.com/pimterry/notes/issues/27)
96100
- [ ] Make the file extension optional (https://github.com/pimterry/notes/issues/24)
97101
- [ ] zsh command and note name autocompletion (https://github.com/pimterry/notes/issues/25)

notes

Lines changed: 26 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
@@ -159,6 +182,8 @@ main() {
159182
;;
160183
"ls" )
161184
cmd="ls_notes"
185+
"search"|"s")
186+
cmd="search_filenames_and_contents"
162187
;;
163188
"find"|"f" )
164189
cmd="find_notes"

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+
@test "Should search files inside subdirectories with spaces" {
77+
mkdir "$NOTES_DIRECTORY/path with spaces"
78+
touch "$NOTES_DIRECTORY/path with spaces/note.md"
79+
80+
run $notes search
81+
82+
assert_success
83+
assert_output "path with spaces/note.md"
84+
}
85+
86+
# These are the 'grep' tests.
87+
88+
@test "Should match only the files containing the given pattern when searching" {
89+
echo "my-pattern" > $NOTES_DIRECTORY/matching-note.md
90+
echo "some-other-pattern" > $NOTES_DIRECTORY/non-matching-note.md
91+
92+
run $notes search my-pattern
93+
94+
assert_success
95+
assert_line "matching-note.md"
96+
refute_line "non-matching-note.md"
97+
}
98+
99+
@test "Should search notes when using the search shorthand alias" {
100+
echo "my-pattern" > $NOTES_DIRECTORY/matching-note.md
101+
102+
run $notes s my-pattern
103+
104+
assert_success
105+
assert_line "matching-note.md"
106+
}
107+
108+
@test "Should search case-insensitively" {
109+
echo "LETTERS" > $NOTES_DIRECTORY/matching-note.md
110+
111+
run $notes search letter
112+
113+
assert_success
114+
assert_line "matching-note.md"
115+
}

0 commit comments

Comments
 (0)