summaryrefslogtreecommitdiff
path: root/run_vim.py
diff options
context:
space:
mode:
Diffstat (limited to 'run_vim.py')
-rwxr-xr-xrun_vim.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/run_vim.py b/run_vim.py
new file mode 100755
index 0000000..93f15e5
--- /dev/null
+++ b/run_vim.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python3
+
+import neovim, os, re, sys, time
+
+# Get a list of buffers that haven't been deleted. `nvim.buffers` includes
+# buffers that have had `:bdelete` called on them and aren't in the buffer
+# list, so we have to filter those out.
+def get_listed_buffers(nvim):
+ return set(buf.number for buf in nvim.buffers \
+ if nvim.eval('buflisted(%d)' % buf.number))
+
+
+def resolve_google3(fname):
+ if fname.startswith('//depot/google3'):
+ cwd = os.getcwd()
+ if "/google3" in cwd:
+ depot_dir = cwd[:cwd.find('/google3')]
+ realfname = fname.replace('//depot', depot_dir)
+ return realfname
+ return fname
+
+# Many terminals now support undercurl, but Neovim still looks for xterm-kitty
+# to enable it.
+if os.environ["TERM"] in ["alactritty", "xterm-256color"]:
+ os.environ["TERM"] = "xterm-kitty"
+
+# For now, treat all arguments that don't start with - or + as filenames. This
+# is good enough to recognize '-f' and `+11`, which is all this script really
+# needs right now.
+filenames = [
+ re.sub(' ', '\ ', os.path.abspath(resolve_google3(arg)))
+ for arg in sys.argv[1:] if not arg[0] in ['-', '+']
+]
+
+try:
+ nvim_socket = os.environ["NVIM"]
+except KeyError:
+ # If we aren't running inside a `:terminal`, just exec nvim.
+ os.execvp(u'nvim', list(filter(lambda a: a != "--float", sys.argv)))
+
+nvim = neovim.attach('socket', path=nvim_socket)
+
+existing_buffers = get_listed_buffers(nvim)
+
+if '--float' in sys.argv:
+ nvim.command(
+ 'call nvim_open_win(0, 1, {' +
+ "'relative': 'editor'," +
+ "'width': 90," +
+ "'height': 40," +
+ "'col': (nvim_list_uis()[0].width / 2) - (90 / 2)," +
+ "'row': (nvim_list_uis()[0].height / 2) - (40 / 2)," +
+ "'anchor': 'NW'," +
+ "'style': 'minimal'," +
+ "'border': 'single'," +
+ "'title': [['" + filenames[0] + "', 'Statement']]" +
+ "})");
+ nvim.command("set winhighlight=Normal:Normal")
+else:
+ nvim.command('split')
+
+nvim.command('args %s' % ' '.join(filenames))
+
+new_buffers = get_listed_buffers(nvim).difference(existing_buffers)
+
+for arg in sys.argv:
+ if arg[0] == '+':
+ nvim.command(arg[1:])
+
+# The '-f' flag is a signal that we're in a situation like a `git commit`
+# invocation where we need to block until the user is done with the file(s).
+if '-f' in sys.argv and len(new_buffers) > 0:
+ # The rule here is that the user is 'done' with the opened files when none
+ # of them are visible onscreen. This allows for use cases like hitting `:q`
+ # on a `git commit` tempfile. However, we can't just poll to see if they're
+ # visible, because using `nvim.windows`, `nvim.eval()`, or `nvim.call()`
+ # will interrupt any multi-key mappings the user may be inputting. The
+ # solution is to set a buffer-local autocmd on each opened buffer so that
+ # we only check for visibility immediately after the user either closes or
+ # hides one of the buffers.
+ channel_id = nvim.channel_id
+ for buffer in new_buffers:
+ nvim.command((
+ 'autocmd BufDelete,BufHidden,QuitPre <buffer=%d> ' +
+ 'call rpcnotify(%d, "check_buffers")'
+ ) % (buffer, channel_id))
+
+ stay_open = True
+ while stay_open:
+ nvim.next_message() # block until `rpcnotify` is called
+ open_buffers = [window.buffer.number for window in nvim.windows]
+ stay_open = any([buffer in open_buffers for buffer in new_buffers])
+
+ # Now that none of the opened files are visible anymore, we do a few
+ # cleanup steps before ending the script:
+ # * Clear the arg list, since otherwise `:next` would reopen the tempfile
+ # or whatever.
+ # * Clear the autocmds we added, since `bdelete` just hides the buffer and
+ # the autocmds will still be active if the user reopens the file(s).
+ # * Delete each of the buffers we created.
+ nvim.command('argdel *')
+ for buffer in new_buffers:
+ nvim.command('autocmd! BufDelete,BufHidden,QuitPre <buffer=%d>' % buffer)
+ nvim.command('bdelete! %d' % buffer)