Skip to content

Artawower/raindrop.el

Repository files navigation

✨ raindrop.el — Raindrop → Org-mode

Buy Me A Coffee donate button Patreon donate button wakatime

Introduction

Integrate your Raindrop bookmarks into Org-mode.

This package provides:

  • A dynamic block #+BEGIN: raindrop ... #+END: that renders a list of links.
  • A helper command to use current heading tags to insert/update a links list.
  • An Org-babel language raindrop that returns Org-formatted lists.
  • An interactive search interface with as-you-type completion and animated spinner.

This is an AI-assisted Emacs package, created in collaboration with a large language model (OpenAI). Requirements and vision were provided by the author.

Connected links

Screenshots

Search interface ./images/search.png Dynamic block ./images/org.png

Install

This package requires Emacs 27.1+ and Org 9.4+.

Elpaca

(use-package raindrop
  :defer t
  :ensure (raindrop :host github :repo "artawower/raindrop.el"))

Org integration

(use-package raindrop-org
  :after raindrop
  :ensure nil
  :defer t)

Raindrop search

(use-package raindrop-search
  :ensure nil
  :after raindrop
  :bind (("C-c r s" . raindrop-search))
  :defer t)

Ob raindrop (dynamic block)

(use-package ob-raindrop
  :after (org raindrop)
  :commands (org-babel-execute:raindrop)
  :ensure nil
  :init
  (with-eval-after-load 'org
    (add-to-list 'org-babel-load-languages '(raindrop . t))
    (when (boundp 'org-babel-load-languages)
      (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages))))

package-vc (Emacs 29+)

(package-vc-install '(raindrop :url "https://github.com/artawower/raindrop.el"))

(use-package raindrop)
(use-package raindrop-org :after org)
(use-package raindrop-search)
(use-package ob-raindrop :after org)

Setup (Token)

For security, prefer auth-source:

  • Create an entry: machine raindrop.io login token secret <YOUR_TOKEN>.
  • Alternatively export env var RAINDROP_TOKEN. You can also set raindrop-custom-token, but this is less secure.

Example auth-source entry for .authinfo.gpg:

machine raindrop.io login token password 0123456789abcdef

Usage

Load packages (autoloads are simple; explicit require is fine):

(require 'raindrop)
(require 'raindrop-org)
(require 'raindrop-search)
(require 'ob-raindrop)

Interactive Search Interface

Use M-x raindrop-search for an interactive search with as-you-type completion:

  • Search by tags: #emacs #lisp some text
  • Tags with spaces: #\"disk usage\" #\"file manager\" backup tools
  • Exclude tags: #emacs -#outdated (include emacs, exclude outdated)
  • Exclude spaced tags: #cli -#\"old tool\" modern tools
  • Mixed search: #programming -#legacy [Work] project
  • Search by folders: [Work] project notes
  • Combined search: #important [Archive] meeting notes
  • Animated ASCII spinner during loading
  • Smart collection/tag parsing
  • Support for all major completion frameworks (Vertico, Ivy, etc.)

Features:

  • Press RET to open the selected bookmark in your browser
  • Use M-x raindrop-search-toggle-enter-action to toggle between opening the original link and the Raindrop app URL
  • Embark integration for additional actions (edit, delete, open in different ways)

Embark Actions (when using Embark):

  • o: Open original link
  • O: Open in Raindrop app
  • e: Edit bookmark in dedicated buffer
  • D: Delete bookmark (with confirmation)
  • c: Create new bookmark (from clipboard/browser)
  • C: Create bookmark from URL in kill ring

Customization:

  • raindrop-search-idle-delay: delay before API request (default 0.25s)
  • raindrop-search-page-size: number of results per page (default 50)
  • raindrop-search-spinner-frames: spinner animation frames
  • raindrop-search-spinner-delay: spinner animation speed
  • raindrop-search-title-max / raindrop-search-excerpt-max: truncation limits

Creating Bookmarks

Create new bookmarks directly from Emacs using these functions:

  • M-x raindrop-search-create-bookmark: Create bookmark from any URL
  • M-x raindrop-search-create-from-browser: Create from clipboard (browser URL)
  • M-x raindrop-search-create-from-kill-ring: Create from URL in kill ring

All creation functions open an edit buffer where you can:

  • Set the title and description
  • Add tags (comma-separated: emacs, productivity, tools)
  • Customize before saving with C-c C-c
  • Cancel with C-c C-k

The edit buffer automatically detects URLs at point or in clipboard for quick bookmarking.

Insert/Update links under a heading (tags AND)

Add tags to a heading, e.g.:

* Books                                                        :book:fiction:

Then run:

M-x raindrop-insert-or-update-links-under-heading

This inserts (or updates) a dynamic block directly in the body of that node, rendering an Org bullet list in the form:

- [[https://example.com][Title]] — optional excerpt

Tip: Use C-u M-x raindrop-insert-or-update-links-under-heading to switch to OR semantics for tags just for this run; default is AND.

Dynamic block (manual)

You can insert a block yourself and refresh with C-c C-c:

#+BEGIN: raindrop :tags "emacs, -outdated, programming" :match all :limit 50
#+END:

Parameters:

  • :tags string with comma-separated or space-separated tags. Supports exclusion with -tag syntax (e.g., "emacs, -outdated, programming"). Both formats work: "cli -openai macos" or "cli, -openai, macos". Tags with spaces work naturally: "cli, -openai, -tui with space".
  • :folders string with comma-separated folder names (e.g., "work, personal").
  • :folder alias for :folders that accepts a single folder name.
  • :search string for text search query (e.g., "machine learning").
  • :exclude-groups string with comma-separated tags to exclude from smart grouping (e.g., "cli, terminal").
  • :match all (AND, default) or any (OR).
  • :collection numeric collection id (optional, 0 means all). If both :folders and :collection are provided, the folder names are resolved to IDs and take precedence.
  • :limit max items to fetch (default 100).
  • :smart enable smart auto-grouping by tags (t or nil, default nil).

Examples:

  • By folder only:
    #+BEGIN: raindrop :folders "Terminal" :match all :limit 20
    #+END:
        
  • Tags within a folder:
    #+BEGIN: raindrop :folders "Work" :tags "cli, -legacy" :match any :limit 30
    #+END:
        
  • With tag exclusion and smart grouping:
    #+BEGIN: raindrop :tags "emacs, -outdated, programming" :match all :limit 25 :smart t
    #+END:
        
  • Tags with spaces and exclusions:
    #+BEGIN: raindrop :tags "cli, -openai, -tui with space" :match all :output org-list :smart t
    #+END:
        
  • Text search with tags:
    #+BEGIN: raindrop :search "machine learning" :tags "python, ai" :match any :limit 20
    #+END:
        
  • Text search only:
    #+BEGIN: raindrop :search "productivity tools" :limit 15 :smart t
    #+END:
        
  • Smart grouping with excluded groups:
    #+BEGIN: raindrop :tags "emacs" :exclude-groups "cli, terminal" :smart t :limit 20
    #+END:
        

Org-babel block

Returns Org-formatted output; use :results raw replace:


Also works with folders:


With tag exclusion and tags with spaces:


Space-separated format also supported:


With text search:


Text search only:


You can also enable via babel languages API:

(with-eval-after-load 'org
  (require 'ob-raindrop))

Customization

  • raindrop-request-timeout: request timeout (seconds).
  • raindrop-default-limit: default fetch limit.
  • raindrop-auth-source-host: host to look up in auth-source.
  • raindrop-token-source: order of token sources (auth-source/env/custom).
  • raindrop-links-empty-text: text when no results.
  • raindrop-heading-tags-match: default AND/OR for heading tags.

Notes

  • Backend uses request.el for HTTP requests and json-parse-buffer for JSON parsing.
  • Content is inserted idempotently inside a dynamic block.
  • Title/excerpt are sanitized for single-line list items.
  • Interactive search supports vector-to-list conversion for Raindrop API responses.

🍩 Contribute guide

Any contribution is welcome! Please consider reading the style guide and, if you like this project, supporting via Patreon. Typical contributions:

  • Bug reports, feature requests
  • Documentation improvements
  • Code patches

This project is licensed under GPLv3 or later. Make sure your contributions are compatible with this license.

Tests

This project uses ERT tests located under test/.

Run with Eldev (recommended)

Useful variants:

  • Verbose with backtraces: eldev -dtT test
  • Select specific tests: eldev test :selector '"raindrop-parse-tags"'

Run with plain Emacs (no Eldev)

From the project root:

emacs -Q --batch -L . \
  -l raindrop.el -l raindrop-org.el \
  -l test/raindrop-core-tests.el \
  -f ert-run-tests-batch-and-exit

Notes:

  • Tests are self-contained and do not require a Raindrop token; they do not hit the network.
  • Tests automatically handle the request.el dependency via Eldev configuration.

About

Raindrop integration for OrgMode

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors