├── LICENSE ├── README.md └── edit.py /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Keith Smiley (http://keith.so) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the 'Software'), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # edit-weechat 2 | 3 | This simple [weechat](https://weechat.org/) plugin allows you to 4 | compose messages in your `$EDITOR`. 5 | 6 | # Usage 7 | 8 | ```sh 9 | /edit 10 | # Type some stuff 11 | # Save and quit 12 | ``` 13 | 14 | # Configuration 15 | 16 | If you'd like to customize the editor you use outside of the `$EDITOR` 17 | environment variable, you can set it in weechat. 18 | 19 | ```sh 20 | /set plugins.var.python.edit.editor "vim -f" 21 | ``` 22 | 23 | In case you want to run editor externally without blocking weechat (since 24 | blocking weechat can break things), you can configure the plugin like this: 25 | 26 | ``` 27 | /set plugins.var.python.edit.editor "gvim -f" 28 | /set plugins.var.python.edit.run_externally "true" 29 | ``` 30 | 31 | You can of course use any editor you want, you can even spawn a terminal and 32 | use terminal vim if you prefer. 33 | 34 | # Installation 35 | 36 | Copy the script to `~/.weechat/python/autoload` 37 | 38 | ``` 39 | mkdir -p ~/.weechat/python/autoload 40 | wget https://raw.githubusercontent.com/keith/edit-weechat/master/edit.py ~/.weechat/python/autoload 41 | ``` 42 | -------------------------------------------------------------------------------- /edit.py: -------------------------------------------------------------------------------- 1 | # Open your $EDITOR to compose a message in weechat 2 | # 3 | # Usage: 4 | # /edit 5 | # 6 | # Optional settings: 7 | # /set plugins.var.python.edit.editor "vim -f" 8 | # /set plugins.var.python.edit.run_externally "false" 9 | # 10 | # If run_externally, the editor is spawned without blocking weechat. The 11 | # process should not output to the terminal (use GUI program or spawn a new 12 | # terminal). Otherwise the editor is executed in the current terminal (blocking 13 | # weechat, which can break stuff). 14 | # 15 | # History: 16 | # 2022-09-09 17 | # Version 1.0.4: Use temporary files for the message 18 | # Version 1.0.3: Drop terminal option and leave that up to the user 19 | # 10-18-2015 20 | # Version 1.0.2: Add the ability to run the editor in a external terminal 21 | # Version 1.0.1: Add configurable editor key 22 | # Version 1.0.0: initial release 23 | 24 | VERSION = "1.0.4" 25 | 26 | import json 27 | import os 28 | import os.path 29 | import shlex 30 | import subprocess 31 | import tempfile 32 | import weechat 33 | 34 | def xdg_cache_dir(): 35 | return os.path.expanduser(os.environ.get("XDG_CACHE_HOME", "~/.cache/")) 36 | 37 | def weechat_cache_dir(): 38 | cache_dir = os.path.join(xdg_cache_dir(), "weechat") 39 | if os.path.exists(cache_dir): 40 | return cache_dir 41 | return os.path.expanduser(os.environ.get("WEECHAT_HOME", "~/.weechat/")) 42 | 43 | 44 | def editor_process_cb(data, command, return_code, out, err): 45 | buf, path = json.loads(data) 46 | 47 | if return_code != 0: 48 | cleanup(path, buf) 49 | weechat.prnt("", "{}: {}".format( 50 | err.strip(), 51 | return_code 52 | )) 53 | return weechat.WEECHAT_RC_ERROR 54 | 55 | if return_code == 0: 56 | read_file(path, buf) 57 | cleanup(path, buf) 58 | 59 | return weechat.WEECHAT_RC_OK 60 | 61 | 62 | def cleanup(path, buf): 63 | try: 64 | os.remove(path) 65 | except (OSError, IOError): 66 | pass 67 | 68 | weechat.command(buf, "/window refresh") 69 | 70 | 71 | def read_file(path, buf): 72 | try: 73 | with open(path) as f: 74 | text = f.read().strip() 75 | 76 | weechat.buffer_set(buf, "input", text) 77 | weechat.buffer_set(buf, "input_pos", str(len(text))) 78 | 79 | except (OSError, IOError): 80 | pass 81 | 82 | weechat.command(buf, "/window refresh") 83 | 84 | 85 | def hook_editor_process(editor, path, buf): 86 | editor_cmd = "{} {}".format(editor, path) 87 | data = json.dumps([buf, path]) 88 | weechat.hook_process( 89 | shlex.join(shlex.split(editor) + [path]), 0, "editor_process_cb", data) 90 | 91 | 92 | def run_blocking(editor, path, buf): 93 | cmd = shlex.split(editor) + [path] 94 | code = subprocess.Popen(cmd).wait() 95 | 96 | if code != 0: 97 | cleanup(path, buf) 98 | 99 | read_file(path, buf) 100 | 101 | 102 | def edit(data, buf, args): 103 | editor = (weechat.config_get_plugin("editor") 104 | or os.environ.get("EDITOR", "vim -f")) 105 | 106 | run_externally = weechat.config_string_to_boolean( 107 | weechat.config_get_plugin("run_externally") 108 | ) 109 | run_externally = bool(run_externally) 110 | 111 | f, path = tempfile.mkstemp(prefix = "weechat-edit-") 112 | os.close(f) 113 | 114 | with open(path, "w+") as f: 115 | f.write(weechat.buffer_get_string(buf, "input")) 116 | 117 | if run_externally: 118 | hook_editor_process(editor, path, buf) 119 | else: 120 | run_blocking(editor, path, buf) 121 | 122 | return weechat.WEECHAT_RC_OK 123 | 124 | 125 | def main(): 126 | if not weechat.register("edit", "Keith Smiley", VERSION, "MIT", 127 | "Open your $EDITOR to compose a message", "", ""): 128 | return weechat.WEECHAT_RC_ERROR 129 | 130 | weechat.hook_command("edit", "Open your $EDITOR to compose a message", "", 131 | "", "", "edit", "") 132 | 133 | 134 | if __name__ == "__main__": 135 | main() 136 | --------------------------------------------------------------------------------