Another copy of my dotfiles. Because I don't completely trust GitHub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
5.7 KiB

  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2019 Cole Helbling <cole.e.helbling@outlook.com>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. # Changelog:
  19. # 2019-12-14, Cole Helbling <cole.e.helbling@outlook.com>
  20. # version 1.0: initial release
  21. SCRIPT_NAME = "styurl"
  22. SCRIPT_AUTHOR = "Cole Helbling <cole.e.helbling@outlook.com>"
  23. SCRIPT_VERSION = "1.0"
  24. SCRIPT_LICENSE = "GPL3"
  25. SCRIPT_DESC = "Style URLs with a Python regex"
  26. import_ok = True
  27. try:
  28. import weechat as w
  29. except ImportError:
  30. print("This script must be run under WeeChat.")
  31. print("Get WeeChat now at: https://weechat.org")
  32. import_ok = False
  33. try:
  34. import re
  35. except ImportError as message:
  36. print("Missing package for %s: %s" % (SCRIPT_NAME, message))
  37. import_ok = False
  38. # https://mathiasbynens.be/demo/url-regex
  39. # If you don't want to create your own regex, see the above link for options or
  40. # ideas on creating your own
  41. styurl_settings = {
  42. "buffer_type": (
  43. "formatted",
  44. "the type of buffers to run on (options are \"formatted\", \"free\", "
  45. "or \"*\" for both)"
  46. ),
  47. "format": (
  48. "${color:*_32}",
  49. "the style that should be applied to the URL"
  50. "(evaluated, see /help eval)"
  51. ),
  52. "ignored_buffers": (
  53. "core.weechat,python.grep",
  54. "comma-separated list of buffers to ignore URLs in "
  55. "(full name like \"irc.freenode.#alacritty\")"
  56. ),
  57. "ignored_tags": (
  58. "irc_quit,irc_join",
  59. "comma-separated list of tags to ignore URLs from"
  60. ),
  61. "regex": (
  62. r"((?:https?|ftp)://[^\s/$.?#].\S*)",
  63. "the URL-parsing regex using Python syntax "
  64. "(make sure capturing group 1 is the full URL)"
  65. ),
  66. }
  67. line_hook = None
  68. def styurl_line_cb(data, line):
  69. """
  70. Callback called when a line is displayed.
  71. This parses the message for any URLs and styles them according to
  72. styurl_settings["format"].
  73. """
  74. global styurl_settings
  75. # Don't style the line if it's not going to be displayed... duh
  76. if line["displayed"] != "1":
  77. return line
  78. tags = line["tags"].split(',')
  79. ignored_tags = styurl_settings["ignored_tags"]
  80. # Ignore specified message tags
  81. if ignored_tags:
  82. if any(tag in tags for tag in ignored_tags.split(',')):
  83. return line
  84. bufname = line["buffer_name"]
  85. ignored_buffers = styurl_settings["ignored_buffers"]
  86. # Ignore specified buffers
  87. if ignored_buffers and bufname in ignored_buffers.split(','):
  88. return line
  89. message = line["message"]
  90. # TODO: enforce presence of a properly-formatted color object at
  91. # styurl_settings["format"] (eval object would also be valid, if it eval'd
  92. # to a color)
  93. regex = re.compile(styurl_settings["regex"])
  94. url_style = w.string_eval_expression(styurl_settings["format"], {}, {}, {})
  95. reset = w.color("reset")
  96. # Search for URLs and surround them with the defined URL styling
  97. formatted = regex.sub(r"%s\1%s" % (url_style, reset), message)
  98. line["message"] = line["message"].replace(message, formatted)
  99. return line
  100. def styurl_config_cb(data, option, value):
  101. """Callback called when a script option is changed."""
  102. global styurl_settings, line_hook
  103. pos = option.rfind('.')
  104. if pos > 0:
  105. name = option[pos+1:]
  106. if name in styurl_settings:
  107. # Changing the buffer target requires us to re-hook to prevent
  108. # obsolete buffer types from getting styled
  109. if name == "buffer_type":
  110. if value in ("free", "formatted", "*"):
  111. w.unhook(line_hook)
  112. line_hook = w.hook_line(value, "", "", "styurl_line_cb",
  113. "")
  114. else:
  115. # Don't change buffer type if it is invalid
  116. w.prnt("", SCRIPT_NAME + ": Invalid buffer type: '%s', "
  117. "not changing." % value)
  118. w.config_set_plugin(name, styurl_settings[name])
  119. return w.WEECHAT_RC_ERROR
  120. styurl_settings[name] = value
  121. return w.WEECHAT_RC_OK
  122. def styurl_unload_cb():
  123. """Callback called when the script is unloaded."""
  124. global line_hook
  125. w.unhook(line_hook)
  126. del line_hook
  127. return w.WEECHAT_RC_OK
  128. if __name__ == "__main__" and import_ok:
  129. if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
  130. SCRIPT_DESC, "styurl_unload_cb", ""):
  131. version = w.info_get("version_number", "") or 0
  132. for option, value in styurl_settings.items():
  133. if w.config_is_set_plugin(option):
  134. styurl_settings[option] = w.config_get_plugin(option)
  135. else:
  136. w.config_set_plugin(option, value[0])
  137. styurl_settings[option] = value[0]
  138. if int(version) >= 0x00030500:
  139. w.config_set_desc_plugin(option, "%s (default: \"%s\")"
  140. % (value[1], value[0]))
  141. w.hook_config("plugins.var.python." + SCRIPT_NAME + ".*",
  142. "styurl_config_cb", "")
  143. # Style URLs
  144. line_hook = w.hook_line(styurl_settings["buffer_type"], "", "",
  145. "styurl_line_cb", "")