Search with Vim without opening Joplin terminal app

Hello!

I'd like to use Vim to search through the notebooks without opening terminal app. Actually, I'm able to do it with a workaround. First, I export everything in Markdown format and then I use Vim with Ack plugin to see every search result and open a file if needed. It's more convenient than using "search" command in terminal app, in my opinion. Ideally, I could do that directly with Joplin notebooks, make modifications in Vim, and sync it.

You might like this - GitHub - ZwodahS/jopvim.nvim

It uses the data api and allows you to search your joplin notes using telescope in neovim.

In case you need any help with it this is what I did to get it to work as I wasn't familiar with telescope in general.

  • Added jopvim to my init.vim vim-plug section
  • Added "lua require('conf.jopvim') to my init.vim
  • Created lua/conf within my .config/nvim dir
  • Created a jopvim.lua with the config detailed in the jopvim.nvim repo
  • ran :lua require("jopvim.telescope").joplin_notes() (I know it needs to be mapped, just wanted proof of concept at this point)
1 Like

My Friend!

I'll definitely check it out when I'll have free time and will give a feedback. Million thanks!

Finally, I'm back to write my solution! After thinking about different approaches I made a conclusion that I don't need to open Neovim right away. As for GitHub - ZwodahS/jopvim.nvim, I didn't like the Disclaimer to be honest, plus I already use "junegunn/fzf.vim", so I didn't want put another fuzzy finder (Telescope) in my 'init.vim'. It probably works nicely but isn't really necessary for me. So, I will share working code with explanations here which could be modified and used however anybody would like. Hopefully, someone will find it useful :slight_smile:

Requirements


Scenario 1: You know you have a key word or phrase somewhere in your notebooks but you don't know where it is

edjop() {
	joplin edit $1
	joplin sync
}

joplin_search_all() {
	# Get all note data from database
	notes=$(sqlite3 ~/.config/joplin/database.sqlite "select id from notes;")
	search_command="rg '${1}' "
	# Convert string to array
	note_array=($(echo $notes| tr ";" "\n"))

	# Search each Markdown file containing note data
	for i in "${note_array[@]}"
	do
		search_command+=$i'.md '
	done

	eval $search_command
}

snote() {
	CPATH=$PWD
	cd ~/Dropbox/Apps/Joplin
	joplin sync
	if [ "$1" = "-f" ]
	then
		joplin_search_folder $2
	else
		joplin_search_all $1
	fi
	cd $CPATH
}

Here we call snote "your query" from terminal, make sure everything is up to date (joplin sync) and then we get the results from all our notes in our terminal. If we need to modify something we call ejop "filename or note ID" and after editing everything will be synced.

Scenario 2: You know you have a key word or phrase in specific note

edjop() {
	joplin edit $1
	joplin sync
}

jnote() {
	joplin sync
	note_name=$(sqlite3 ~/.config/joplin/database.sqlite "select title from notes;" | fzf)
	note_id=$(sqlite3 ~/.config/joplin/database.sqlite "select id from notes where title='$note_name';")
	edjop $note_id
}

At this point, we can just open any note in Vim/Neovim and do whatever we want.

Scenario 3: You know you have a key word or phrase in specific folder (notebook)

joplin_find_subfolders() {
	for i in "${folders_array[@]}"
	do
		if [[ ! " ${checked_folders_array[*]} " =~ $i ]]; then
			subfolders_string=$(sqlite3 ~/.config/joplin/database.sqlite "select id from folders where parent_id='$i';")
			checked_folders_array+=$i
			
			if [ "$subfolders_string" ]
			then
				subfolders_array=($(echo $subfolders_string| tr ";" "\n"))
				folders_array+="${subfolders_array[@]}"
				joplin_find_subfolders "${folders_array[@]}" "${checked_folders_array[@]}"
			fi
		fi
	done
}

joplin_search_folder() {
	search_command="rg '${1}' "
	main_folder_name=$(sqlite3 ~/.config/joplin/database.sqlite "select title from folders;" | fzf)
	main_folder_id=$(sqlite3 ~/.config/joplin/database.sqlite "select id from folders where title='$main_folder_name';")
	folders_array=($(echo $main_folder_id| tr ";" "\n"))
	checked_folders_array=()
	joplin_find_subfolders "${folders_array[@]}" "${checked_folders_array[@]}"
	final_array=($(echo $folders_array| tr ";" "\n"))

	for i in "${final_array[@]}"
	do
		notes=$(sqlite3 ~/.config/joplin/database.sqlite "select id from notes where parent_id='$i';")
		notes_array=($(echo $notes| tr ";" "\n"))

		for j in "${notes_array[@]}"
		do
			search_command+=$j'.md '
		done

	done
	eval $search_command
}

snote() {
	CPATH=$PWD
	cd ~/Dropbox/Apps/Joplin
	joplin sync
	# Search in specific directory
	if [ "$1" = "-f" ]
	then
		joplin_search_folder $2
	else
		joplin_search_all $1
	fi
	cd $CPATH
}

Here we call snote -f "your query" from terminal, make sure everything is up to date (joplin sync), make sure every subfolder is included, and then we get the results from our notes from folder in our terminal. Again, ff we need to modify something we call ejop "filename or note ID" and after editing everything will be synced.


Any suggestion how to improve it is welcomed.

2 Likes