From 2791a3065c881a5338a2acad92321aa200fb672d Mon Sep 17 00:00:00 2001 From: Serpent7776 Date: Sat, 6 Apr 2024 14:25:48 +0200 Subject: [PATCH] F1 shows man page for current query --- pgcli/key_bindings.py | 17 +++++++++++++++++ pgcli/man.py | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 pgcli/man.py diff --git a/pgcli/key_bindings.py b/pgcli/key_bindings.py index 9c016f7ff..2f0c9f206 100644 --- a/pgcli/key_bindings.py +++ b/pgcli/key_bindings.py @@ -1,4 +1,6 @@ import logging +import click +import re from prompt_toolkit.enums import EditingMode from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.filters import ( @@ -8,6 +10,7 @@ has_selection, vi_mode, ) +from .man import man from .pgbuffer import buffer_should_be_handled, safe_multi_line_mode @@ -20,6 +23,20 @@ def pgcli_bindings(pgcli): tab_insert_text = " " * 4 + @kb.add("f1") + def _(event): + """Show man page for current command.""" + _logger.debug("Detected key.") + + m = re.match(r"^[\w\s]+", event.app.current_buffer.text) + if not m: + return + click.clear() + text = m.group() + _logger.debug(f"Launching man page for {text}") + if not man(text): + _logger.debug("Failed to show man page") + @kb.add("f2") def _(event): """Enable/Disable SmartCompletion Mode.""" diff --git a/pgcli/man.py b/pgcli/man.py new file mode 100644 index 000000000..ab6716183 --- /dev/null +++ b/pgcli/man.py @@ -0,0 +1,44 @@ +import subprocess + +IGNORED = [ + "OR", + "REPLACE", + "DEFAULT", + "UNIQUE", + "TRUSTED", + "PROCEDURAL", + "TEMP", + "TEMPORARY", + "UNLOGGED", + "GLOBAL", + "LOCAL", + "CONSTRAINT", + "RECURSIVE", + "WORK", + "TRANSACTION", + "SESSION", +] + + +def try_man(page): + try: + subprocess.run( + f"man -I 7 {page}", shell=True, check=True, universal_newlines=True + ) + return True + except subprocess.CalledProcessError: + return False + + +def man(query): + words = query.strip().split()[:6] + words = map(lambda e: e.upper(), words) + words = list(filter(lambda e: e not in IGNORED, words)) + if not words: + return True + if words[0] == "RELEASE": + words.insert(1, "SAVEPOINT") + for i in [2, 1, 3, 4]: + if try_man("_".join(words[0 : i + 1])): + return True + return False