rj1
log | files | refs

edit (3518B) - raw


#!/usr/bin/env python
import libtmux
from pynvim import attach
from i3ipc import Connection as sway
import sys
import os
import glob
import json
import time


def in_dir(path, dir):
    return os.path.realpath(path).startswith(os.path.realpath(dir) + os.sep)


def abs_filepath(filepath):
    if os.path.isabs(filepath):
        return filepath
    else:
        return os.getcwd() + "/" + filepath


server = libtmux.Server()

# default session name is "edit"
tmux_session = server.sessions.filter(session_name="edit")[0]

# check if 'edit' tmux session is open
if tmux_session is None:
    print("you don't have the edit session opened, do this first")
    quit()

# check if file parameter is passed
if len(sys.argv) != 2:
    print("missing file parameter, e.g. `edit <filename>`")
    quit()

# get list of windows in our tmux session
windows = tmux_session.windows

open_windows = []
for window in windows:
    open_windows.append(window.name)

# get list of all neovim sessions
session_dir = os.getenv("XDG_STATE_HOME") + "/nvim/session"
session_files = glob.glob(session_dir + "/*.json")

# create our list of sessions and the data we need to use them
sessions = {}
for session in session_files:
    # open json file
    with open(session) as f:
        data = json.load(f)

    # add sessions
    basename = os.path.basename(session).replace(".json", "")
    sessions[basename] = {}
    sessions[basename]["name"] = basename
    sessions[basename]["dir"] = data["cwd"]
    sessions[basename]["open"] = False

# reverse sort by string length of dir, so we can find the deepest dir that contains the file we're trying to open
# e.g. if we have sessions for ~/.config/nvim and ~/.config/nvim/plugins/some-plugin
sessions = dict(sorted(sessions.items(), key=lambda x: len(x[1]["dir"]), reverse=True))

# set open flag for sessions that are open in tmux
for session in sessions:
    if session in open_windows:
        sessions[session]["open"] = True

# absolute filepath
file = abs_filepath(sys.argv[1])

# set default session
use_session = sessions["config"]

# see if there's a non-default session available that we should use instead
for session in sessions.values():
    if in_dir(file, session["dir"]) is True:
        use_session = session
        break

if use_session["open"] is False:
    # create new tmux window
    window = tmux_session.new_window(window_name=use_session["name"])

    # open neovim in new tmux window
    pane = window.attached_pane
    pane.send_keys("nvim")
    pane.send_keys(":LoadSession " + use_session["name"])

    # wait for socket to be created
    socket = "/tmp/nvim-" + use_session["name"]
    while os.path.exists(socket) is False:
        time.sleep(0.1)

# connect to neovim socket and open file
# NOTE: this requires the creation of sockets per session in your neovim config
# e.g. au sessionloadpost * call serverstart('/tmp/nvim-' . SessionName())
socket = "/tmp/nvim-" + use_session["name"]
nvim = attach("socket", path=socket)
nvim.command("edit " + file)

# find tmux window and switch to it
find_window = tmux_session.windows.filter(window_name=use_session["name"])[0]
window = tmux_session.select_window(str(find_window).split(":")[0].split()[1])

# switch to first pane in session window (this is where i always have neovim)
pane = window.panes[0]
pane.select()

# find the edit window in sway and focus it
for window in sway().get_tree().leaves():
    if "edit: " in window.name:
        window.command("focus")
        window.workspace().command("focus")