def command_main(data, buffer, args): args = args.split() curr_buffer = weechat.current_buffer() curr_buffer_number = weechat.buffer_get_integer(curr_buffer, "number") if len(args) != 1 and len(args) != 2: weechat.prnt("", "You need to specify 1 or 2 buffers") return weechat.WEECHAT_RC_ERROR if len(args) == 2: weechat.command("", "/buffer %s" % args[0]) first_buffer = weechat.current_buffer() first_buffer_number = weechat.buffer_get_integer(first_buffer, "number") weechat.command("", "/buffer %s" % args[1]) second_buffer = weechat.current_buffer() second_buffer_number = weechat.buffer_get_integer(second_buffer, "number") else: first_buffer = weechat.current_buffer() first_buffer_number = weechat.buffer_get_integer(first_buffer, "number") weechat.command("", "/buffer %s" % args[0]) second_buffer = weechat.current_buffer() second_buffer_number = weechat.buffer_get_integer(second_buffer, "number") weechat.buffer_set(first_buffer, "number", str(second_buffer_number)) weechat.buffer_set(second_buffer, "number", str(first_buffer_number)) weechat.command("", "/buffer %s" % str(curr_buffer_number)) return weechat.WEECHAT_RC_OK
def sort_buffers(udata, signal, buf): bufs_dict = defaultdict(set) for buf in buffers(): if weechat.buffer_get_integer(buf, "active") != 0: bufs_dict[weechat.buffer_get_integer(buf, "number")].add(buf) for i, bufs in enumerate(sorted(bufs_dict.values(), key=buffer_key), 1): buf = next(iter(bufs)) weechat.buffer_set(buf, "number", str(i)) return weechat.WEECHAT_RC_OK
def tc_bar_item_update (data=None, signal=None, signal_data=None): '''Updates bar item''' '''May be used as a callback or standalone call.''' global length, cursor_pos, tc_input_text current_buffer = w.current_buffer() length = w.buffer_get_integer(current_buffer,'input_length') cursor_pos = w.buffer_get_integer(current_buffer,'input_pos') + 1 w.bar_item_update('tc') return w.WEECHAT_RC_OK
def replace_misspelled_word(buffer): input_line = weechat.buffer_get_string(buffer, 'localvar_spell_correction_suggest_input_line') if not input_line: # remove spell_correction item weechat.buffer_set(buffer, 'localvar_del_spell_correction_suggest_item', '') weechat.bar_item_update('spell_correction') weechat.bar_item_update('spell_suggestion') return if OPTIONS['eat_input_char'].lower() == 'off' or input_line == '': input_pos = weechat.buffer_get_integer(buffer,'input_pos') # check cursor position if len(input_line) < int(input_pos) or input_line[int(input_pos)-1] == ' ' or input_line == '': input_line = weechat.buffer_get_string(buffer, 'input') weechat.buffer_set(buffer, 'localvar_del_spell_correction_suggest_input_line', '') localvar_aspell_suggest = get_localvar_aspell_suggest(buffer) # localvar_aspell_suggest = word,word2/wort,wort2 if localvar_aspell_suggest: misspelled_word,aspell_suggestions = localvar_aspell_suggest.split(':') aspell_suggestions = aspell_suggestions.replace('/',',') aspell_suggestion_list = aspell_suggestions.split(',') else: return tab_complete,position,aspell_suggest_item = get_position_and_suggest_item(buffer) if not position or not aspell_suggest_item: return position = int(position) input_line = input_line.replace(misspelled_word, aspell_suggestion_list[position]) if input_line[-2:] == ' ': input_line = input_line.rstrip() input_line = input_line + ' ' weechat.buffer_set(buffer,'input',input_line) # set new cursor position. check if suggestion is longer or smaller than misspelled word input_pos = weechat.buffer_get_integer(buffer,'input_pos') + 1 length_misspelled_word = len(misspelled_word) length_suggestion_word = len(aspell_suggestion_list[position]) if length_misspelled_word < length_suggestion_word: difference = length_suggestion_word - length_misspelled_word new_position = input_pos + difference + 1 weechat.buffer_set(buffer,'input_pos',str(new_position)) weechat.buffer_set(buffer, 'localvar_del_spell_correction_suggest_item', '') weechat.bar_item_update('spell_suggestion') weechat.bar_item_update('spell_correction')
def replace_misspelled_word(buffer): input_line = weechat.buffer_get_string(buffer, "localvar_spell_correction_suggest_input_line") if not input_line: # remove spell_correction item weechat.buffer_set(buffer, "localvar_del_spell_correction_suggest_item", "") weechat.bar_item_update("spell_correction") return if OPTIONS["eat_input_char"].lower() == "off" or input_line == "": input_pos = weechat.buffer_get_integer(buffer, "input_pos") # check cursor position if len(input_line) < int(input_pos) or input_line[int(input_pos) - 1] == " " or input_line == "": input_line = weechat.buffer_get_string(buffer, "input") weechat.buffer_set(buffer, "localvar_del_spell_correction_suggest_input_line", "") localvar_aspell_suggest = get_localvar_aspell_suggest(buffer) # localvar_aspell_suggest = word,word2/wort,wort2 if localvar_aspell_suggest: misspelled_word, aspell_suggestions = localvar_aspell_suggest.split(":") aspell_suggestions = aspell_suggestions.replace("/", ",") aspell_suggestion_list = aspell_suggestions.split(",") else: return tab_complete, position, aspell_suggest_item = get_position_and_suggest_item(buffer) if not position or not aspell_suggest_item: return position = int(position) input_line = input_line.replace(misspelled_word, aspell_suggestion_list[position]) if input_line[-2:] == " ": input_line = input_line.rstrip() input_line = input_line + " " weechat.buffer_set(buffer, "input", input_line) weechat.bar_item_update("spell_correction") # set new cursor position. check if suggestion is longer or smaller than misspelled word input_pos = weechat.buffer_get_integer(buffer, "input_pos") + 1 length_misspelled_word = len(misspelled_word) length_suggestion_word = len(aspell_suggestion_list[position]) if length_misspelled_word < length_suggestion_word: difference = length_suggestion_word - length_misspelled_word new_position = input_pos + difference + 1 weechat.buffer_set(buffer, "input_pos", str(new_position)) weechat.buffer_set(buffer, "localvar_del_spell_correction_suggest_item", "")
def minesweeper_timer_cb(data, remaining_calls): """Callback for timer.""" global minesweeper if minesweeper['buffer'] and weechat.buffer_get_integer(minesweeper['buffer'], 'num_displayed') > 0: minesweeper['time'] += 1 minesweeper_display_status() return weechat.WEECHAT_RC_OK
def complete_cb(data, bufferptr, command): """ Apply transformation to input line in specified buffer """ if command != "/input complete_next": return weechat.WEECHAT_RC_OK line = decode(weechat.buffer_get_string(bufferptr, 'input')) caret_pos = weechat.buffer_get_integer(bufferptr, 'input_pos') match = re.search('(:\w+$)', line[:caret_pos]) if not match: return weechat.WEECHAT_RC_OK # tw = tabbed word tw = match.group(0) tw_length = len(tw) tw_start = caret_pos - tw_length tw_end = caret_pos completion = "" for key, value in EMOJIS.iteritems(): if key.startswith(tw): completion = decode(value) break if completion: line = line[:tw_start] + completion + line[tw_end:] new_caret_pos = caret_pos - tw_length + len(completion) weechat.buffer_set(bufferptr, 'input', encode(line)) weechat.buffer_set(bufferptr, 'input_pos', str(new_caret_pos)) return weechat.WEECHAT_RC_OK
def hotlist_item_cb(data, item, window): priorities = {} titles = {} hdata_hotlist = w.hdata_get('hotlist') ptr_hotlist = w.hdata_get_list(hdata_hotlist, 'gui_hotlist') while ptr_hotlist: priority = w.hdata_integer(hdata_hotlist, ptr_hotlist, 'priority') buffer = w.hdata_pointer(hdata_hotlist, ptr_hotlist, 'buffer') count = w.hdata_integer( hdata_hotlist, ptr_hotlist, '%d|count' % GUI_HOTLIST_MESSAGE) number = w.buffer_get_integer(buffer, 'number') name = w.buffer_get_string(buffer, 'short_name') if priority != GUI_HOTLIST_LOW: priorities[number] = priority titles[number] = '%d:%s' % (number, name) if count: titles[number] += '(%d)' % count ptr_hotlist = w.hdata_move(hdata_hotlist, ptr_hotlist, 1) items = [] for number, priority in sorted(priorities.items()): items.append('%s %s %s' % ( w.color(COLORS[priority]), titles[number], w.color('reset'))) return ' '.join(items)
def at_completion(data, buffer, command): if not config['enable']: return weechat.WEECHAT_RC_OK input = weechat.buffer_get_string(buffer, 'input') if input[0] != '/': buffer_name = weechat.buffer_get_string(buffer,'name') plugin_name = weechat.buffer_get_string(buffer,'plugin') # don't nick complete in core if plugin_name == 'core': return weechat.WEECHAT_RC_OK server_name = buffer_name.split('.')[0] if (server_name not in config['servers'] or not check_buffers(buffer_name) ): return weechat.WEECHAT_RC_OK pos = weechat.buffer_get_integer(buffer, 'input_pos') if pos > 0 and (pos == len(input) or input[pos] == ' '): n = input.rfind(' ', 0, pos) e = input.find(' ',n) at = 0 word = input[n+1:pos] if e != n : word = word[:e] if word[0] == '@': word = word[1:] at = 1 nicklist = weechat.infolist_get('nicklist', buffer, '') if nicklist: nick = walk_nicklist(nicklist,word) if nick != "": complete = '%s@%s %s' %(input[:pos-len(word)-at],nick,input[pos:]) weechat.buffer_set(buffer, 'input', complete) weechat.buffer_set(buffer, 'input_pos', str(pos - len(word) + len(nick)+2)) return weechat.WEECHAT_RC_OK_EAT return weechat.WEECHAT_RC_OK
def switch_current_buffer(): """Save current buffer and ensure that it's visible, then if the buffer is elegible to be hidden, we add it to the list of the buffers to be hidden after a delay """ global CURRENT_BUFFER global CURRENT_BUFFER_TIMER_HOOK previous_buffer = CURRENT_BUFFER CURRENT_BUFFER = weechat.current_buffer() if previous_buffer == CURRENT_BUFFER: return if weechat.buffer_get_integer(CURRENT_BUFFER, "hidden") == 1: weechat.buffer_set(CURRENT_BUFFER, "hidden", "0") if weechat.config_get_plugin("keep_open") != "off": if CURRENT_BUFFER_TIMER_HOOK is not None: weechat.unhook(CURRENT_BUFFER_TIMER_HOOK) CURRENT_BUFFER_TIMER_HOOK = None maybe_hide_buffer(previous_buffer) else: keep_alive_buffer(previous_buffer) CURRENT_BUFFER_TIMER_HOOK = weechat.hook_timer(MINIMUM_BUFFER_LIFE, 0, 1, "on_current_buffer_is_still_active_timeout", "") else: maybe_hide_buffer(previous_buffer)
def cb_process_message(data, wbuffer, date, tags, displayed, highlight, prefix, message): """Delegates incoming messages to appropriate handlers.""" tags = set(tags.split(",")) functions = globals() is_public_message = tags.issuperset(TAGGED_MESSAGES["public message or action"]) buffer_name = weechat.buffer_get_string(wbuffer, "name") display_count = weechat.buffer_get_integer(wbuffer, "num_displayed") dcc_buffer_regex = re.compile(r"^irc_dcc\.", re.UNICODE) dcc_buffer_match = dcc_buffer_regex.match(buffer_name) highlighted = False if highlight == "1": highlighted = True # Is this buffer currently displayed, with the 'ignore_active_window' setting on and the user not away? if display_count > 0 and weechat.config_get_plugin("ignore_active_window") == "on" and STATE["is_away"] == False: return weechat.WEECHAT_RC_OK # Private DCC message identifies itself as public. if is_public_message and dcc_buffer_match: notify_private_message_or_action(prefix, message, highlighted, buffer_name) return weechat.WEECHAT_RC_OK # Pass identified, untagged message to its designated function. for key, value in UNTAGGED_MESSAGES.items(): match = value.match(message) if match: functions[DISPATCH_TABLE[key]](match) return weechat.WEECHAT_RC_OK # Pass identified, tagged message to its designated function. for key, value in TAGGED_MESSAGES.items(): if tags.issuperset(value): functions[DISPATCH_TABLE[key]](prefix, message, highlighted, buffer_name) return weechat.WEECHAT_RC_OK return weechat.WEECHAT_RC_OK
def force_redraw(data, modifier, modifier_data, string): plugin, buffer_name = re.match('([^;]+);([^;]+)', modifier_data).group(1, 2) if weechat.buffer_get_integer(weechat.buffer_search(plugin, buffer_name), 'num_displayed') > 0: weechat.command(weechat.current_buffer(), '/window refresh') return string
def translate_process_cb(data, command, rc, stdout, stderr): """Callback reading HTML data from website.""" global translate if stdout != '': translate['stdout'] += stdout if int(rc) >= 0: translated = translate['stdout'].split('"')[1] translate['input_before'][0] = weechat.buffer_get_string(weechat.current_buffer(), 'input') translate['input_before'][1] = weechat.buffer_get_integer(weechat.current_buffer(), 'input_pos') if translate['options']['word']: # translate last word of input str_input = translate['input_before'][0] if str_input: pos = str_input.rfind(' ') if pos < 0: str_input = translated else: str_input = '%s %s' % (str_input[0:pos], translated) else: str_input = translated translate['input_after'][0] = str_input else: if translate['options']['before_marker']: translated = '%s%s' % (translate['options']['before_marker'], translated) translate['input_after'][0] = translated # set input with translation translate['input_after'][1] = len(translate['input_after'][0]) weechat.buffer_set(weechat.current_buffer(), 'input', translate['input_after'][0]) weechat.buffer_set(weechat.current_buffer(), 'input_pos', '%d' % translate['input_after'][1]) translate['hook_process'] = '' elif int(rc) == WEECHAT_HOOK_PROCESS_ERROR: translate['hook_process'] = '' return weechat.WEECHAT_RC_OK
def hexip_completion(data, buffer, command): input = weechat.buffer_get_string(buffer, 'input') # cmd = input.partition(' ')[0].strip('/') # if cmd not in weechat.config_get_plugin('commands_cmpl'): # # don't complete then # return WEECHAT_RC_OK pos = weechat.buffer_get_integer(buffer, 'input_pos') #debug('%r %s %s' %(input, len(input), pos)) if pos >= 8 and (pos == len(input) or input[pos] == ' '): n = input.rfind(' ', 0, pos) word = input[n+1:pos] #debug(word) if not word: return WEECHAT_RC_OK replace = '' if is_hexip(word): replace = hex_to_ip(word) elif is_ip(word): replace = ip_to_hex(word) if replace: n = len(word) weechat.buffer_set(buffer, 'input', '%s%s%s' %(input[:pos-n], replace, input[pos:])) weechat.buffer_set(buffer, 'input_pos', str(pos - n + len(replace))) return WEECHAT_RC_OK_EAT return WEECHAT_RC_OK
def help_cb(data, buffer, args): global help_buf if help_buf is None: help_buf = weechat.buffer_new("vimode", '', '', "help_closed_cb", '') buf_num = weechat.buffer_get_integer(help_buf, "number") weechat.command('', "/buffer %s" % buf_num) weechat.prnt(help_buf, help_text) return weechat.WEECHAT_RC_OK
def is_displayed(buffer): """Returns True if buffer is in a window and the user is active. This is for not show notifications of a visible buffer while the user is doing something and wouldn't need to be notified.""" window = weechat.buffer_get_integer(buffer, 'num_displayed') if window != 0: return not inactive() return False
def urlbuf_print_cb(data, buffer, date, tags, displayed, highlight, prefix, message): """ Called when a message is printed. """ global urlbuf_buffer, urlbuf_tags # Exit immediately if the buffer does not exist if not urlbuf_buffer: return weechat.WEECHAT_RC_OK # Exit if there is not wanted tag in the message tagslist = tags.split(",") if not "notify_message" in tagslist: if weechat.config_get_plugin("display_private") == "on": if not "notify_private" in tagslist: return weechat.WEECHAT_RC_OK else: return weechat.WEECHAT_RC_OK # Exit if the message came into a buffer that is on the skip list buffer_number = str(weechat.buffer_get_integer(buffer, "number")) skips = set(weechat.config_get_plugin("skip_buffers").split(",")) if buffer_number in skips: return weechat.WEECHAT_RC_OK if weechat.config_get_plugin("display_active_buffer") == "off": if buffer_number == weechat.buffer_get_integer(weechat.current_buffer(), "number"): return weechat.WEECHAT_RC_OK # Process all URLs from the message for url in urlRe.findall(message): output = "" if weechat.config_get_plugin("skip_duplicates") == "on": if is_url_listed(urlbuf_buffer, url): continue if weechat.config_get_plugin("display_buffer_number") == "on": output += "%s%-2d " % (weechat.color("reset"), weechat.buffer_get_integer(buffer, "number")) if weechat.config_get_plugin("display_nick") == "on": output += "%s " % (prefix) # Output the formatted URL into the buffer weechat.prnt(urlbuf_buffer, output + url) return weechat.WEECHAT_RC_OK
def go_start(buffer): """ Start go on buffer """ global saved_input, saved_input_pos, old_input, buffers_pos hook_all() saved_input = weechat.buffer_get_string(buffer, "input") saved_input_pos = weechat.buffer_get_integer(buffer, "input_pos") weechat.buffer_set(buffer, "input", "") old_input = None buffers_pos = 0
def command_run_cb (data, signal, signal_data): if tc_options['warn_command'] == '': return w.WEECHAT_RC_OK global length, cursor_pos, tc_input_text current_buffer = w.current_buffer() cursor_pos = w.buffer_get_integer(current_buffer,'input_pos') + 1 if (cursor_pos -1) == 0: tc_action_cb() return w.WEECHAT_RC_OK
def go_start(buf): """Start go on buffer.""" global saved_input, saved_input_pos, old_input, buffers_pos go_hook_all() saved_input = weechat.buffer_get_string(buf, 'input') saved_input_pos = weechat.buffer_get_integer(buf, 'input_pos') weechat.buffer_set(buf, 'input', '') old_input = None buffers_pos = 0
def get_input_line(buffer, right): input_line = w.buffer_get_string(buffer, 'input') input_pos = w.buffer_get_integer(buffer, 'input_pos') if right == 1: return input_line[input_pos:] elif right == -1: #Left return input_line[:input_pos] else: return input_line
def key_w(repeat): """Simulate vi's behavior for the w key.""" buf = weechat.current_buffer() for _ in range(max([1, repeat])): input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") weechat.command('', ("/input move_next_word\n/input move_next_word\n" "/input move_previous_word")) if len(input_line[cur:].split(' ')) == 1: weechat.command('', "/input move_end_of_line")
def command_run_cb (data, signal, signal_data): if tc_options['warn_command'] == '': return w.WEECHAT_RC_OK global length, cursor_pos, tc_input_text current_buffer = w.current_buffer() start_pos = int(tc_options['start_cursor_pos_at_zero'].lower() == 'off') cursor_pos = w.buffer_get_integer(current_buffer,'input_pos') + start_pos if (cursor_pos -1) == 0: tc_action_cb() return w.WEECHAT_RC_OK
def hlpv_print_cb(data, buffer, date, tags, displayed, highlight, prefix, message): """ Called when a message is printed. """ tagslist = tags.split(",") show_all_buffers = weechat.config_get_plugin("show_all_buffers") num_displayed = weechat.buffer_get_integer(buffer, "num_displayed") if num_displayed == 0 or show_all_buffers == "on": highlight_enabled = weechat.config_get_plugin("highlight") private_enabled = weechat.config_get_plugin("private") if ((highlight == "1") and (highlight_enabled == "on")) or (("notify_private" in tagslist) and (private_enabled == "on")): hlpv_item_add(buffer, highlight, prefix, message) return weechat.WEECHAT_RC_OK
def pressed_keys_check(data, remaining_calls): """Check the pressed keys and changes modes or detects bound keys accordingly. """ global pressed_keys, mode, vi_buffer, esc_pressed # If the last pressed key was Escape, this one will be detected as an arg # as Escape acts like a modifier (pressing Esc, then pressing i is detected # as pressing meta-i). We'll emulate it being pressed again, so that the # user's input is actually processed normally. if esc_pressed is True: esc_pressed = False weechat.hook_timer(50, 0, 1, "handle_esc", pressed_keys[-1]) if mode == "INSERT": # Ctrl + Space, or Escape if pressed_keys == "@" or pressed_keys == "[": set_mode("NORMAL") if pressed_keys == "[": esc_pressed = True elif mode == "NORMAL": # We strip all numbers and check if the the combo is recognized below, # then extract the numbers, if any, and pass them as the repeat factor. buffer_stripped = re.sub(num, '', vi_buffer) if vi_buffer in ['i', 'a', 'A']: set_mode("INSERT") if vi_buffer == 'a': weechat.command('', "/input move_next_char") elif vi_buffer == 'A': weechat.command('', "/input move_end_of_line") # Pressing '0' should not be detected as a repeat count. elif vi_buffer == '0': weechat.command('', vi_keys['0']) # Quick way to detect repeats (e.g. d5w). This isn't perfect, as things # like "5d2w1" are detected as "dw" repeated 521 times, but it should # be alright as long as the user doesn't try to break it on purpose. # Maximum number of repeats performed is 10000. elif buffer_stripped in vi_keys: repeat = ''.join(re.findall(num, vi_buffer)) if len(repeat) > 0: repeat = min([int(repeat), 10000]) else: repeat = 0 if isinstance(vi_keys[buffer_stripped], str): for _ in range(1 if repeat == 0 else repeat): weechat.command('', vi_keys[re.sub(num, '', vi_buffer)]) else: buf = weechat.current_buffer() input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") vi_keys[buffer_stripped](buf, input_line, cur, repeat) else: return weechat.WEECHAT_RC_OK clear_vi_buffers() return weechat.WEECHAT_RC_OK
def input_modifier_cb(data, modifier, modifier_data, string): """Modifier that will add help on command line (for display only).""" global cmdhelp_settings line = weechat.string_remove_color(string, '') if line == '': return string command = '' arguments = '' if weechat.string_input_for_buffer(line) != '': return string items = line.split(' ', 1) if len(items) > 0: command = items[0] if len(command) < 2: return string if len(items) > 1: arguments = items[1] if command[1:].lower() in cmdhelp_settings['ignore_commands'].split(','): return string current_buffer = weechat.current_buffer() current_window = weechat.current_window() plugin = weechat.buffer_get_pointer(current_buffer, 'plugin') msg_help = (get_help_command(plugin, command[1:], arguments) or get_list_commands(plugin, command[1:], arguments)) if not msg_help: if cmdhelp_settings['display_no_help'] != 'on': return string msg_help = weechat.color(cmdhelp_settings['color_no_help']) if command: msg_help += 'No help for command %s' % command else: msg_help += 'No help' if cmdhelp_settings['right_align'] == 'on': win_width = weechat.window_get_integer(current_window, 'win_width') input_length = weechat.buffer_get_integer(current_buffer, 'input_length') help_length = len(weechat.string_remove_color(msg_help, "")) min_space = int(cmdhelp_settings['space']) padding = int(cmdhelp_settings['right_padding']) space = win_width - input_length - help_length - padding if space < min_space: space = min_space else: space = int(cmdhelp_settings['space']) color_delimiters = cmdhelp_settings['color_delimiters'] return '%s%s%s%s%s%s%s' % (string, space * ' ', weechat.color(color_delimiters), cmdhelp_settings['prefix'], msg_help, weechat.color(color_delimiters), cmdhelp_settings['suffix'])
def set_mode(arg): """Set the current mode and update the bar mode indicator.""" global mode mode = arg # If we're going to Normal mode, the cursor must move one character to the # left. if mode == "NORMAL": buf = weechat.current_buffer() input_line = weechat.buffer_get_string(buf, "input") cur = weechat.buffer_get_integer(buf, "input_pos") set_cur(buf, input_line, cur - 1, False) weechat.bar_item_update("mode_indicator")
def unfocused_bar_item (data, item, window): '''Item constructor''' # window empty? root bar! if not window: window = w.current_window() ptr_buffer = w.window_get_pointer(window, "buffer") if ptr_buffer == "" or ptr_buffer == w.current_buffer(): return "" length = w.window_get_integer(window, 'win_width') - w.buffer_get_integer(ptr_buffer, 'input_length') s = length * inputtape_char return s
def command_run_input(data, buffer, command): """ Function called when a command "/input xxxx" is run """ global buffers, buffers_pos if command == "/input search_text" or command.find("/input jump") == 0: # search text or jump to another buffer is forbidden now return weechat.WEECHAT_RC_OK_EAT elif command == "/input complete_next": # choose next buffer in list buffers_pos += 1 if buffers_pos >= len(buffers): buffers_pos = 0 weechat.hook_signal_send("input_text_changed", weechat.WEECHAT_HOOK_SIGNAL_STRING, "") return weechat.WEECHAT_RC_OK_EAT elif command == "/input complete_previous": # choose previous buffer in list buffers_pos -= 1 if buffers_pos < 0: buffers_pos = len(buffers) - 1 weechat.hook_signal_send("input_text_changed", weechat.WEECHAT_HOOK_SIGNAL_STRING, "") return weechat.WEECHAT_RC_OK_EAT elif command == "/input return": # switch to selected buffer (if any) go_end(buffer) if len(buffers) > 0: currentbuffer = buffers[buffers_pos]["number"] # check for a window opened with this buffer if buffers_match_window: windows = weechat.infolist_get("window", "", "") win = True foundwin = False while win: win = weechat.infolist_next(windows) if weechat.buffer_get_integer(weechat.infolist_pointer(windows, "buffer"), "number") == currentbuffer: foundwin = True break weechat.infolist_free(windows) if buffers_match_window and foundwin: weechat.command(buffer, "/window b" + str(buffers[buffers_pos]["number"])) else: weechat.command(buffer, "/buffer " + str(buffers[buffers_pos]["number"])) return weechat.WEECHAT_RC_OK_EAT return weechat.WEECHAT_RC_OK
def server_switch(signal_data,servername_from_current_buffer,name): global look_server SERVER = {} bufpointer = weechat.window_get_pointer(weechat.current_window(),"buffer") servername_current_buffer = servername_from_current_buffer if look_server == "merge_with_core": # merge_with_core SERVER["weechat"] = "core.weechat" # get ALL server buffers and save them infolist = weechat.infolist_get("buffer","","*server.*") # we are only interest in server-buffers while weechat.infolist_next(infolist): bufpointer = weechat.infolist_pointer(infolist,"pointer") server = weechat.infolist_string(infolist, "name") # full servername (server.<servername>) servername = weechat.infolist_string(infolist, "short_name") # get servername from server (without prefix "server") active = weechat.infolist_integer(infolist,"active") SERVER[servername] = server if (active == 1) and (servername_current_buffer != servername): # buffer active but not correct server buffer? weechat.command(bufpointer,"/input switch_active_buffer") # switch server buffer weechat.infolist_free(infolist) # do not forget to free infolist! # switch though all server and stop at server from current buffer i = 0 while i <= len(SERVER): for servername,full_name in SERVER.items(): bufpointer = weechat.buffer_search("irc","%s" % full_name) # search pointer from server buffer if bufpointer == "": # core buffer if weechat.buffer_get_integer(weechat.buffer_search_main(),'active') == 1: weechat.command(weechat.buffer_search_main(),"/input switch_active_buffer") else: # server buffer! if (servername != servername_current_buffer) and (weechat.buffer_get_integer(bufpointer,'active') == 1): weechat.command(bufpointer,"/input switch_active_buffer") elif (servername == servername_current_buffer) and (weechat.buffer_get_integer(bufpointer,'active') == 1): i = len(SERVER) break i += 1
def on_autosort_complete(data, name, buffer, completion): cmdline = weechat.buffer_get_string(buffer, "input") cursor = weechat.buffer_get_integer(buffer, "input_pos") prefix = cmdline[:cursor] words = prefix.split()[1:] # If the current word isn't finished yet, # ignore it for coming up with completion suggestions. if prefix[-1] != ' ': words = words[:-1] if len(words) == 0: add_completions(completion, ['debug', 'helpers', 'rules', 'sort']) elif words[0] == 'rules': return autosort_complete_rules(words[1:], completion) elif words[0] == 'helpers': return autosort_complete_helpers(words[1:], completion) return weechat.WEECHAT_RC_OK
def update_title(data, signal, signal_data): title = w.buffer_get_string(w.current_buffer(), 'name') num = w.buffer_get_integer(w.current_buffer(), 'number') title = w.string_remove_color(title, '') title = "[WeeChat] [" + str(num) + ":" + title + "]" hotlist = w.infolist_get('hotlist', '', '') while w.infolist_next(hotlist): number = w.infolist_integer(hotlist, 'buffer_number') thebuffer = w.infolist_pointer(hotlist, 'buffer_pointer') name = w.buffer_get_string(thebuffer, 'short_name') if not number == num: title += ' (%s:%s)' % (number, name) w.infolist_free(hotlist) w.window_set_title(title) return w.WEECHAT_RC_OK
def input_text_changed_cb(data, signal, signal_data): global multiline_input if multiline_input == '1': return weechat.WEECHAT_RC_OK buffer = signal_data if not buffer: return weechat.WEECHAT_RC_OK tab_complete, position, aspell_suggest_item = get_position_and_suggest_item( buffer) if not position or not aspell_suggest_item: cursor_pos = weechat.buffer_get_integer(buffer, 'input_pos') if get_localvar_aspell_suggest( buffer ) and cursor_pos > 0: # save cursor position of misspelled word weechat.buffer_set(buffer, 'localvar_set_current_cursor_pos', '%s' % cursor_pos) else: saved_cursor_pos = weechat.buffer_get_string( buffer, 'localvar_current_cursor_pos') if saved_cursor_pos != '': if int(cursor_pos) > int(saved_cursor_pos) + int( OPTIONS['complete_near']) + 3: # +3 to be sure! delete_localvar_replace_mode(buffer) return weechat.WEECHAT_RC_OK # 1 = cursor etc., 2 = TAB, 3 = replace_mode if tab_complete != '0': if not aspell_suggest_item: aspell_suggest_item = '' weechat.buffer_set(buffer, 'localvar_set_spell_correction_suggest_item', '%s:%s:%s' % ('0', position, aspell_suggest_item)) return weechat.WEECHAT_RC_OK if OPTIONS['auto_replace'].lower() == "on": replace_misspelled_word(buffer) return weechat.WEECHAT_RC_OK # weechat.buffer_set(buffer, 'localvar_set_spell_correction_suggest_item', '%s:%s:' % ('0','-1')) weechat.bar_item_update('spell_correction') weechat.bar_item_update('spell_suggestion') return weechat.WEECHAT_RC_OK
def complete_cb(data, bufferptr, command): """ Apply transformation to input line in specified buffer """ line = decode(weechat.buffer_get_string(bufferptr, 'input')) caret_pos = weechat.buffer_get_integer(bufferptr, 'input_pos') match = re.search(r'(:[^:\s]+:?$)', line[:caret_pos]) if not match: return weechat.WEECHAT_RC_OK # tw = tabbed word tw = match.group(0) tw_length = len(tw) tw_start = caret_pos - tw_length tw_end = caret_pos if bufferptr in COMPLETIONS and COMPLETIONS[ bufferptr] and tw == COMPLETIONS[bufferptr][0]: # cycle through completions if we'd already made a list # if there is only one completion, nothing happens if len(COMPLETIONS[bufferptr]) <= 1: return weechat.WEECHAT_RC_OK if command == "/input complete_next": completions = COMPLETIONS[bufferptr][1:] + COMPLETIONS[ bufferptr][:1] elif command == "/input complete_previous": completions = COMPLETIONS[bufferptr][-1:] + COMPLETIONS[ bufferptr][:-1] else: # start a new list of completions completions = [] for key, value in EMOJIS.iteritems(): if key.startswith(tw): completions.append(decode(key)) completions.sort() if completions: COMPLETIONS[bufferptr] = completions line = line[:tw_start] + completions[0] + line[tw_end:] new_caret_pos = caret_pos - tw_length + len(completions[0]) weechat.buffer_set(bufferptr, 'input', encode(line)) weechat.buffer_set(bufferptr, 'input_pos', str(new_caret_pos)) return weechat.WEECHAT_RC_OK_EAT
def completion_replacer(data, completion_item, buffer, completion): global replace_table pos = weechat.buffer_get_integer(buffer, 'input_pos') input = decode(weechat.buffer_get_string(buffer, 'input')) #debug('%r %s %s' %(input, len(input), pos)) if pos > 0 and (pos == len(input) or input[pos] == ' '): n = input.rfind(' ', 0, pos) word = input[n + 1:pos] #debug(repr(word)) if word in replace_table: replace = replace_table[word] if pos >= len(input.strip()): # cursor is in the end of line, append a space replace += ' ' n = len(word) input = '%s%s%s' % (input[:pos - n], replace, input[pos:]) weechat.buffer_set(buffer, 'input', encode(input)) weechat.buffer_set(buffer, 'input_pos', str(pos - n + len(replace))) return WEECHAT_RC_OK
def translate_process_cb(data, command, rc, stdout, stderr): """Callback reading HTML data from website.""" global translate if stdout != '': translate['stdout'] += stdout if int(rc) >= 0: translated = ''.join( [x['trans'] for x in json.loads(translate['stdout'])['sentences']]) if sys.version_info < (3, ): translated = translated.encode('utf-8') translate['input_before'][0] = weechat.buffer_get_string( weechat.current_buffer(), 'input') translate['input_before'][1] = weechat.buffer_get_integer( weechat.current_buffer(), 'input_pos') if translate['options']['word']: # translate last word of input str_input = translate['input_before'][0] if str_input: pos = str_input.rfind(' ') if pos < 0: str_input = translated else: str_input = '%s %s' % (str_input[0:pos], translated) else: str_input = translated translate['input_after'][0] = str_input else: if translate['options']['before_marker']: translated = '%s%s' % (translate['options']['before_marker'], translated) translate['input_after'][0] = translated # set input with translation translate['input_after'][1] = len(translate['input_after'][0]) weechat.buffer_set(weechat.current_buffer(), 'input', translate['input_after'][0]) weechat.buffer_set(weechat.current_buffer(), 'input_pos', '%d' % translate['input_after'][1]) translate['hook_process'] = '' elif int(rc) == WEECHAT_HOOK_PROCESS_ERROR: translate['hook_process'] = '' return weechat.WEECHAT_RC_OK
def cb_process_message( data, wbuffer, date, tags, displayed, highlight, prefix, message ): '''Delegates incoming messages to appropriate handlers.''' tags = set(tags.split(',')) functions = globals() is_public_message = tags.issuperset( TAGGED_MESSAGES['public message or action']) buffer_name = weechat.buffer_get_string(wbuffer, 'name') display_count = weechat.buffer_get_integer(wbuffer, 'num_displayed') dcc_buffer_regex = re.compile(r'^irc_dcc\.', re.UNICODE) dcc_buffer_match = dcc_buffer_regex.match(buffer_name) highlighted = False if highlight == "1": highlighted = True # Is this buffer currently displayed, with the 'ignore_active_window' setting on and the user not away? if display_count > 0 and weechat.config_get_plugin('ignore_active_window') == 'on' and STATE['is_away'] == False: return weechat.WEECHAT_RC_OK # Private DCC message identifies itself as public. if is_public_message and dcc_buffer_match: notify_private_message_or_action(prefix, message, highlighted, buffer_name) return weechat.WEECHAT_RC_OK # Pass identified, untagged message to its designated function. for key, value in UNTAGGED_MESSAGES.items(): match = value.match(message) if match: functions[DISPATCH_TABLE[key]](match) return weechat.WEECHAT_RC_OK # Pass identified, tagged message to its designated function. for key, value in TAGGED_MESSAGES.items(): if tags.issuperset(value): functions[DISPATCH_TABLE[key]](prefix, message, highlighted, buffer_name) return weechat.WEECHAT_RC_OK return weechat.WEECHAT_RC_OK
def collapse_cb(data, modifier, modifier_string, string): line = string caret_pos = weechat.buffer_get_integer(data, 'input_pos') matches = list(re.finditer(r'(:[^:\s]+:)', line)) if not matches: return line shrink = 0 for match in matches: name = match.group(0) if name not in EMOJIS: continue name_length = len(name) name_start = match.start() - shrink name_end = match.end() - shrink emoji = EMOJIS[name] shrink += name_end - name_start + len(emoji) line = line[:name_start] + emoji + line[name_end:] return line
def buffer_is_hidable(buffer): """Check if passed buffer can be hidden. If configuration option ``hide_private`` is enabled, private buffers will become hidden as well. If the previous buffer name matches any of the exemptions defined in ``exemptions``, it will not become hidden. :param buffer: Buffer string representation """ if buffer == weechat.current_buffer(): return False if buffer in KEEP_ALIVE_BUFFERS.keys(): return False full_name = weechat.buffer_get_string(buffer, "full_name") if full_name.startswith("irc.server"): return False buffer_type = weechat.buffer_get_string(buffer, 'localvar_type') if (buffer_type == "private" and weechat.config_get_plugin("hide_private") == "off"): return False if weechat.config_get_plugin("hide_inactive") == "off": nicks_count = weechat.buffer_get_integer(buffer, 'nicklist_nicks_count') if nicks_count == 0: return False for entry in list_exemptions(): if entry in full_name: return False return True
def key_dw(repeat, key="dw"): """Simulate vi's behavior for dw or de.""" buf = weechat.current_buffer() input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") input_line = list(input_line) for i in range(max([1, repeat])): done = False found_letter = False delete_word = True one_timer = False while done is False: if cur >= len(input_line): done = True elif input_line[cur] != ' ' and delete_word is True: found_letter = True del input_line[cur] elif input_line[cur] == ' ' and found_letter is False: if key == "dw": delete_word = False del input_line[cur] elif input_line[cur] == ' ' and found_letter is True: delete_word = False if key == "dw" or (one_timer is False and cur < len(input_line) and input_line[cur + 1] == ' ' and i < max([1, repeat]) - 1): one_timer = True del input_line[cur] else: if i == max([1, repeat]) - 1: cur += 1 else: del input_line[cur] else: done = True input_line = ''.join(input_line) weechat.buffer_set(buf, "input", input_line)
def replace_cb(replacer_obj, data, completion_item, weechat_buffer, completion): """replace keyword with value from replacement table, if found""" position = weechat.buffer_get_integer(weechat_buffer, 'input_pos') input_line = weechat.buffer_get_string(weechat_buffer, 'input') input_line = _decode(input_line) if len(input_line) == 0: return weechat.WEECHAT_RC_OK if input_line[position - 1] == ' ': return weechat.WEECHAT_RC_OK if position > 0: left_space_index = input_line.rfind(' ', 0, position - 1) if left_space_index == -1: left_space_index = 0 word = input_line[left_space_index:position].strip() if word in replacer_obj.replacement_map: replacement = replacer_obj.replacement_map[word] if position >= len(input_line.strip()): replacement += ' ' new_line = u'' if left_space_index: new_line += input_line[:left_space_index] + u' ' new_line += replacement new_position = len(new_line) new_line += input_line[position:] weechat.buffer_set(weechat_buffer, 'input', _encode(new_line)) weechat.buffer_set(weechat_buffer, 'input_pos', str(new_position)) return weechat.WEECHAT_RC_OK
def input_rem_char(data, remaining_calls): """Remove one character from the input buffer. If data is set to 'cursor', the character at the cursor will be removed. Otherwise, data must be an integer and the character at that position will be removed instead. """ buf = weechat.current_buffer() input_line = weechat.buffer_get_string(buf, 'input') if data == "cursor": data = weechat.buffer_get_integer(buf, "input_pos") input_line = list(input_line) try: del input_line[int(data - 1)] # Not sure why nothing is being detected in some cases from the first time except IndexError: weechat.hook_timer(1, 0, 1, "input_rem_char", "cursor") return weechat.WEECHAT_RC_OK input_line = ''.join(input_line) weechat.buffer_set(buf, "input", input_line) # move the cursor back to its position before removing our character weechat.command('', "/input move_previous_char") return weechat.WEECHAT_RC_OK
def completion(data, completion_item, buffer, completion): if state.used == True: return w.WEECHAT_RC_OK else: state.used = True # Current cursor position pos = w.buffer_get_integer(buffer, 'input_pos') # Current input string input = w.buffer_get_string(buffer, 'input') fst = input.find("s/") snd = input.find("/", fst + 2) # Check for typo or suggestion completion if pos > 2 and fst >= 0 and fst < pos: if snd >= 0 and snd < pos: complete_replacement(pos, input, buffer) else: complete_typo(pos, input, buffer) state.used = False return w.WEECHAT_RC_OK
def pressed_keys_check(data, remaining_calls): """Check the pressed keys and changes modes or detects bound keys accordingly. """ global pressed_keys, mode, vi_buffer, esc_pressed # If the last pressed key was Escape, this one will be detected as an arg # as Escape acts like a modifier (pressing Esc, then pressing i is detected # as pressing meta-i). We'll emulate it being pressed again, so that the # user's input is actually processed normally. if esc_pressed is True: esc_pressed = False weechat.hook_timer(50, 0, 1, "handle_esc", pressed_keys[-1]) if mode == "INSERT": # Ctrl + Space, or Escape if pressed_keys == "@" or pressed_keys == "[": set_mode("NORMAL") if pressed_keys == "[": esc_pressed = True elif mode == "NORMAL": # We strip all numbers and check if the the combo is recognized below, # then extract the numbers, if any, and pass them as the repeat factor. buffer_stripped = re.sub(num, '', vi_buffer) if vi_buffer in ['i', 'a', 'A']: set_mode("INSERT") if vi_buffer == 'a': weechat.command('', "/input move_next_char") elif vi_buffer == 'A': weechat.command('', "/input move_end_of_line") # Pressing only '0' should not be detected as a repeat count. elif vi_buffer == '0': weechat.command('', vi_keys['0']) # Quick way to detect repeats (e.g. d5w). This isn't perfect, as things # like "5d2w1" are detected as "dw" repeated 521 times, but it should # be alright as long as the user doesn't try to break it on purpose. # Maximum number of repeats performed is 10000. elif len(buffer_stripped) > 0: repeat = ''.join(re.findall(num, vi_buffer)) if len(repeat) > 0: repeat = min([int(repeat), 10000]) else: repeat = 0 buf = weechat.current_buffer() input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") # First, the key combo is checked against the vi_keys dict which can # contain WeeChat commands (as strings) or Python functions. if buffer_stripped in vi_keys: if isinstance(vi_keys[buffer_stripped], str): for _ in range(1 if repeat == 0 else repeat): weechat.command('', vi_keys[re.sub(num, '', vi_buffer)]) else: vi_keys[buffer_stripped](buf, input_line, cur, repeat) # We then check if the pressed key is a motion (e.g. 'w') # If it is, we call the function "motion_X" where X is the motion, # then set the cursor's position to what the function returned. elif buffer_stripped[0] in vi_motions: for _ in range(1 if repeat == 0 else repeat): input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") if buffer_stripped[0] in special_chars: func = "motion_%s" % special_chars[buffer_stripped[0]] else: func = "motion_%s" % buffer_stripped[0] end, _ = globals()[func](input_line, cur) set_cur(buf, end) # And finally, if it's an operator + motion (e.g. 'dw') # If it is, we call the function "motion_X" where X is the motion, # then we call the function "operator_Y" where Y is the operator, # with the position "motion_X" returned. The "operator_Y" then # handles changing the input line. elif (len(buffer_stripped) > 1 and buffer_stripped[0] in vi_operators and buffer_stripped[1] in vi_motions): for _ in range(1 if repeat == 0 else repeat): input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") if buffer_stripped[1] in special_chars: func = "motion_%s" % special_chars[buffer_stripped[1]] else: func = "motion_%s" % buffer_stripped[1] pos, overwrite = globals()[func](input_line, cur) oper = "operator_%s" % buffer_stripped[0] globals()[oper](buf, input_line, cur, pos, overwrite) else: return weechat.WEECHAT_RC_OK else: return weechat.WEECHAT_RC_OK clear_vi_buffers() return weechat.WEECHAT_RC_OK
def get_last_position_of_misspelled_word(misspelled_word, buffer): input_pos = weechat.buffer_get_integer(buffer, 'input_pos') input_line = weechat.buffer_get_string(buffer, 'input') x = input_line.rfind(misspelled_word, 0, int(input_pos)) y = x + len(misspelled_word) return x, y, input_pos
def cb_key_combo_default(data, signal, signal_data): """Eat and handle key events when in Normal mode, if needed. The key_combo_default signal is sent when a key combo is pressed. For example, alt-k will send the "\x01[k" signal. Esc is handled a bit differently to avoid delays, see `cb_key_pressed()`. """ global esc_pressed, vi_buffer, cmd_text # If Esc was pressed, strip the Esc part from the pressed keys. # Example: user presses Esc followed by i. This is detected as "\x01[i", # but we only want to handle "i". keys = signal_data if esc_pressed or esc_pressed == -2: if keys.startswith("\x01[" * esc_pressed): # Multiples of 3 seem to "cancel" themselves, # e.g. Esc-Esc-Esc-Alt-j-11 is detected as "\x01[\x01[\x01" # followed by "\x01[j11" (two different signals). if signal_data == "\x01[" * 3: esc_pressed = -1 # `cb_check_esc()` will increment it to 0. else: esc_pressed = 0 # This can happen if a valid combination is started but interrupted # with Esc, such as Ctrl-W→Esc→w which would send two signals: # "\x01W\x01[" then "\x01W\x01[w". # In that case, we still need to handle the next signal ("\x01W\x01[w") # so we use the special value "-2". else: esc_pressed = -2 keys = keys.split('\x01[')[-1] # Remove the "Esc" part(s). # Ctrl-Space. elif keys == "\x01@": set_mode("NORMAL") return weechat.WEECHAT_RC_OK_EAT # Nothing to do here. if mode == "INSERT": return weechat.WEECHAT_RC_OK # We're in Replace mode — allow 'normal' key presses (e.g. 'a') and # overwrite the next character with them, but let the other key presses # pass normally (e.g. backspace, arrow keys, etc). if mode == "REPLACE": if len(keys) == 1: weechat.command('', "/input delete_next_char") elif keys == "\x01?": weechat.command('', "/input move_previous_char") return weechat.WEECHAT_RC_OK_EAT return weechat.WEECHAT_RC_OK # We're catching keys! Only 'normal' key presses interest us (e.g. 'a'), # not complex ones (e.g. backspace). if len(keys) == 1 and catching_keys_data['amount']: catching_keys_data['keys'] += keys catching_keys_data['amount'] -= 1 # Done catching keys, execute the callback. if catching_keys_data['amount'] == 0: globals()[catching_keys_data['callback']]() vi_buffer = '' weechat.bar_item_update("vi_buffer") return weechat.WEECHAT_RC_OK_EAT # We're in command-line mode. if cmd_text: # Backspace key. if keys == "\x01?": # Remove the last character from our command line. cmd_text = list(cmd_text) del cmd_text[-1] cmd_text = ''.join(cmd_text) # Return key. elif keys == "\x01M": weechat.hook_timer(1, 0, 1, "cb_exec_cmd", cmd_text) cmd_text = '' # Input. elif len(keys) == 1: cmd_text += keys # Update (and maybe hide) the bar item. weechat.bar_item_update("cmd_text") if not cmd_text: weechat.command('', "/bar hide vi_cmd") return weechat.WEECHAT_RC_OK_EAT # Enter command mode. elif keys == ':': cmd_text += ':' weechat.command('', "/bar show vi_cmd") weechat.bar_item_update("cmd_text") return weechat.WEECHAT_RC_OK_EAT # Add key to the buffer. vi_buffer += keys weechat.bar_item_update("vi_buffer") if not vi_buffer: return weechat.WEECHAT_RC_OK # Check if the keys have a (partial or full) match. If so, also get the # keys without the count. (These are the actual keys we should handle.) # After that, `vi_buffer` is only used for display purposes — only # `vi_keys` is checked for all the handling. # If no matches are found, the keys buffer is cleared. matched, vi_keys, count = get_keys_and_count(vi_buffer) if not matched: vi_buffer = '' return weechat.WEECHAT_RC_OK_EAT buf = weechat.current_buffer() input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") # It's a key. If the corresponding value is a string, we assume it's a # WeeChat command. Otherwise, it's a method we'll call. if vi_keys in VI_KEYS: if isinstance(VI_KEYS[vi_keys], str): for _ in range(max(count, 1)): # This is to avoid crashing WeeChat on script reloads/unloads, # because no hooks must still be running when a script is # reloaded or unloaded. if VI_KEYS[vi_keys] == "/input return": return weechat.WEECHAT_RC_OK weechat.command('', VI_KEYS[vi_keys]) current_cur = weechat.buffer_get_integer(buf, "input_pos") set_cur(buf, input_line, current_cur) else: VI_KEYS[vi_keys](buf, input_line, cur, count) # It's a motion (e.g. 'w') — call `motion_X()` where X is the motion, then # set the cursor's position to what that function returned. elif vi_keys in VI_MOTIONS: if vi_keys in SPECIAL_CHARS: func = "motion_%s" % SPECIAL_CHARS[vi_keys] else: func = "motion_%s" % vi_keys end, _ = globals()[func](input_line, cur, count) set_cur(buf, input_line, end) # It's an operator + motion (e.g. 'dw') — call `motion_X()` (where X is # the motion), then we call `operator_Y()` (where Y is the operator) # with the position `motion_X()` returned. `operator_Y()` should then # handle changing the input line. elif (len(vi_keys) > 1 and vi_keys[0] in VI_OPERATORS and vi_keys[1:] in VI_MOTIONS): if vi_keys[1:] in SPECIAL_CHARS: func = "motion_%s" % SPECIAL_CHARS[vi_keys[1:]] else: func = "motion_%s" % vi_keys[1:] pos, overwrite = globals()[func](input_line, cur, count) oper = "operator_%s" % vi_keys[0] globals()[oper](buf, input_line, cur, pos, overwrite) # The combo isn't completed yet (e.g. just 'd'). else: return weechat.WEECHAT_RC_OK_EAT # We've already handled the key combo, so clear the keys buffer. if not catching_keys_data['amount']: vi_buffer = '' weechat.bar_item_update("vi_buffer") return weechat.WEECHAT_RC_OK_EAT
def tc_bar_item (data, item, window): '''Item constructor''' # window empty? root bar! if not window: window = w.current_window() global length, cursor_pos, tc_input_text, count_over,tc_options count_over = '0' sms = '' tweet = '' reverse_chars = 0 ptr_buffer = w.window_get_pointer(window,"buffer") if ptr_buffer == "": return "" length = w.buffer_get_integer(ptr_buffer,'input_length') start_pos = int(tc_options['start_cursor_pos_at_zero'].lower() == 'off') cursor_pos = w.buffer_get_integer(ptr_buffer,'input_pos') + start_pos plugin = w.buffer_get_string(ptr_buffer, 'plugin') host = '' if plugin == 'irc': servername = w.buffer_get_string(ptr_buffer, 'localvar_server') channelname = w.buffer_get_string(ptr_buffer, 'localvar_channel') channel_type = w.buffer_get_string(ptr_buffer, 'localvar_type') name = w.buffer_get_string(ptr_buffer, 'localvar_name') input_line = w.buffer_get_string(ptr_buffer, 'input') mynick = w.info_get('irc_nick', servername) nick_ptr = w.nicklist_search_nick(ptr_buffer, '', mynick) # check for a sms message if channel_type == 'private' and name in tc_options['sms_buffer'].split(","): # 160 chars for a sms # 'sms:name:text' get_sms_text = re.match(r'(s|sms):(.*?:)(.*)', input_line) if get_sms_text: # if get_sms_text.group(2): sms_len = len(get_sms_text.group(3)) # input_length = len(input_line) # sms_prefix = input_length - sms_len sms = 160-sms_len reverse_chars = sms else: get_sms_text = re.match(r'(r|reply):(.*)', input_line) if get_sms_text: sms_len = len(get_sms_text.group(2)) sms = 160-sms_len reverse_chars = sms # check for a tweet buffer elif name in tc_options['tweet_buffer'].split(","): # 140 chars for a tweet! prefix "post " = 5 chars # check out if length >= 5 and matches "post " if length >= 5 and re.match(r'post (.*)', input_line): tweet = 145 - length reverse_chars = tweet # get host and length from host elif servername != channelname: infolist = w.infolist_get('irc_nick', '', '%s,%s,%s' % (servername,channelname,mynick)) # w.prnt("","%s.%s.%s.%s" % (servername,channelname,mynick,nick_ptr)) while w.infolist_next(infolist): host = w.infolist_string(infolist, 'host') w.infolist_free(infolist) if host != '': host = ':%s!%s PRIVMSG %s :' % (mynick,host,channelname) host_length = len(host) # w.prnt("","%d" % host_length) reverse_chars = (475 - int(host_length) - length -1) # -1 = return else: reverse_chars = (int(tc_options['max_chars']) - length) else: reverse_chars = (int(tc_options['max_chars']) - length) else: # reverse check for max_chars reverse_chars = (int(tc_options['max_chars']) - length) if reverse_chars == 0: reverse_chars = "%s" % ("0") else: if reverse_chars < 0: count_over = "%s%s%s" % (w.color(tc_options['warn_colour']),str(reverse_chars*-1), w.color('default')) reverse_chars = "%s" % ("0") tc_action_cb() else: reverse_chars = str(reverse_chars) out_format = tc_options['format'] if tc_options['warn']: if length >= int(tc_options['warn']): length_warn = "%s%s%s" % (w.color(tc_options['warn_colour']), str(length), w.color('default')) out_format = out_format.replace('%L', length_warn) else: out_format = out_format.replace('%L', str(length)) else: out_format = out_format.replace('%L', str(length)) out_format = out_format.replace('%P', str(cursor_pos)) if sms: out_format = out_format.replace('%R', "s:" + reverse_chars) elif tweet: out_format = out_format.replace('%R', "t:" + reverse_chars) else: out_format = out_format.replace('%R', reverse_chars) out_format = out_format.replace('%C', count_over) # out_format = out_format.replace('%T', str(tweet)) # out_format = out_format.replace('%S', str(sms)) tc_input_text = out_format return substitute_colors(tc_input_text)
def get_current_buffer_number(): ptr_buffer = weechat.window_get_pointer(weechat.current_window(), 'buffer') return weechat.buffer_get_integer(ptr_buffer, 'number')
def cb_key_combo_default(data, signal, signal_data): """Eat and handle key events when in Normal mode, if needed. The key_combo_default signal is sent when a key combo is pressed. For example, alt-k will send the "\x01[k" signal. Esc is handled a bit differently to avoid delays, see `cb_key_pressed()`. """ global esc_pressed, vi_buffer, cmd_text # If Esc was pressed, strip the Esc part from the pressed keys. # Example: user presses Esc followed by i. This is detected as "\x01[i", # but we only want to handle "i". keys = signal_data if esc_pressed and keys.startswith("\x01[" * esc_pressed): keys = keys[2 * esc_pressed:] # Multiples of 3 seem to "cancel" themselves, # e.g. Esc-Esc-Esc-Alt-j-11 is detected as "\x01[\x01[\x01" followed by # "\x01[j11" (two different signals). if signal_data == "\x01[" * 3: esc_pressed = -1 # Because cb_check_esc will increment it to 0. else: esc_pressed = 0 # Ctrl-Space. elif keys == "\x01@": set_mode("NORMAL") return weechat.WEECHAT_RC_OK_EAT # Nothing to do here. if mode == "INSERT": return weechat.WEECHAT_RC_OK # We're in Replace mode — allow 'normal' key presses (e.g. 'a') and # overwrite the next character with them, but let the other key presses # pass normally (e.g. backspace, arrow keys, etc). if mode == "REPLACE": if len(keys) == 1: weechat.command('', "/input delete_next_char") elif keys == "\x01?": weechat.command('', "/input move_previous_char") return weechat.WEECHAT_RC_OK_EAT return weechat.WEECHAT_RC_OK # We're catching keys! Only 'normal' key presses interest us (e.g. 'a'), # not complex ones (e.g. backspace). if len(keys) == 1 and catching_keys_data['amount']: catching_keys_data['keys'] += keys catching_keys_data['amount'] -= 1 # Done catching keys, execute the callback. if catching_keys_data['amount'] == 0: globals()[catching_keys_data['callback']]() vi_buffer = '' weechat.bar_item_update("vi_buffer") return weechat.WEECHAT_RC_OK_EAT # We're in command-line mode. if cmd_text: # Backspace key. if keys == "\x01?": # Remove the last character from our command line. cmd_text = list(cmd_text) del cmd_text[-1] cmd_text = ''.join(cmd_text) # Return key. elif keys == "\x01M": weechat.hook_timer(1, 0, 1, "cb_exec_cmd", cmd_text) cmd_text = '' # Input. elif len(keys) == 1: cmd_text += keys # Update (and maybe hide) the bar item. weechat.bar_item_update("cmd_text") if not cmd_text: weechat.command('', "/bar hide vi_cmd") return weechat.WEECHAT_RC_OK_EAT # Enter command mode. elif keys == ':': cmd_text += ':' weechat.command('', "/bar show vi_cmd") weechat.bar_item_update("cmd_text") return weechat.WEECHAT_RC_OK_EAT # Add key to the buffer. vi_buffer += keys weechat.bar_item_update("vi_buffer") if not vi_buffer: return weechat.WEECHAT_RC_OK # Keys without the count. These are the actual keys we should handle. # The count, if any, will be removed from vi_keys just below. # After that, vi_buffer is only used for display purposes — only vi_keys is # checked for all the handling. vi_keys = vi_buffer # Look for a potential match (e.g. 'd' might become 'dw' or 'dd' so we # accept it, but 'd9' is invalid). # If no matches are found, the keys buffer is cleared. match = False # Digits are allowed at the beginning (counts or '0'). count = 1 if vi_buffer.isdigit(): match = True elif vi_buffer and vi_buffer[0].isdigit(): count = '' for char in vi_buffer: if char.isdigit(): count += char else: break vi_keys = vi_buffer.replace(count, '', 1) count = int(count) # Check against defined keys. if not match: for key in VI_KEYS: if key.startswith(vi_keys): match = True break # Check against defined motions. if not match: for motion in VI_MOTIONS: if motion.startswith(vi_keys): match = True break # Check against defined operators + motions. if not match: for operator in VI_OPERATORS: if vi_keys.startswith(operator): for motion in VI_MOTIONS: if motion.startswith(vi_keys[1:]): match = True break # No match found — clear the keys buffer. if not match: vi_buffer = '' return weechat.WEECHAT_RC_OK_EAT buf = weechat.current_buffer() input_line = weechat.buffer_get_string(buf, 'input') cur = weechat.buffer_get_integer(buf, "input_pos") # It's a key. If the corresponding value is a string, we assume it's a # WeeChat command. Otherwise, it's a method we'll call. if vi_keys in VI_KEYS: if isinstance(VI_KEYS[vi_keys], str): for _ in range(count): # This is to avoid crashing WeeChat on script reloads/unloads, # because no hooks must still be running when a script is # reloaded or unloaded. if VI_KEYS[vi_keys] == "/input return": return weechat.WEECHAT_RC_OK weechat.command('', VI_KEYS[vi_keys]) current_cur = weechat.buffer_get_integer(buf, "input_pos") set_cur(buf, input_line, current_cur) else: VI_KEYS[vi_keys](buf, input_line, cur, count) # It's a motion (e.g. 'w') — call `motion_X()` where X is the motion, then # set the cursor's position to what that function returned. elif vi_keys in VI_MOTIONS: if vi_keys in SPECIAL_CHARS: func = "motion_%s" % SPECIAL_CHARS[vi_keys] else: func = "motion_%s" % vi_keys end, _ = globals()[func](input_line, cur, count) set_cur(buf, input_line, end) # It's an operator + motion (e.g. 'dw') — call `motion_X()` (where X is # the motion), then we call `operator_Y()` (where Y is the operator) # with the position `motion_X()` returned. `operator_Y()` should then # handle changing the input line. elif (len(vi_keys) > 1 and vi_keys[0] in VI_OPERATORS and vi_keys[1:] in VI_MOTIONS): if vi_keys[1:] in SPECIAL_CHARS: func = "motion_%s" % SPECIAL_CHARS[vi_keys[1:]] else: func = "motion_%s" % vi_keys[1:] pos, overwrite = globals()[func](input_line, cur, count) oper = "operator_%s" % vi_keys[0] globals()[oper](buf, input_line, cur, pos, overwrite) # The combo isn't completed yet (e.g. just 'd'). else: return weechat.WEECHAT_RC_OK_EAT # We've already handled the key combo, so clear the keys buffer. if not catching_keys_data['amount']: vi_buffer = '' weechat.bar_item_update("vi_buffer") return weechat.WEECHAT_RC_OK_EAT
def get_number(self): return weechat.buffer_get_integer(self.buffer, "number")
def get_notify_level(self): return weechat.buffer_get_integer(self.get_pointer(), "notify")
def receive(data, buf, date, tags, disp, hilite, prefix, message): display = False ## notification levels ## 0 none ## 1 highlight ## 2 message ## 3 all notify = weechat.buffer_get_integer(buf, "notify") tags = tags.split(',') ## generate the list of nicks we are using on our irc servers nicks = [] servers = weechat.infolist_get("irc_server", "", "") while weechat.infolist_next(servers): if weechat.infolist_integer(servers, 'is_connected') == 1: nicks.append(weechat.infolist_string(servers, 'nick')) weechat.infolist_free(servers) ## remove duplicates from nicks nicks = set(nicks) ## sometimes we don't want notifications at all ## we need to strip non-alpha chars from prefix, since ## otherwise we wont match @nickname for example if notify == 0 or filter(str.isalnum, prefix) in nicks: return ok() ## always display when notify set to all or message ## this means we lump irc_join under this notification level if notify in [2, 3]: display = True elif notify == 1 and (int(hilite) or 'notify_private' in tags): display = True if display: font = config('font') fontsize = config('fontsize') color = config('normal_fg') background = config('normal_bg') timeout = config('normal_timeout') prefix = prefix.replace('"', '\\"') message = "%s" % message.replace('"', '\\"') channel = weechat.buffer_get_string( buf, "short_name") or weechat.buffer_get_string( buf, "name").replace('"', '\\"') title = "[%s] <i>%s</i>" % (channel, prefix) if 'notify_private' in tags: title = "<i>%s</i>" % prefix color = config('private_fg') background = config('private_bg') timeout = config('private_timeout') if int(hilite): color = config('hilite_fg') background = config('hilite_bg') timeout = config('hilite_timeout') message = "<b> %s</b> %s " % (title, message) if sys.version_info >= (3, 3): message = shlex.quote(message) else: message = pipes.quote(message) args = dict\ ( message = message , font = font , fontsize = fontsize , timeout = int(timeout)*1000 , color = color , background = background , height = config('height') , position = config('position') ) cmd = 'twmnc --aot '\ + '-t "" '\ + '--pos %(position)s '\ + '-d %(timeout)s '\ + '--fg "%(color)s" '\ + '--bg "%(background)s" '\ + '--content=%(message)s '\ + '--fn "%(font)s" '\ + '-s %(height)s '\ + '--fs %(fontsize)s ' weechat.hook_process(cmd % args, 10000, "ok", "") return ok()
def buffer_key(bufs): hidden = min(weechat.buffer_get_integer(buf, "hidden") for buf in bufs) localvar_type = min( BUFFER_TYPES[weechat.buffer_get_string(buf, "localvar_type")] for buf in bufs) return (hidden, localvar_type)