rafi / .config

Rafi's workstations (Archlinux, osx) ~/.config.
94 stars 15 forks source link

i3-focus #1

Closed pbogut closed 7 years ago

pbogut commented 8 years ago

Hi mate,

Sorry for rising issue, but hove no idea how to ask you anywhere else.

I found this issue https://github.com/christoomey/vim-tmux-navigator/issues/45 You mentioned i3-focus script there and I can see it is used in your i3/config file but can't find the script itself. Are you fancy to share it somewhere?

Thanks

frdrcv commented 8 years ago

I would really appreciate to use this script too.

rafi commented 8 years ago

@pbogut @frdrcv I haven't been using it for more than a year, and it's quite a mess.

#!/usr/bin/python

import sys
import os
import i3
import subprocess
import re
import ast

cmd = str(sys.argv[1])
if len(cmd) == 1:
    if cmd == 'U': cmd = 'up'
    if cmd == 'D': cmd = 'down'
    if cmd == 'L': cmd = 'left'
    if cmd == 'R': cmd = 'right'

source = 'i3'
if len(sys.argv) == 3:
    source = str(sys.argv[2])

current = i3.filter(nodes=[], focused=True)[0]
in_tmux = re.search('tmux\{(.*)\}', current['name'])
move_i3 = True

#mylog = open("/tmp/i3-focus.log", "a")
#mylog.write(current['name'])
#mylog.write(str(source)+' ')

if in_tmux:
    tmux_session = in_tmux.group(1)
    panes = subprocess.check_output([
        'tmux',
        'list-panes',
        '-st',
        tmux_session,
        '-F',
        '[#{window_active},#{pane_active},#{pane_left},#{pane_right},#{pane_top},#{pane_bottom},#{window_width},#{window_height},"#{pane_current_command}"]'
    ])
    # Preparing output for parsing.
    # Note: In zoom mode, other windows will return empty for coordinates.
    panes = panes.decode().replace('\n', ',').replace(',,', '0')
#   mylog.write(', session: '+tmux_session+' '+panes)
    panes = ast.literal_eval(panes)

    for p in panes:
        if p[0] and p[1]:
            pane = p

    move_i3 = False
    # Check tmux borders if Vim called us
    # Or we're not in Vim

#   mylog.write(pane[8]+'%'
#           +' x:'+str(pane[2])+'-'+str(pane[3])+' y:'+str(pane[4])+'-'+str(pane[5])+' ['+str(pane[6])+'w '
#           +str(pane[7])+'h]')

    if source == 'vim' or pane[8] != 'vim':
#       mylog.write(", checking tmux coords")
#       mylog.write(", "+str(pane))
        if cmd == 'up':
            if pane[4] == 0: move_i3 = True
        if cmd == 'down':
            if pane[5] == pane[7]-1: move_i3 = True
        if cmd == 'left':
            if pane[2] == 0: move_i3 = True
        if cmd == 'right':
            if pane[3] == pane[6]-1: move_i3 = True

# ignore vimb, a vim-like gtk browser
if source != 'vim' and re.compile('g?V?im[^b]').match(current['name']):
    move_i3  =  False

if move_i3:
    i3.focus(cmd)

else:
    if in_tmux and source == 'vim':
#       mylog.write(", moving tmux")
        if cmd == 'up':
            subprocess.check_output([ 'tmux', 'select-pane', '-U' ]);
        if cmd == 'down':
            subprocess.check_output([ 'tmux', 'select-pane', '-D' ]);
        if cmd == 'left':
            subprocess.check_output([ 'tmux', 'select-pane', '-L' ]);
        if cmd == 'right':
            subprocess.check_output([ 'tmux', 'select-pane', '-R' ]);
    else:
#   from ctypes import *
#       mylog.write(", moving keyb")
#       libxdo = CDLL('libxdo.so.3')
#       xdo = libxdo.xdo_new(b':0.0')
#       wid = c_int(current['window'])
#       delay = c_int(0)
#       xdo_cmd_dict = {'left':  c_char_p(b"Ctrl+h"),
#                                       'right': c_char_p(b"Ctrl+l"),
#                                       'up':    c_char_p(b"Ctrl+k"),
#                                       'down':  c_char_p(b"Ctrl+j")}

#       libxdo.xdo_keysequence(xdo, wid, xdo_cmd_dict[cmd], delay)
#       libxdo.xdo_free(xdo)

        xdo_cmd_dict = {'left':  'Ctrl+h',
                                        'right': 'Ctrl+l',
                                        'up':    'Ctrl+k',
                                        'down':  'Ctrl+j'}
        subprocess.check_output([ 'xdotool', 'key', xdo_cmd_dict[cmd] ])

#mylog.write(", move i3: "+str(move_i3))
#mylog.write("\n\n")

#  vim: set ts=2 sw=2 tw=80 noet :

It expects a certain title string configured in tmux:

set-option -g set-titles on
set-option -g set-titles-string '#T #W tmux{#S}:#I.#P'
frdrcv commented 8 years ago

Thanks for sharing, I will try to give it a look soon.

frdrcv commented 8 years ago

It's working quite well, except that I mustn't type h,j,k or l too fast when using tmux or nothing is happening. May I upload it to a new repository with a reference to you? Or perhaps could you create one so I can fork it? I would like to work on it and make it more public. Thanks!

pbogut commented 8 years ago

@frdrcv I've created my own that I'm using, it's not pretty but here it is. It works with tmux panes and nvim windows inside or outside tmux. It's using nvr (neovim remote) when outside tmux. Session ID is taken from window title so that has to be configured in tmux.conf and/or vimrc (you can check my dotfiles).

Maybe you will find it useful.

rafi commented 8 years ago

@frdrcv sure. go ahead! It's a great way of navigating i3/tmux/vim panes and windows. It worked very well for me, don't remember those issue you mention, however Python isn't really the best tool for this.

@pbogut thanks for sharing.

rafi commented 8 years ago

I also remember nicm, tmux dev, was gracious enough to add the pane_* output variables for this idea to work and be able to detect the "edge" of tmux panes.. https://github.com/tmux/tmux/commit/7160b8c2d5d17565ef8da0fb532cb49b2d5718bb