Skip to content

Commit 90add0c

Browse files
author
adam
committed
update
1 parent c9206ea commit 90add0c

File tree

8 files changed

+202
-18
lines changed

8 files changed

+202
-18
lines changed

edit

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
3+
# this script edits a note, it inserts the file name into the first line
4+
# after editing the file, it reads the first line and renames the file accordingly
5+
# It takes two arguments: 1. the editor command and 2. the note to be edited
6+
7+
set -eu
8+
9+
EDITOR=$1
10+
initial_path=$2
11+
filename="$(basename "$initial_path")"
12+
basename="${filename%.*}"
13+
14+
15+
while true; do
16+
# insert the filename if it isn't already there
17+
#first_line="$(head --lines=1 -- "$initial_path")"
18+
#if [[ "$first_line" != "$basename" ]]; then
19+
#fi
20+
21+
if [[ -f "$initial_path" ]]; then
22+
ed -s +1 "$initial_path" <<< $'i\n'"$basename"$'\n.\nw'
23+
fi
24+
25+
# edit the file and read the first line
26+
$EDITOR "$initial_path"
27+
edited_line="$(head --lines=1 -- "$initial_path")"
28+
[[ -z "$edited_line" ]] && exit 1;
29+
ed -s +1 "$initial_path" <<< $'d\nw'
30+
31+
if [[ "$basename" == "$edited_line" ]]; then
32+
break
33+
fi
34+
35+
if [[ "$filename" == *.* ]]; then
36+
extension=".${filename##*.}"
37+
else
38+
extension=""
39+
fi
40+
chosen_path="$(dirname "$initial_path")/$edited_line${extension}"
41+
if [[ -e "$chosen_path" ]]; then
42+
{ echo "i"
43+
echo "=== Error Message starts here ==="
44+
echo "The name '$edited_line' is already taken"
45+
echo "Please delete this error message then:"
46+
echo "- Save and quit to accept the original name"
47+
echo "- or, choose another name"
48+
echo "=== Error Message ends here ==="
49+
echo
50+
echo "."
51+
echo "w"
52+
} | ed -s +1 "$initial_path";
53+
continue
54+
fi
55+
if mv "$initial_path" "$chosen_path"; then
56+
break;
57+
else
58+
{ echo "i"
59+
echo "Error: rename operation failed"
60+
echo "File name is reset to the initial name"
61+
echo "Choose another name or keep the original"
62+
echo "Make sure to remove this message once done"
63+
echo "."
64+
echo "w"
65+
} | ed -s +1 "$initial_path";
66+
continue
67+
fi
68+
done

grep.sh

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

3-
# This script uses ripgrep, fzf and bat to interactively find, select, and preview notes
4-
# the script returns a string of the format "FILE\tLINE_NUMBER", where FILE is the path
5-
# to the selected note, and LINE_NUMBER is the line number of the match
3+
# This script uses ripgrep, fzf and bat to interactively find, select, and
4+
# preview notes.
5+
# The script returns a string of the format "FILE\tLINE_NUMBER".
6+
# FILE is the path of the selected file (the note)
7+
# LINE_NUMBER is the line number for the matched string
68

79
# This script takes takes the notes directory as a first argument
810
# and an initial search query as a second argument
911

1012
set -eu
1113

14+
print_usage_help() {
15+
cat <<EOF
16+
Usage: grep <notes_directory> [search_pattern]
17+
Where: <notes_directory> is the directory where the notes are stored
18+
and [search_pattern] is the optional initial search pattern
19+
EOF
20+
}
21+
1222
if (($# < 1)); then
23+
echo insuffictient number of arguments !
24+
print_usage_help
1325
exit
1426
fi
1527

new.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ NOTES_DIRECTORY=$2
1414
EDITOR=$1
1515

1616
# choose a random name for the note
17-
editing_file="$NOTES_DIRECTORY/newnote${RANDOM}"
17+
editing_file="$NOTES_DIRECTORY/newnote${RANDOM}.md"
1818

1919
# choose a new note name
2020
while true; do

readme.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,38 @@
11
A set of simple bash scripts for finding, opening and creating notes.
22

3-
This is my a very simple and naive solution for note taking, it doesn't assume
4-
much so it can easily be integrated into an editor or a window manager for convinience.
3+
The scripts are simple and doesn't assume much, so they can easily be integrated
4+
into an editor or a window manager.
5+
6+
- `resolve` takes two arguments, 1. a search query and 2. the location of the notes. it outputs the first note it finds that matches query.
7+
- `edit` takes two arguments, 1. a editor command and 2. a path to a file. it inserts the file name at the top of the file before opening it. afterwards it changes the name of the file if the first line changes. this allow the name of the note (playing the role of it's title) to be as easily cnageable as the rest of the text of the note
8+
- `select_with_*` are scripts that start with `select_with_`. they allow selecting a note using different menu programs, runners, launchers, etc.. they output a path to the selected note
9+
- `select_random` outputs a random note given a notes directory
10+
11+
# Usage Examples
12+
13+
You can bind these to your preferred window manager
14+
15+
```sh
16+
# select a note with bemenu and open it with neovide
17+
# use your preferred editor and and menu program
18+
note_select_with_bemenu ~/notes | xargs -d'\n' note_edit neovide
19+
20+
# open a new note with the name stored at clipboard
21+
# (use `xclip -sel clip` intead of `wl-paste` if you are on X11)
22+
note_edit neovide ~/notes/"$(wl-paste)"
23+
24+
# if your editor doesn't support jumping to the file at the cursor
25+
# you can copy the filename then hit a keybind to call this command
26+
# which would open the note that matches the name you copied
27+
note_resolve "$(wl-paste)" ~/notes | xargs -d"\n" note_edit neovide
28+
```
29+
30+
Note: Piping the result to `xargs` seems like a raoundabout way to pass command
31+
results as an argument. the reason for the choice is that a failing command
32+
fails the while pipeline preventing passing invalid output to the commands
33+
consuming it. whilst a command substitution passes the result regardless.
34+
35+
# QA
36+
37+
- Q: Why are the names so long and ugly
38+
- A: They are meant to be bound to keys rather than typed

resolve

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
3+
# This script resolves a link from one note to another.
4+
# Finding the target of a link is no more than finding the match of an exact
5+
# search by file name. If no matches are found, the script fails
6+
# The script takes a search query, a location to search within
7+
8+
set -eu
9+
10+
if (($# != 2)); then
11+
echo "Usage: $0 <search query> <notes directory>"
12+
echo "Example: $0 'Foundations of Mathematics' ~/notes"
13+
exit 1
14+
fi
15+
16+
SEARCH_QUERY="$1"
17+
NOTES_PATH="$(realpath "$2")"
18+
19+
FIND_COMMAND=(
20+
fd
21+
--search-path "$NOTES_PATH"
22+
--type file
23+
--and "$SEARCH_QUERY.md"
24+
)
25+
26+
search_result="$("${FIND_COMMAND[@]}" | head -1)"
27+
28+
if [[ -z "$search_result" ]]; then
29+
exit 1
30+
else
31+
printf '%s' "$search_result"
32+
fi

random.sh renamed to select_random.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
# this script selects a random note
44
# this secript takes an argument for the notes directory
55

6-
# fail if no arguments are given
6+
set -eu
7+
8+
# fail if no or too many arguments are given
79
if (($# != 1)); then
810
exit 1
911
fi
@@ -17,8 +19,9 @@ FIND_COMMAND_ZERO_TERMINATED=(fd
1719
--glob '*.md'
1820
--print0)
1921

22+
echo "$NOTES_DIRECTORY"
2023
declare -a search_results
2124
readarray -d '' search_results < <("${FIND_COMMAND_ZERO_TERMINATED[@]}")
2225

23-
# is this really how one is supposed to index a random element in bash
26+
# is this really how one is supposed to index a random array element in bash
2427
printf "%s" "${search_results[$((RANDOM % "${#search_results[@]}"))]}"

select_with_bemenu

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
set -eu
3+
4+
declare NOTES_DIRECTORY
5+
if (($# != 1)); then
6+
echo "expected exactly one argument, namely the notes directory"
7+
echo "usage: $0 <notes_direcoty>"
8+
exit 1
9+
fi
10+
11+
FIND_COMMAND=(
12+
fd
13+
--type file
14+
--and '.md$'
15+
#--print0 # outputs a NUL separated list
16+
)
17+
18+
BEMENU_FLAGS=(
19+
--list 7
20+
--ignorecase
21+
--fixed-height
22+
--no-exec
23+
)
24+
25+
NOTES_DIRECTORY="$(realpath $1)" # to normalize the path
26+
cd "$NOTES_DIRECTORY" || exit 1
27+
28+
result=$("${FIND_COMMAND[@]}" | sed 's|^'$NOTES_DIRECTORY/'||' | sed 's|.md$||' | bemenu "${BEMENU_FLAGS[@]}")
29+
[[ -z "$result" ]] && exit 1;
30+
printf '%s' "$NOTES_DIRECTORY/$result.md"
Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,42 @@
11
#!/usr/bin/env bash
22

3-
# This script uses fd and fzf to interactively find a note
3+
# This script uses fd, fzf and bat to find, select and preview notes
44
# This script requires two arguments, the first being the directory under which
55
# notes are located, and the second is an optional initial search query
66

7-
# expect at least 1 argument (the second is optional)
7+
# expect at least 1 argument
88
if (($# < 1)); then
9-
exit
9+
echo "refusig to run without arguments"
10+
echo "usage: $0 <notes_directory> [search_query]"
11+
echo "examples:"
12+
echo "$0 /path/to/notes"
13+
echo "$0 /path/to/notes metaphysics"
14+
exit 1
1015
fi
1116

1217
NOTES_DIRECTORY=$1
1318

1419
FZF_PREVIEW_COMMAND=(
15-
bat
20+
command bat
1621
--color=always
1722
--style="numbers"
18-
'{}'
23+
'{}' # place holder for the currently selected file in fzf
1924
)
2025

2126
FIND_COMMAND=(
22-
fd
27+
command fd
2328
--search-path "$NOTES_DIRECTORY"
2429
--type file
2530
--and '.md$'
26-
--print0 # outputs a NUL separated list
31+
--print0 # NUL separated output
2732
)
2833

2934
FZF_COMMAND=(
30-
fzf
35+
command fzf
3136
--prompt 'Open note> '
3237
--delimiter / --with-nth -1
3338
--preview "${FZF_PREVIEW_COMMAND[*]}"
34-
--read0 # read a NUL separated list
39+
--read0 # read a NUL separated input
3540
)
3641

3742
# if a 2nd argument is receieved, pass it as a query to fzf
@@ -43,5 +48,5 @@ chosen_note="$("${FIND_COMMAND[@]}" | "${FZF_COMMAND[@]}")"
4348
if [[ -f "$chosen_note" ]]; then
4449
printf '%s' "$chosen_note"
4550
else
46-
exit 1
51+
exit 2
4752
fi

0 commit comments

Comments
 (0)