Skip to content

Instantly share code, notes, and snippets.

@GermainZ
Last active September 29, 2018 16:31
Show Gist options
  • Save GermainZ/d458cb014059f6fa56f3d46da4eb7c4b to your computer and use it in GitHub Desktop.
Save GermainZ/d458cb014059f6fa56f3d46da4eb7c4b to your computer and use it in GitHub Desktop.
diff --git a/README.md b/README.md
index cce0d81..7a9e5bb 100644
--- a/README.md
+++ b/README.md
@@ -72,9 +72,11 @@ default, and can be shown to display line numbers next to the chat window
(Depending on your configuration, you may need to adjust some of its settings
for it to be displayed correctly, but the defaults should suit most users.)
-It is useful for `:<num>` commands, which will start WeeChat's cursor mode and
+It is useful for `:{num}` commands, which will start WeeChat's cursor mode and
take you to the appropriate line. You can then use the default key bindings to
-quote the message (`Q`, `m` and `q`).
+quote the message (`Q`, `m` and `q`), or do so directly in the command
+`:{num}m` / `:{num}q` / `:{num}Q`). Additionally, you can quote multiple lines
+at once using a range (e.g. `:<num1>,<num2>m`)
You can customize the prefix/suffix for each line: `/fset vimode.line_number`.
@@ -199,7 +201,13 @@ Normal mode. When in search mode, pressing `/` will start a new search.
* `:s/pattern/repl`
`:s/pattern/repl/g`
Search/Replace \*
-* `:<num>` Start cursor mode and go to line.
+* `:{num}` Start cursor mode and go to line `{num}`.
+* `:{num}m` Quote message at line `{num}`.
+* `:{num}q` Quote prefix + message at line `{num}`.
+* `:{num}Q` Quote time + prefix + message at line `{num}`.
+* `:{num1},{num2}m` Quote messages from line `{num1}` to line `{num2}`.
+* `:{num1},{num2}q` Similar to above.
+* `:{num1},{num2}Q` Similar to above.
* `:nmap` List user-defined key mappings.
* `:nmap {lhs} {rhs}`
Map {lhs} to {rhs} for Normal mode.
diff --git a/vimode.py b/vimode.py
index 06f9c28..da03b7f 100755
--- a/vimode.py
+++ b/vimode.py
@@ -1467,6 +1467,77 @@ def load_user_mappings():
# Command-line execution.
# -----------------------
+def format_focus_message(focus, cmd):
+ """Format quoted line, similar to WeeChat's cursor mode q/Q/m bindings."""
+ time = "{} ".format(focus['_chat_line_time']) if cmd == "Q" else ""
+ if cmd in ["Q", "q"]:
+ prefix = focus['_chat_line_prefix']
+ if 'prefix_' in focus['_chat_line_tags']:
+ prefix = "<{}>".format(prefix)
+ prefix += " "
+ else:
+ prefix = ""
+ message = focus['_chat_line_message']
+ return "{}{}{}".format(time, prefix, message)
+
+def handle_range_command(data):
+ """Handle :[range] commands (e.g. `:22` or `:21,23m`)."""
+ range_ = None
+ # Format: `:22m` (numbers + letter).
+ if not data[-1].isdigit() and data[:-1].isdigit():
+ line_number = int(data[:-1])
+ cmd = data[-1]
+ # Format: `:21,23m` (numbers range + letter).
+ elif not data[-1].isdigit() and "," in data:
+ range_ = data[:-1].split(",", 1)
+ if range_[0].isdigit() and range_[1].isdigit():
+ range_[0] = int(range_[0])
+ range_[1] = int(range_[1])
+ line_number = range_[0]
+ else:
+ return
+ cmd = data[-1]
+ # Format: `:22` (numbers).
+ elif data.isdigit():
+ line_number = int(data)
+ cmd = None
+ # Unknown format.
+ else:
+ return
+ hdata_window = weechat.hdata_get("window")
+ window = weechat.current_window()
+ x = weechat.hdata_integer(hdata_window, window, "win_chat_x")
+ win_y = weechat.hdata_integer(hdata_window, window, "win_chat_y")
+ y = win_y + line_number - 1
+ # No command (e.g. `:22`).
+ if not cmd:
+ weechat.command("", "/cursor go {},{}".format(x, y))
+ return
+ # Unknown command.
+ elif cmd not in ["Q", "q", "m"]:
+ return
+ # Range command (e.g. `:21,23m`).
+ elif range_:
+ message = []
+ last_line_ptr = None
+ for line_number in range(range_[0], range_[1] + 1):
+ y = win_y + line_number - 1
+ focus = weechat.info_get_hashtable("gui_focus_info",
+ {"x": str(x), "y": str(y)})
+ # Don't duplicate lines (can happen for lines that wrap).
+ if last_line_ptr == focus['_chat_line']:
+ continue
+ last_line_ptr = focus['_chat_line']
+ message.append(format_focus_message(focus, cmd))
+ message = "\n".join(message)
+ # Single-line command (e.g. `:22m`).
+ else:
+ focus = weechat.info_get_hashtable("gui_focus_info",
+ {"x": str(x), "y": str(y)})
+ message = format_focus_message(focus, cmd)
+ buf = weechat.current_buffer()
+ weechat.buffer_set(buf, "input", message)
+
def cb_exec_cmd(data, remaining_calls):
"""Translate and execute our custom commands to WeeChat command."""
# Process the entered command.
@@ -1496,14 +1567,8 @@ def cb_exec_cmd(data, remaining_calls):
weechat.command("", "/exec -buffer shell %s" % data[1:])
# Commands like `:22`. This should start cursor mode (``/cursor``) and take
# us to the relevant line.
- elif data.isdigit():
- line_number = int(data)
- hdata_window = weechat.hdata_get("window")
- window = weechat.current_window()
- x = weechat.hdata_integer(hdata_window, window, "win_chat_x")
- y = (weechat.hdata_integer(hdata_window, window, "win_chat_y") +
- (line_number - 1))
- weechat.command("", "/cursor go {},{}".format(x, y))
+ elif data and data[0].isdigit():
+ handle_range_command(data)
# Check againt defined commands.
elif data:
raw_data = data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment