aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElena ``of Valhalla'' Grandi <valhalla@trueelena.org>2022-03-15 09:52:31 +0100
committerElena ``of Valhalla'' Grandi <valhalla@trueelena.org>2022-03-15 09:52:31 +0100
commit82eac2165d3a8bc20abea52d32a1037be8472b69 (patch)
treed6d49b0bc2e9c8623edee8e6a6e143bf7a8721a9
parent386a27282de20fbf4e41e9f9e3640deec7e77963 (diff)
Add a mixin with the ability to open a file in an external editor
-rw-r--r--hazwaz/__init__.py1
-rw-r--r--hazwaz/mixins.py42
-rw-r--r--tests/test_mixins.py37
3 files changed, 80 insertions, 0 deletions
diff --git a/hazwaz/__init__.py b/hazwaz/__init__.py
index 883ffe2..e328bee 100644
--- a/hazwaz/__init__.py
+++ b/hazwaz/__init__.py
@@ -1 +1,2 @@
+from . import mixins # noqa: F401
from .command import Command, MainCommand # noqa: F401
diff --git a/hazwaz/mixins.py b/hazwaz/mixins.py
new file mode 100644
index 0000000..5720a38
--- /dev/null
+++ b/hazwaz/mixins.py
@@ -0,0 +1,42 @@
+import logging
+import os
+import subprocess
+
+
+class ExternalEditorMixin:
+ """
+ Add facilities to open a file in an external editor to a Command.
+ """
+ editors = [
+ (os.environ.get("EDITOR"), "$EDITOR (set to {editor})"),
+ ("sensible-editor", "sensible-editor"),
+ ("vi", "vi"),
+ ]
+
+ def edit_file_in_external_editor(self, filepath):
+ """
+ Open filepath in an external editor and wait for it to be closed.
+
+ Return whether opening the file was succesful.
+ This tries to cycle through all editors listed in self.editors.
+ """
+ for editor, e_name in self.editors:
+ if editor:
+ try:
+ res = subprocess.call([editor, filepath])
+ except FileNotFoundError as e:
+ if editor in str(e):
+ logging.info('Could not open file {} with {}'.format(
+ filepath, e_name
+ ))
+ else:
+ logging.warning("Could not open file {}".format(
+ filepath
+ ))
+ return False
+ else:
+ if res == 0:
+ return True
+ else:
+ return False
+ return False
diff --git a/tests/test_mixins.py b/tests/test_mixins.py
new file mode 100644
index 0000000..1e2f91d
--- /dev/null
+++ b/tests/test_mixins.py
@@ -0,0 +1,37 @@
+import unittest
+
+import hazwaz
+
+
+class testEditorMixin(unittest.TestCase):
+ def test_open_with_cat_existing_file(self):
+ subcmd = hazwaz.mixins.ExternalEditorMixin()
+ subcmd.editors = [("cat", "cat")]
+ # TODO: suppress this output in the tests (we can't use
+ # contextlib.redirect_stdout because that doesn't redirect the
+ # stdout used by subprocess.
+ res = subcmd.edit_file_in_external_editor("/bin/fgrep")
+ self.assertTrue(res)
+
+ def test_open_with_cat_missing_file(self):
+ subcmd = hazwaz.mixins.ExternalEditorMixin()
+ subcmd.editors = [("cat", "cat")]
+ # TODO: suppress this output in the tests (we can't use
+ # contextlib.redirect_stderr because that doesn't redirect the
+ # stderr used by subprocess.
+ res = subcmd.edit_file_in_external_editor("no_such_file")
+ self.assertFalse(res)
+
+ def test_open_with_non_existing_editor(self):
+ subcmd = hazwaz.mixins.ExternalEditorMixin()
+ subcmd.editors = [("no_such_command", "no_such_command")]
+ with self.assertLogs() as cm:
+ subcmd.edit_file_in_external_editor("no_such_file")
+ self.assertIn(
+ "Could not open file no_such_file with no_such_command",
+ cm.output[0]
+ )
+
+
+if __name__ == '__main__':
+ unittest.main()