{"id":8794,"date":"2022-11-26T21:16:50","date_gmt":"2022-11-26T21:16:50","guid":{"rendered":"https:\/\/www.blopig.com\/blog\/?p=8794"},"modified":"2022-11-26T21:55:05","modified_gmt":"2022-11-26T21:55:05","slug":"unreasonably-faster-notes-with-command-line-fuzzy-search","status":"publish","type":"post","link":"https:\/\/www.blopig.com\/blog\/2022\/11\/unreasonably-faster-notes-with-command-line-fuzzy-search\/","title":{"rendered":"Unreasonably faster notes, with command-line fuzzy search"},"content":{"rendered":"\n<p>A good note system should act like a second brain:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Accessible in seconds<\/li>\n\n\n\n<li>Adding information should be frictionless<\/li>\n\n\n\n<li>Searching should be exhaustive &#8211; if it&#8217;s there, you must find it<\/li>\n<\/ol>\n\n\n\n<p>The benefits of such a note system are immense &#8211; never forget anything again! Search, perform the magic ritual of Copy Paste, and rejoice in the wisdom of your tried and tested past.<\/p>\n\n\n\n<p>But how? Through the unreasonable effectiveness of interactive fuzzy search. This is how I have used <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/Magnushhoie\/fuz\" target=\"_blank\"><em>Fuz<\/em>, a terminal-based file fuzzy finder<\/a>, for about 4 years.<\/p>\n\n\n\n<p>Briefly, <em>Fuz<\/em> extracts all text within a directory using <em><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/BurntSushi\/ripgrep\" target=\"_blank\">ripgrep<\/a><\/em>, enables interactive fuzzy search with <em><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/junegunn\/fzf\" target=\"_blank\">FZF<\/a><\/em>, and returns you the selected item. As you type, the search results get narrowed down to a few matches. Files are opened at the exact line you found. And it&#8217;s FAST &#8211; 100,000 lines in half a second fast.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/github.com\/Magnushhoie\/fuz\" target=\"_blank\" rel=\"noreferrer noopener\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"625\" height=\"348\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2022\/11\/fuz.gif?resize=625%2C348&#038;ssl=1\" alt=\"\" class=\"wp-image-8803\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2022\/11\/fuz.gif?resize=1024%2C570&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2022\/11\/fuz.gif?resize=300%2C167&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2022\/11\/fuz.gif?resize=768%2C427&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2022\/11\/fuz.gif?resize=624%2C347&amp;ssl=1 624w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><figcaption class=\"wp-element-caption\">Using <em>Fuz<\/em> to quickly add a code-snippet in our note directory &#8211; then retrieving it with fuzzy-search. Here, on how to read FASTA files with Biopython, conveniently added to a file called biopython.py.<\/figcaption><\/figure>\n\n\n\n<!--more-->\n\n\n\n<p>There are also a few other convenient features. Files are searched from memory when available, there is syntax highlighting for markdown and e.g. Python code (using <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/sharkdp\/bat\" data-type=\"URL\" data-id=\"https:\/\/github.com\/sharkdp\/bat\" target=\"_blank\"><em>bat<\/em><\/a>), and it&#8217;s clever enough to ignore binary, hidden and .gitignore files.<\/p>\n\n\n\n<p><strong>Here is how to install and use <em>Fuz<\/em>, from <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/Magnushhoie\/fuz\" target=\"_blank\">https:\/\/github.com\/Magnushhoie\/fuz<\/a><\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Download and install Fuz\ngit clone https:\/\/github.com\/Magnushhoie\/fuz\/\ncd fuz &amp;&amp; chmod +x fuz\n.\/fuz --setup\n<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Requirements (Pick one)\n\n# 1. MacOS, using brew: https:\/\/brew.sh\/\nbrew install fzf rg bat\n\n# 2. Any OS, using conda: https:\/\/conda.io\/docs\/user-guide\/install\/\nconda install -c conda-forge fzf ripgrep bat \n\n# 3. Ubuntu\nsudo apt-get install fzf ripgrep\nsudo apt install bat\nmkdir -p ~\/.local\/bin\nln -s \/usr\/bin\/batcat ~\/.local\/bin\/bat<\/pre>\n\n\n\n<p>By default, <em>Fuz<\/em> searches the current directory up to 3 levels down, but this can be modified to any depth. It can be immensely useful for finding text across a code-base, or every mention of something across all your projects. Here are a few useful options:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>fuz<\/strong>: Search text in current directory, (3) levels down<\/li>\n\n\n\n<li><strong>fuz <kbd>--<\/kbd>path: <\/strong>Search a specific directory<\/li>\n\n\n\n<li><strong>fuz <\/strong><kbd>--<\/kbd><strong>names<\/strong>: Search file-names<\/li>\n\n\n\n<li><strong>fuz <kbd>--<\/kbd>edit<\/strong>: Open file using vim<\/li>\n\n\n\n<li><strong>fuz <kbd>--<\/kbd>open<\/strong>: Open file using the system default application<\/li>\n<\/ul>\n\n\n\n<p>The<em> <kbd>--<\/kbd>setup<\/em> flag adds a few handy aliases to your <em>~\/.bashrc<\/em> or ~\/<em>.zshrc<\/em> file, pointing <em>Fuz<\/em> to a specific directory (see example in the gif above). For example, you may point <em>Fuz<\/em> to a directory where you keep text notes (e.g. <a rel=\"noreferrer noopener\" href=\"https:\/\/obsidian.md\/\" target=\"_blank\">Obsidian<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/roamresearch.com\/\" target=\"_blank\">Roam<\/a>), or a collection of code\/project files you want available at your fingertips.<\/p>\n\n\n\n<p>You can have as many files and directories as you wish. Just try to mark your entries with memorable patterns such as <em>__biopython how to read FASTA files__<\/em>, and you&#8217;ll find them in seconds &#8211; regardless of where they&#8217;re located.<\/p>\n\n\n\n<p>Good luck, and may your second brain grow limited by no bounds!<\/p>\n\n\n\n<p>(And lastly &#8211; a short list of related tools you may want to check out)<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/notational.net\/\" target=\"_blank\">Notational velocity<\/a> for MacOS<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/vhp\/terminal_velocity\" target=\"_blank\" rel=\"noreferrer noopener\">terminal-velocity<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/alichtman\/fzf-notes\" target=\"_blank\" rel=\"noreferrer noopener\">fzf-notes<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Fuz &#8211; A command-line text search tool built with FZF and ripgrep<\/p>\n","protected":false},"author":105,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","wikipediapreview_detectlinks":true,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"ngg_post_thumbnail":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[348,29,296,14,588,587,586,589],"tags":[659,673,675,677,676,674,678],"ppma_author":[672],"class_list":["post-8794","post","type-post","status-publish","format-standard","hentry","category-bash","category-code","category-hints-and-tips","category-howto","category-linux-gnu-linux","category-macos","category-os","category-windows","tag-command-line-2","tag-fuzzy","tag-fzf","tag-notes","tag-ripgrep","tag-search","tag-vim"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"authors":[{"term_id":672,"user_id":105,"is_guest":0,"slug":"magnus","display_name":"Magnus Haraldson H\u00f8ie","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/c9f3c7e35621c7406f9cba8a9ab424f33397c1c9a8c4891da48e7fb8d23139cb?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/8794","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/users\/105"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/comments?post=8794"}],"version-history":[{"count":5,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/8794\/revisions"}],"predecessor-version":[{"id":8912,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/8794\/revisions\/8912"}],"wp:attachment":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/media?parent=8794"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/categories?post=8794"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/tags?post=8794"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=8794"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}