{"id":915,"date":"2025-09-26T04:15:49","date_gmt":"2025-09-26T02:15:49","guid":{"rendered":"https:\/\/www.dereckson.be\/blog\/?p=915"},"modified":"2025-09-26T15:41:04","modified_gmt":"2025-09-26T13:41:04","slug":"unifying-your-spelling-dictionaries-with-merge-dictionaries","status":"publish","type":"post","link":"https:\/\/www.dereckson.be\/blog\/2025\/09\/26\/unifying-your-spelling-dictionaries-with-merge-dictionaries\/","title":{"rendered":"Unifying your spelling dictionaries with merge-dictionaries"},"content":{"rendered":"\n<p>If you work across multiple IDEs, you\u2019ve probably noticed that each one maintains its own spelling dictionary. Add a word in PyCharm, and PhpStorm still underlines it. Teach Hunspell a word, and your IDE doesn\u2019t know it.<\/p>\n\n\n\n<p>That\u2019s where <code>merge-dictionaries<\/code> comes in.<\/p>\n\n\n\n<p>This tool automatically discovers your dictionaries, extracts the words, and merges them into a single unified set. You can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Merge<\/strong> dictionaries with <code>--merge<\/code><\/li>\n\n\n\n<li><strong>Extract<\/strong> words safely with <code>--extract<\/code><\/li>\n\n\n\n<li><strong>Format<\/strong> output for Hunspell or IDE-specific formats with <code>--format<\/code><\/li>\n\n\n\n<li><strong>Delete<\/strong> unwanted words with <code>--delete-words word1 word2 \u2026<\/code><\/li>\n<\/ul>\n\n\n\n<p>You can even sync your dictionary with a Git repository, ensuring consistency across machines and teammates.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting started<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Install with pip<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>$ pip install merge-dictionaries<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Example: merge all your IDE dictionaries<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>$ merge-dictionaries --merge<\/code><\/pre>\n\n\n\n<p>That command will find your dictionaries in known paths, sync them all.<br>It will also publish on Git if so configured.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example: build a Hunspell personal dictionary<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>$ merge-dictionaries --extract > ~\/.hunspell_default<\/code><\/pre>\n\n\n\n<p><strong>Did you know?<\/strong> Hunspell is the spell checker of vim, LibreOffice \/ OpenOffice, Firefox, gedit, Eclipse, Scribus, Texmaker, etc.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example: sync with Git<\/h3>\n\n\n\n<p>Create a repository. Keep the name simple, like <em>dictionary<\/em> and write a <code>$HOME\/.config\/merge-dictionaries.conf<\/code> file with a YAML list of repositories:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git:\n  - git:@github.com:luser\/dictionary.git<\/code><\/pre>\n\n\n\n<p>Tip: you can also use a dotfiles-like repository: merge-dictionaries will add a <code>dictionary.txt<\/code> file in the top folder.<\/p>\n\n\n\n<p>Tip: to help you know what word come from what machine, the sync commit includes the name of the machine you run the script.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example: delete unwanted words<\/h3>\n\n\n\n<p>We understand it can be tricky to delete a word from a dictionary if at each time we run the merge command, the words are restored from Git or if you forgot you moved from CLion to  RustRover, but the CLion dictionary is still there.<\/p>\n\n\n\n<p>So the &#8211;delete-words command will find any local dictionary, your Git repository if configured and will remove the specified words from there.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ merge-dictionaries --delete-words teh alowed<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Current state of the project and future plan<\/h2>\n\n\n\n<p><code>merge-dictionaries<\/code> currently supports:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>All JetBrains IDEs (application-level dictionary)<\/li>\n\n\n\n<li>Hunspell personal dictionaries<\/li>\n\n\n\n<li>Git repositories for syncing<\/li>\n<\/ul>\n\n\n\n<p>If you want to contribute, I&#8217;ve documented in <a href=\"https:\/\/devcentral.nasqueron.org\/source\/merge-dictionaries\/browse\/main\/README.md\" data-type=\"link\" data-id=\"https:\/\/devcentral.nasqueron.org\/source\/merge-dictionaries\/browse\/main\/README.md\">the project README<\/a> where to add new back-end to support more formats. The project is open source, released under BSD-2-Clause license.<\/p>\n\n\n\n<p>This project is supported by the Nasqueron open source project, as part of the Nasqueron development tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why it matters<\/h2>\n\n\n\n<p>Having consistent spelling across tools improves focus, reduces duplication, and eliminates those \u201cwhy is this word still red?\u201d moments.<\/p>\n\n\n\n<p>It also avoids you to add on every new machine your name, the name of your project or company, your username, method names like <code>strlen<\/code>, etc.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Links<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/pypi.org\/project\/merge-dictionaries\">PyPI<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/devcentral.nasqueron.org\/source\/merge-dictionaries\/\" data-type=\"link\" data-id=\"https:\/\/devcentral.nasqueron.org\/source\/merge-dictionaries\/\">Source code<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/agora.nasqueron.org\/How_to_contribute_code\">How to contribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/devcentral.nasqueron.org\/\">Bug tracke<\/a><a href=\"https:\/\/devcentral.nasqueron.org\/project\/view\/134\/\">r<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/agora.nasqueron.org\/Get_support\">Get support<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>If you work across multiple IDEs, you\u2019ve probably noticed that each one maintains its own spelling dictionary. Add a word in PyCharm, and PhpStorm still underlines it. Teach Hunspell a word, and your IDE doesn\u2019t know it. That\u2019s where merge-dictionaries comes in. This tool automatically discovers your dictionaries, extracts the words, and merges them into [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":942,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[302,268],"class_list":["post-915","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev","tag-cli","tag-python"],"_links":{"self":[{"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/posts\/915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/comments?post=915"}],"version-history":[{"count":14,"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/posts\/915\/revisions"}],"predecessor-version":[{"id":935,"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/posts\/915\/revisions\/935"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/media\/942"}],"wp:attachment":[{"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/media?parent=915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/categories?post=915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dereckson.be\/blog\/wp-json\/wp\/v2\/tags?post=915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}