Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F12061383
D3724.id9632.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D3724.id9632.diff
View Options
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -63,6 +63,22 @@
See below if you wish to host the Git repository locally.
+### Delete words from a dictionary
+
+Now your dictionaries are synced, it can be tricky to delete words from them,
+as the next sync will overwrite them and restore words you removed if still in
+the Git repository or one local fi
+le.
+
+If you added a word in a dictionary, you can delete it:
+
+```shell
+$ merge-dictionaries --delete-words <word> [word ...]
+```
+
+This is a potentially destructive operation:
+your dictionary files will be overwritten.
+
## IDE support
Currently, the following IDEs are supported
@@ -83,6 +99,7 @@
* a method to dump the extracted words in the IDE format
* write
* a method to save the files, normally you can call the ones created
+ * a method to rewrite a file with a list of words, so delete works too
### How can I contribute?
@@ -92,23 +109,6 @@
## FAQ
-### Delete a word
-
-Not yet implemented. Here a proposal to implement this.
-
-Curently, the workflow is:
-
-[ extract ] -> { words } -> [ publish ]
-
-You want to add a new transformation step:
-
-[ extract ] -> { words } -> [ transform ] -> { words cleaned up } -> [ publish ]
-
-Add a transform step with an allowlist of the words to remove.
-
-It's not easy to detect if the user has removed a word explicitly
-from a dictionary, as we don't cache extracted words.
-
### Host locally the Git repository
If you want to host the repository on your local machine, use a bare repository:
diff --git a/setup.cfg b/setup.cfg
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = merge-dictionaries
-version = 0.3.0
+version = 0.4.0
author = Sébastien Santoro
author_email = dereckson@espace-win.org
description = Merge dictionaries
diff --git a/src/mergedictionaries/actions/__init__.py b/src/mergedictionaries/actions/__init__.py
new file mode 100644
--- /dev/null
+++ b/src/mergedictionaries/actions/__init__.py
@@ -0,0 +1,9 @@
+# -------------------------------------------------------------
+# Merge dictionaries :: Actions
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+from .delete_words import DeleteAction
diff --git a/src/mergedictionaries/actions/delete_words.py b/src/mergedictionaries/actions/delete_words.py
new file mode 100644
--- /dev/null
+++ b/src/mergedictionaries/actions/delete_words.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+# -------------------------------------------------------------
+# Delete words from all dictionaries
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Delete words from all dictionaries from
+# all currently found sources.
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+from mergedictionaries import sources, write
+from mergedictionaries.sources import GitRepository
+
+
+class DeleteAction:
+ def __init__(self, context):
+ self.git_config = context["config"].get("git", [])
+
+ if "git" not in context:
+ context["git"] = []
+ self.git_cached_repos = context["git"]
+
+ def run(self, words):
+ for source in self.get_sources():
+ for arg in source["query"]():
+ source["delete"](words, arg)
+
+ def get_sources(self):
+ return [
+ {
+ "query": sources.jetbrains.find_application_level_dictionaries,
+ "delete": lambda words, file: write.jetbrains.delete_words(file, words),
+ },
+ {
+ "query": self.query_git_repositories,
+ "delete": lambda words, repo: write.git.delete_words(repo, words),
+ },
+ ]
+
+ def query_git_repositories(self):
+ return [
+ GitRepository(git_repo_url, self.git_cached_repos)
+ for git_repo_url in self.git_config
+ ]
diff --git a/src/mergedictionaries/app/app.py b/src/mergedictionaries/app/app.py
--- a/src/mergedictionaries/app/app.py
+++ b/src/mergedictionaries/app/app.py
@@ -17,6 +17,7 @@
import yaml
from mergedictionaries import write, output, sources
+from mergedictionaries.actions import DeleteAction
# -------------------------------------------------------------
@@ -74,6 +75,15 @@
help="Merge all found dictionaries",
)
+ parser.add_argument(
+ "-D",
+ "--delete-words",
+ metavar="word",
+ dest="delete_words",
+ nargs="+",
+ help="Delete one or more words from the dictionaries",
+ )
+
return parser.parse_args()
@@ -84,17 +94,24 @@
def run(self):
args = parse_arguments()
- if args.task is None:
+ task = "delete" if args.delete_words else args.task
+ if task is None:
print("No task has been specified.", file=sys.stderr)
sys.exit(1)
self.context["config"] = parse_configuration()
self.context["args"] = args
- if args.task == "extract":
+ if task == "extract":
self.run_extract_all_words(args.format)
- elif args.task == "merge":
+ elif task == "merge":
self.run_merge()
+ elif task == "delete":
+ action = DeleteAction(self.context)
+ action.run(args.delete_words)
+
+ self.on_exit()
+ sys.exit(0)
def get_dictionary_writers(self):
return [
@@ -110,8 +127,6 @@
for method in self.get_dictionary_writers():
method(words)
- self.on_exit()
-
def get_words_sources(self):
return [
lambda: sources.git.extract_words_from_all_dictionaries(
@@ -137,8 +152,7 @@
for word in words:
print(word)
- self.on_exit()
- sys.exit(0)
+ return
# We need a specific formatter
formatters = get_dictionary_formatters()
@@ -148,12 +162,10 @@
sys.exit(2)
print(formatters[words_format](words))
- self.on_exit()
- sys.exit(0)
def on_exit(self):
"""Events to run before exiting to cleanup resources."""
- sources.git.on_exit(self.context["git"])
+ sources.git.on_exit(self.context.get("git", {}))
def run():
diff --git a/src/mergedictionaries/utils/collections.py b/src/mergedictionaries/utils/collections.py
new file mode 100644
--- /dev/null
+++ b/src/mergedictionaries/utils/collections.py
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------
+# Merge dictionaries :: Utilities :: Collections
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Helper functions for lists
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+from typing import List
+
+
+def remove_words(current_words: List, words_to_delete: List) -> List:
+ """
+ Removes specified words from a list of words.
+
+ Parameters:
+ current_words: list
+ The list of words from which specified words are to be removed.
+ words_to_delete: list
+ The list containing words that need to be removed.
+
+ Returns:
+ list
+ A new list containing words from the current_words list that are not
+ present in the words_to_delete list.
+ """
+ words = list(set(current_words) - set(words_to_delete))
+ words.sort()
+
+ return words
diff --git a/src/mergedictionaries/write/git.py b/src/mergedictionaries/write/git.py
--- a/src/mergedictionaries/write/git.py
+++ b/src/mergedictionaries/write/git.py
@@ -6,10 +6,14 @@
# from Git repository
# License: BSD-2-Clause
# -------------------------------------------------------------
+
+
import os
from tempfile import NamedTemporaryFile
+from typing import List
from mergedictionaries.sources import GitRepository
+from mergedictionaries.utils.collections import remove_words
def build_temporary_dictionary(words):
@@ -31,3 +35,18 @@
GitRepository(repo, cached_repos).publish(tmp_dictionary_path)
os.unlink(tmp_dictionary_path)
+
+
+def delete_words(repo: GitRepository, words_to_delete: List):
+ current_words = repo.extract_words()
+
+ if not any(word in current_words for word in words_to_delete):
+ # Nothing to do, the dictionary is already up to date.
+ return
+
+ words = remove_words(current_words, words_to_delete)
+
+ tmp_dictionary_path = build_temporary_dictionary(words)
+ repo.publish(tmp_dictionary_path)
+
+ os.unlink(tmp_dictionary_path)
diff --git a/src/mergedictionaries/write/jetbrains.py b/src/mergedictionaries/write/jetbrains.py
--- a/src/mergedictionaries/write/jetbrains.py
+++ b/src/mergedictionaries/write/jetbrains.py
@@ -10,6 +10,7 @@
from mergedictionaries.sources import jetbrains as jetbrains_source
from mergedictionaries.output import jetbrains as jetbrains_output
+from mergedictionaries.utils.collections import remove_words
def write(words):
@@ -19,3 +20,18 @@
with open(file_path, "w") as fd:
fd.write(contents)
fd.write("\n")
+
+
+def delete_words(file_path, words_to_delete):
+ current_words = jetbrains_source.extract_words(file_path)
+
+ if not any(word in current_words for word in words_to_delete):
+ # Nothing to do, the dictionary is already up to date.
+ return
+
+ words = remove_words(current_words, words_to_delete)
+
+ contents = jetbrains_output.dump(words)
+ with open(file_path, "w") as fd:
+ fd.write(contents)
+ fd.write("\n")
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Sep 30, 05:29 (19 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3028049
Default Alt Text
D3724.id9632.diff (9 KB)
Attached To
Mode
D3724: Allow to remove a word from developer dictionary
Attached
Detach File
Event Timeline
Log In to Comment