2016-02-15 02:44:01 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2016-02-17 00:22:49 +00:00
|
|
|
"""
|
|
|
|
Copyright (c) 2015 - present Marco Hinz
|
2016-02-15 02:44:01 +00:00
|
|
|
|
2016-02-17 00:22:49 +00:00
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
"""
|
|
|
|
|
2017-08-06 23:59:59 +00:00
|
|
|
import argparse
|
|
|
|
import neovim
|
2016-02-17 00:22:49 +00:00
|
|
|
import os
|
2017-08-06 23:59:59 +00:00
|
|
|
import psutil
|
|
|
|
import re
|
2017-09-30 12:13:15 +00:00
|
|
|
import socket
|
2017-06-20 13:01:56 +00:00
|
|
|
import stat
|
2016-06-06 10:15:14 +00:00
|
|
|
import subprocess
|
2017-08-06 23:59:59 +00:00
|
|
|
import sys
|
2017-06-20 13:01:56 +00:00
|
|
|
import tempfile
|
2017-08-06 23:59:59 +00:00
|
|
|
import textwrap
|
|
|
|
import time
|
|
|
|
import traceback
|
2016-02-17 00:22:49 +00:00
|
|
|
|
|
|
|
|
2017-12-03 15:35:11 +00:00
|
|
|
class Nvr():
|
2017-07-26 22:25:13 +00:00
|
|
|
def __init__(self, address, silent=False):
|
2016-06-06 18:05:38 +00:00
|
|
|
self.address = address
|
|
|
|
self.server = None
|
2017-12-03 15:19:21 +00:00
|
|
|
self.silent = silent
|
2016-06-06 18:05:38 +00:00
|
|
|
self._msg_shown = False
|
2016-02-17 00:22:49 +00:00
|
|
|
|
2016-06-06 18:05:38 +00:00
|
|
|
def attach(self):
|
2016-02-17 00:22:49 +00:00
|
|
|
try:
|
2017-09-30 10:52:05 +00:00
|
|
|
if get_address_type(self.address) == 'tcp':
|
2017-09-29 15:20:20 +00:00
|
|
|
ip, port = self.address.split(':', 1)
|
2017-09-30 10:52:05 +00:00
|
|
|
self.server = neovim.attach('tcp', address=ip, port=int(port))
|
2016-02-17 00:22:49 +00:00
|
|
|
else:
|
2017-08-06 23:59:59 +00:00
|
|
|
self.server = neovim.attach('socket', path=self.address)
|
2017-08-02 10:10:03 +00:00
|
|
|
except OSError:
|
|
|
|
# Ignore invalid addresses.
|
2016-06-06 18:05:38 +00:00
|
|
|
pass
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
def start_new_process(self):
|
2017-09-30 10:53:57 +00:00
|
|
|
pid = os.fork()
|
|
|
|
if pid == 0:
|
|
|
|
for i in range(10):
|
|
|
|
self.attach()
|
|
|
|
if self.server:
|
|
|
|
return True
|
|
|
|
time.sleep(0.2)
|
2016-06-06 18:05:38 +00:00
|
|
|
else:
|
2017-09-30 10:53:57 +00:00
|
|
|
os.environ['NVIM_LISTEN_ADDRESS'] = self.address
|
|
|
|
try:
|
|
|
|
args = os.environ.get('NVR_CMD')
|
|
|
|
args = args.split(' ') if args else ['nvim']
|
|
|
|
os.dup2(sys.stdout.fileno(), sys.stdin.fileno())
|
|
|
|
os.execvpe(args[0], args, os.environ)
|
|
|
|
except FileNotFoundError:
|
|
|
|
print("[!] Can't start new nvim process: '{}' is not in $PATH.".format(args[0]))
|
|
|
|
sys.exit(1)
|
|
|
|
|
2016-11-28 17:04:55 +00:00
|
|
|
def read_stdin_into_buffer(self, cmd):
|
|
|
|
self.server.command(cmd)
|
|
|
|
for line in sys.stdin:
|
|
|
|
self.server.command("call append('$', '{}')".
|
|
|
|
format(line.rstrip().replace("'", "''")))
|
2016-11-28 19:12:00 +00:00
|
|
|
self.server.command('silent 1delete _ | set nomodified')
|
2016-11-28 17:04:55 +00:00
|
|
|
|
2018-03-12 15:24:13 +00:00
|
|
|
def fnameescaped_command(self, cmd, fname):
|
|
|
|
path = os.path.abspath(fname)
|
|
|
|
path = self.server.eval("fnameescape('{}')".format(path))
|
|
|
|
self.server.command('{} {}'.format(cmd, path))
|
|
|
|
|
2016-06-06 17:23:54 +00:00
|
|
|
def execute(self, arguments, cmd='edit', silent=False, wait=False):
|
2017-08-02 11:21:01 +00:00
|
|
|
cmds, files = split_cmds_from_files(arguments)
|
2016-12-02 17:06:02 +00:00
|
|
|
|
2017-08-02 11:21:01 +00:00
|
|
|
for fname in files:
|
2016-11-28 19:12:00 +00:00
|
|
|
if fname == '-':
|
|
|
|
self.read_stdin_into_buffer('enew' if cmd == 'edit' else cmd)
|
|
|
|
else:
|
2017-08-06 23:59:59 +00:00
|
|
|
try:
|
2018-03-12 15:24:13 +00:00
|
|
|
self.fnameescaped_command(cmd, fname)
|
2017-08-06 23:59:59 +00:00
|
|
|
except neovim.api.nvim.NvimError as e:
|
|
|
|
if not re.search('E37', e.args[0].decode()):
|
|
|
|
traceback.print_exc()
|
|
|
|
sys.exit(1)
|
2016-12-02 17:06:02 +00:00
|
|
|
|
2016-10-06 18:37:09 +00:00
|
|
|
if wait:
|
2016-12-02 16:44:15 +00:00
|
|
|
bvars = self.server.current.buffer.vars
|
|
|
|
chanid = self.server.channel_id
|
2016-12-02 17:06:02 +00:00
|
|
|
|
2016-07-19 14:27:17 +00:00
|
|
|
self.server.command('augroup nvr')
|
2016-12-02 16:44:15 +00:00
|
|
|
self.server.command('autocmd BufDelete <buffer> silent! call rpcnotify({}, "BufDelete")'.format(chanid))
|
|
|
|
self.server.command('autocmd VimLeave * if exists("v:exiting") && v:exiting > 0 | silent! call rpcnotify({}, "Exit", v:exiting) | endif'.format(chanid))
|
2016-07-19 14:27:17 +00:00
|
|
|
self.server.command('augroup END')
|
2016-12-02 17:06:02 +00:00
|
|
|
|
2016-12-02 16:44:15 +00:00
|
|
|
if 'nvr' in bvars:
|
|
|
|
if chanid not in bvars['nvr']:
|
|
|
|
bvars['nvr'] = [chanid] + bvars['nvr']
|
|
|
|
else:
|
|
|
|
bvars['nvr'] = [chanid]
|
2016-12-02 17:06:02 +00:00
|
|
|
|
2017-08-02 11:21:01 +00:00
|
|
|
for cmd in cmds:
|
|
|
|
self.server.command(cmd if cmd else '$')
|
2016-12-02 17:06:02 +00:00
|
|
|
|
2017-08-02 11:21:01 +00:00
|
|
|
return len(files)
|
2016-02-17 00:22:49 +00:00
|
|
|
|
2017-12-03 13:57:26 +00:00
|
|
|
|
2017-12-03 15:19:21 +00:00
|
|
|
def sanitize_address(address):
|
2017-12-03 13:57:26 +00:00
|
|
|
if get_address_type(address) == 'socket' and os.path.exists(address):
|
|
|
|
try:
|
|
|
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
|
|
sock.connect(address)
|
|
|
|
except:
|
|
|
|
with tempfile.NamedTemporaryFile(dir='/tmp', prefix='nvimsocket_') as f:
|
|
|
|
address = f.name
|
|
|
|
|
|
|
|
return address
|
|
|
|
|
|
|
|
|
2017-05-23 21:05:46 +00:00
|
|
|
def parse_args(argv):
|
2016-02-17 00:22:49 +00:00
|
|
|
form_class = argparse.RawDescriptionHelpFormatter
|
2017-05-23 21:05:46 +00:00
|
|
|
usage = '{} [arguments]'.format(argv[0])
|
2018-03-01 19:25:25 +00:00
|
|
|
epilog = 'Development: https://github.com/mhinz/neovim-remote\n\nHappy hacking!'
|
2016-02-17 00:22:49 +00:00
|
|
|
desc = textwrap.dedent("""
|
2017-06-20 18:50:55 +00:00
|
|
|
Remote control Neovim processes.
|
2016-02-17 00:22:49 +00:00
|
|
|
|
2017-06-20 19:09:21 +00:00
|
|
|
If no process is found, a new one will be started.
|
|
|
|
|
2016-06-06 10:59:15 +00:00
|
|
|
$ nvr --remote-send 'iabc<cr><esc>'
|
2016-06-06 11:07:18 +00:00
|
|
|
$ nvr --remote-expr 'map([1,2,3], \"v:val + 1\")'
|
2017-03-27 13:27:04 +00:00
|
|
|
|
2017-11-14 15:49:03 +00:00
|
|
|
Any arguments not consumed by options will be fed to --remote-silent:
|
2017-03-27 13:27:04 +00:00
|
|
|
|
2017-11-14 15:49:03 +00:00
|
|
|
$ nvr --remote-silent file1 file2
|
2017-03-27 13:27:04 +00:00
|
|
|
$ nvr file1 file2
|
2016-06-06 11:58:55 +00:00
|
|
|
|
2017-06-20 19:09:21 +00:00
|
|
|
All --remote options take optional commands.
|
|
|
|
Exception: --remote-expr, --remote-send.
|
2016-11-08 15:26:21 +00:00
|
|
|
|
|
|
|
$ nvr +10 file
|
|
|
|
$ nvr +'echomsg "foo" | echomsg "bar"' file
|
|
|
|
$ nvr --remote-tab-wait +'set bufhidden=delete' file
|
|
|
|
|
2017-06-20 19:09:21 +00:00
|
|
|
Open files in a new window from a terminal buffer:
|
2016-06-06 11:58:55 +00:00
|
|
|
|
2017-03-27 13:27:04 +00:00
|
|
|
$ nvr -cc split file1 file2
|
2016-06-06 11:58:55 +00:00
|
|
|
|
2017-06-20 19:09:21 +00:00
|
|
|
Use nvr from git to edit commit messages:
|
|
|
|
|
|
|
|
$ git config --global core.editor 'nvr --remote-wait-silent'
|
2016-02-17 00:22:49 +00:00
|
|
|
""")
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
formatter_class = form_class,
|
|
|
|
usage = usage,
|
|
|
|
epilog = epilog,
|
|
|
|
description = desc)
|
|
|
|
|
|
|
|
parser.add_argument('--remote',
|
2017-06-19 12:55:27 +00:00
|
|
|
nargs = '*',
|
2016-06-06 12:55:44 +00:00
|
|
|
metavar = '<file>',
|
2017-06-20 18:50:55 +00:00
|
|
|
help = 'Use :edit to open files. If no process is found, throw an error and start a new one.')
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--remote-wait',
|
2017-03-27 12:12:59 +00:00
|
|
|
nargs = '*',
|
2016-06-06 12:55:44 +00:00
|
|
|
metavar = '<file>',
|
2017-06-20 18:50:55 +00:00
|
|
|
help = 'Like --remote, but block until all buffers opened by this option get deleted or the process exits.')
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--remote-silent',
|
2017-06-19 12:55:27 +00:00
|
|
|
nargs = '*',
|
2016-06-06 12:55:44 +00:00
|
|
|
metavar = '<file>',
|
2017-06-20 18:50:55 +00:00
|
|
|
help = 'Like --remote, but throw no error if no process is found.')
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--remote-wait-silent',
|
2017-03-27 12:12:59 +00:00
|
|
|
nargs = '*',
|
2017-03-19 15:48:00 +00:00
|
|
|
metavar = '<file>',
|
2017-03-27 13:27:04 +00:00
|
|
|
help = 'Combines --remote-wait and --remote-silent.')
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-08-01 13:29:04 +00:00
|
|
|
parser.add_argument('--remote-tab',
|
2017-06-19 12:55:27 +00:00
|
|
|
nargs = '*',
|
2016-06-06 12:55:44 +00:00
|
|
|
metavar = '<file>',
|
2017-03-27 13:27:04 +00:00
|
|
|
help = 'Like --remote, but use :tabedit.')
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--remote-tab-wait',
|
2017-06-19 12:55:27 +00:00
|
|
|
nargs = '*',
|
2016-06-06 12:55:44 +00:00
|
|
|
metavar = '<file>',
|
2017-03-27 13:27:04 +00:00
|
|
|
help = 'Like --remote-wait, but use :tabedit.')
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--remote-tab-silent',
|
2017-06-19 12:55:27 +00:00
|
|
|
nargs = '*',
|
2016-06-06 12:55:44 +00:00
|
|
|
metavar = '<file>',
|
2017-03-27 13:27:04 +00:00
|
|
|
help = 'Like --remote-silent, but use :tabedit.')
|
2016-06-06 12:55:44 +00:00
|
|
|
parser.add_argument('--remote-tab-wait-silent',
|
2017-06-19 12:55:27 +00:00
|
|
|
nargs = '*',
|
2016-06-06 12:55:44 +00:00
|
|
|
metavar = '<file>',
|
2017-03-27 13:27:04 +00:00
|
|
|
help = 'Like --remote-wait-silent, but use :tabedit.')
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--remote-send',
|
|
|
|
metavar = '<keys>',
|
2016-06-06 10:59:15 +00:00
|
|
|
help = 'Send key presses.')
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--remote-expr',
|
|
|
|
metavar = '<expr>',
|
2017-06-20 18:50:55 +00:00
|
|
|
help = 'Evaluate expression and print result in shell.')
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--servername',
|
|
|
|
metavar = '<addr>',
|
2016-12-06 21:36:06 +00:00
|
|
|
help = 'Set the address to be used. This overrides the default "/tmp/nvimsocket" and $NVIM_LISTEN_ADDRESS.')
|
2016-02-17 00:22:49 +00:00
|
|
|
parser.add_argument('--serverlist',
|
|
|
|
action = 'store_true',
|
2017-04-27 11:22:40 +00:00
|
|
|
help = 'Print the TCPv4 and Unix domain socket addresses of all nvim processes.')
|
2016-02-17 00:22:49 +00:00
|
|
|
|
2017-02-26 16:20:48 +00:00
|
|
|
parser.add_argument('-cc',
|
|
|
|
action = 'append',
|
|
|
|
metavar = '<cmd>',
|
|
|
|
help = 'Execute a command before every other option.')
|
2016-06-06 11:58:55 +00:00
|
|
|
parser.add_argument('-c',
|
|
|
|
action = 'append',
|
|
|
|
metavar = '<cmd>',
|
2017-02-26 16:20:48 +00:00
|
|
|
help = 'Execute a command after every other option.')
|
2017-06-29 23:55:50 +00:00
|
|
|
parser.add_argument('-l',
|
|
|
|
action = 'store_true',
|
|
|
|
help = 'Change to previous window via ":wincmd p".')
|
2016-06-06 11:58:55 +00:00
|
|
|
parser.add_argument('-o',
|
|
|
|
nargs = '+',
|
|
|
|
metavar = '<file>',
|
|
|
|
help = 'Open files via ":split".')
|
|
|
|
parser.add_argument('-O',
|
|
|
|
nargs = '+',
|
|
|
|
metavar = '<file>',
|
|
|
|
help = 'Open files via ":vsplit".')
|
2017-08-01 13:29:04 +00:00
|
|
|
parser.add_argument('-p',
|
2017-11-13 17:06:31 +00:00
|
|
|
nargs = '+',
|
2017-08-01 13:29:04 +00:00
|
|
|
metavar = '<file>',
|
|
|
|
help = 'Open files via ":tabedit".')
|
2016-12-28 11:29:22 +00:00
|
|
|
parser.add_argument('-q',
|
|
|
|
metavar = '<errorfile>',
|
|
|
|
help = 'Read errorfile into quickfix list and display first error.')
|
2017-06-29 23:52:32 +00:00
|
|
|
parser.add_argument('-s',
|
|
|
|
action = 'store_true',
|
|
|
|
help = 'Silence "no server found" message.')
|
2017-06-29 23:55:50 +00:00
|
|
|
parser.add_argument('-t',
|
|
|
|
metavar = '<tag>',
|
|
|
|
help = 'Jump to file and position of given tag.')
|
2017-12-03 13:24:46 +00:00
|
|
|
parser.add_argument('--nostart',
|
|
|
|
action = 'store_true',
|
|
|
|
help = 'If no process is found, do not start a new one.')
|
2018-03-01 19:26:05 +00:00
|
|
|
parser.add_argument('--version',
|
|
|
|
action = 'store_true',
|
|
|
|
help = 'Show the nvr version.')
|
2016-12-28 11:29:22 +00:00
|
|
|
|
2017-05-23 21:05:46 +00:00
|
|
|
return parser.parse_known_args(argv[1:])
|
2016-02-17 00:22:49 +00:00
|
|
|
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 15:19:21 +00:00
|
|
|
def show_message(old_address, new_address):
|
|
|
|
print(textwrap.dedent("""
|
|
|
|
[!] Can't connect to: {}
|
|
|
|
|
|
|
|
The server (nvim) and client (nvr) have to use the same address.
|
|
|
|
|
|
|
|
Server:
|
|
|
|
|
|
|
|
Expose $NVIM_LISTEN_ADDRESS to the environment before
|
|
|
|
starting nvim:
|
|
|
|
|
|
|
|
$ NVIM_LISTEN_ADDRESS={} nvim
|
|
|
|
|
|
|
|
Use `:echo v:servername` to verify the address.
|
|
|
|
|
|
|
|
Client:
|
|
|
|
|
|
|
|
Expose $NVIM_LISTEN_ADDRESS to the environment before
|
|
|
|
using nvr or use its --servername option. If neither
|
|
|
|
is given, nvr assumes \"/tmp/nvimsocket\".
|
|
|
|
|
|
|
|
$ NVIM_LISTEN_ADDRESS={} nvr file1 file2
|
|
|
|
$ nvr --servername {} file1 file2
|
|
|
|
$ nvr --servername 127.0.0.1:6789 file1 file2
|
|
|
|
|
|
|
|
nvr is now starting a server on its own by running $NVR_CMD or 'nvim'.
|
|
|
|
|
|
|
|
Use -s to suppress this message.
|
|
|
|
|
|
|
|
[*] Starting new nvim process with address {}
|
|
|
|
""".format(old_address, old_address, old_address, old_address, new_address)))
|
|
|
|
|
|
|
|
|
2017-08-02 11:21:01 +00:00
|
|
|
def split_cmds_from_files(args):
|
|
|
|
for i, arg in enumerate(args):
|
|
|
|
if arg[0] != '+':
|
|
|
|
return [x[1:] for x in reversed(args[:i])], list(reversed(args[i:]))
|
|
|
|
return [], []
|
|
|
|
|
|
|
|
|
2017-04-27 11:22:40 +00:00
|
|
|
def print_sockaddrs():
|
|
|
|
sockaddrs = []
|
|
|
|
|
|
|
|
for proc in psutil.process_iter():
|
|
|
|
if proc.name() == 'nvim':
|
|
|
|
for conn in proc.connections('inet4'):
|
|
|
|
sockaddrs.insert(0, ':'.join(map(str, conn.laddr)))
|
|
|
|
for conn in proc.connections('unix'):
|
2017-06-30 00:18:58 +00:00
|
|
|
if conn.laddr:
|
|
|
|
sockaddrs.insert(0, conn.laddr)
|
2017-04-27 11:22:40 +00:00
|
|
|
|
|
|
|
for addr in sorted(sockaddrs):
|
|
|
|
print(addr)
|
|
|
|
|
|
|
|
|
2017-09-30 10:52:05 +00:00
|
|
|
def get_address_type(address):
|
|
|
|
try:
|
|
|
|
ip, port = address.split(':', 1)
|
|
|
|
if port.isdigit():
|
|
|
|
return 'tcp'
|
|
|
|
raise ValueError
|
|
|
|
except ValueError:
|
|
|
|
return 'socket'
|
|
|
|
|
|
|
|
|
2017-05-24 18:40:40 +00:00
|
|
|
def main(argv=sys.argv, env=os.environ):
|
2017-06-20 19:15:25 +00:00
|
|
|
options, arguments = parse_args(argv)
|
2017-10-18 04:11:21 +00:00
|
|
|
|
2018-03-01 19:26:05 +00:00
|
|
|
if options.version:
|
|
|
|
import pkg_resources
|
|
|
|
version = pkg_resources.require('neovim-remote')[0].version
|
|
|
|
print('nvr {}'.format(version))
|
|
|
|
return
|
|
|
|
|
2017-06-20 19:15:25 +00:00
|
|
|
if options.serverlist:
|
2017-04-27 11:22:40 +00:00
|
|
|
print_sockaddrs()
|
2017-11-21 22:05:39 +00:00
|
|
|
return
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 15:19:21 +00:00
|
|
|
address = options.servername or env.get('NVIM_LISTEN_ADDRESS') or '/tmp/nvimsocket'
|
2017-12-03 13:57:26 +00:00
|
|
|
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr = Nvr(address, options.s)
|
|
|
|
nvr.attach()
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 15:35:11 +00:00
|
|
|
if not nvr.server:
|
|
|
|
nvr.address = sanitize_address(address)
|
2017-12-03 15:19:21 +00:00
|
|
|
silent = options.remote_silent or options.remote_wait_silent or options.remote_tab_silent or options.remote_tab_wait_silent or options.s
|
|
|
|
if not silent:
|
2017-12-03 15:35:11 +00:00
|
|
|
show_message(address, nvr.address)
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.nostart:
|
|
|
|
sys.exit(1)
|
|
|
|
else:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.start_new_process()
|
2017-12-03 13:24:46 +00:00
|
|
|
|
|
|
|
if options.cc:
|
2017-06-20 19:15:25 +00:00
|
|
|
for cmd in options.cc:
|
2017-12-20 16:19:18 +00:00
|
|
|
if cmd == '-':
|
|
|
|
cmd = sys.stdin.read()
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command(cmd)
|
2017-02-26 16:20:48 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.l:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command('wincmd p')
|
2016-06-06 13:15:13 +00:00
|
|
|
|
2016-07-03 11:24:54 +00:00
|
|
|
try:
|
|
|
|
arguments.remove('--')
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
|
2017-06-20 19:15:25 +00:00
|
|
|
if options.remote is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.execute(options.remote + arguments, 'edit')
|
2017-06-20 19:15:25 +00:00
|
|
|
elif options.remote_wait is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nfiles = nvr.execute(options.remote_wait + arguments, 'edit', wait=True)
|
2017-12-03 15:19:21 +00:00
|
|
|
elif options.remote_silent is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.execute(options.remote_silent + arguments, 'edit', silent=True)
|
2017-06-20 19:15:25 +00:00
|
|
|
elif options.remote_wait_silent is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nfiles = nvr.execute(options.remote_wait_silent + arguments, 'edit', silent=True, wait=True)
|
2017-06-20 19:15:25 +00:00
|
|
|
elif options.remote_tab is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.execute(options.remote_tab + arguments, 'tabedit')
|
2017-06-20 19:15:25 +00:00
|
|
|
elif options.remote_tab_wait is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nfiles = nvr.execute(options.remote_tab_wait + arguments, 'tabedit', wait=True)
|
2017-06-20 19:15:25 +00:00
|
|
|
elif options.remote_tab_silent is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.execute(options.remote_tab_silent + arguments, 'tabedit', silent=True)
|
2017-06-20 19:15:25 +00:00
|
|
|
elif options.remote_tab_wait_silent is not None:
|
2017-12-03 15:35:11 +00:00
|
|
|
nfiles = nvr.execute(options.remote_tab_wait_silent + arguments, 'tabedit', silent=True, wait=True)
|
2017-12-03 15:19:21 +00:00
|
|
|
elif arguments:
|
|
|
|
# Act like --remote-silent.
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.execute(arguments, 'edit', silent=True)
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.remote_send:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.input(options.remote_send)
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.remote_expr:
|
2016-06-06 11:07:18 +00:00
|
|
|
result = ''
|
2017-12-20 16:19:18 +00:00
|
|
|
if options.remote_expr == '-':
|
|
|
|
options.remote_expr = sys.stdin.read()
|
2016-06-06 11:07:18 +00:00
|
|
|
try:
|
2017-12-03 15:35:11 +00:00
|
|
|
result = nvr.server.eval(options.remote_expr)
|
2016-06-06 11:07:18 +00:00
|
|
|
except:
|
2017-10-24 11:05:56 +00:00
|
|
|
print(textwrap.dedent("""
|
|
|
|
No valid expression: {}
|
|
|
|
Test it in Neovim: :echo eval('...')
|
|
|
|
If you want to execute a command, use -c or -cc instead.
|
|
|
|
""").format(options.remote_expr))
|
2016-06-06 11:07:18 +00:00
|
|
|
if type(result) is bytes:
|
|
|
|
print(result.decode())
|
|
|
|
elif type(result) is list:
|
|
|
|
print(list(map(lambda x: x.decode() if type(x) is bytes else x, result)))
|
|
|
|
elif type(result) is dict:
|
|
|
|
print({ (k.decode() if type(k) is bytes else k): v for (k,v) in result.items() })
|
|
|
|
else:
|
|
|
|
print(result)
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.o:
|
2017-06-20 19:15:25 +00:00
|
|
|
for fname in options.o:
|
2016-11-28 17:04:55 +00:00
|
|
|
if fname == '-':
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.read_stdin_into_buffer('new')
|
2016-11-28 17:04:55 +00:00
|
|
|
else:
|
2018-03-12 15:24:13 +00:00
|
|
|
nvr.fnameescaped_command('split', fname)
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.O:
|
2017-06-20 19:15:25 +00:00
|
|
|
for fname in options.O:
|
2016-11-28 17:04:55 +00:00
|
|
|
if fname == '-':
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.read_stdin_into_buffer('vnew')
|
2016-11-28 17:04:55 +00:00
|
|
|
else:
|
2018-03-12 15:24:13 +00:00
|
|
|
nvr.fnameescaped_command('vsplit', fname)
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.p:
|
2017-11-13 17:06:31 +00:00
|
|
|
for fname in options.p:
|
|
|
|
if fname == '-':
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.read_stdin_into_buffer('tabnew')
|
2017-11-13 17:06:31 +00:00
|
|
|
else:
|
2018-03-12 15:24:13 +00:00
|
|
|
nvr.fnameescaped_command('tabedit', fname)
|
2017-11-13 17:06:31 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.t:
|
2016-12-29 11:56:25 +00:00
|
|
|
try:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command("tag {}".format(options.t))
|
|
|
|
except nvr.server.error as e:
|
2016-12-29 11:56:25 +00:00
|
|
|
print(e)
|
|
|
|
sys.exit(1)
|
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.q:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command("silent execute 'lcd' fnameescape('{}')".
|
2016-12-28 12:45:27 +00:00
|
|
|
format(os.environ['PWD'].replace("'", "''")))
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command('call setqflist([])')
|
2017-06-20 19:15:25 +00:00
|
|
|
with open(options.q, 'r') as f:
|
2016-12-28 11:29:22 +00:00
|
|
|
for line in f.readlines():
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command("caddexpr '{}'".
|
2016-12-28 11:29:22 +00:00
|
|
|
format(line.rstrip().replace("'", "''").replace('|', '\|')))
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command('silent lcd -')
|
|
|
|
nvr.server.command('cfirst')
|
2016-12-28 11:29:22 +00:00
|
|
|
|
2017-12-03 13:24:46 +00:00
|
|
|
if options.c:
|
2017-06-20 19:15:25 +00:00
|
|
|
for cmd in options.c:
|
2017-12-20 16:19:18 +00:00
|
|
|
if cmd == '-':
|
|
|
|
cmd = sys.stdin.read()
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.command(cmd)
|
2017-02-26 16:20:48 +00:00
|
|
|
|
2017-07-11 13:46:44 +00:00
|
|
|
if 'nfiles' in locals():
|
|
|
|
exitcode = 0
|
|
|
|
|
|
|
|
def notification_cb(msg, args):
|
|
|
|
nonlocal nfiles
|
|
|
|
nonlocal exitcode
|
|
|
|
|
|
|
|
if msg == 'BufDelete':
|
|
|
|
nfiles -= 1
|
|
|
|
if nfiles == 0:
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.stop_loop()
|
2017-07-11 13:46:44 +00:00
|
|
|
elif msg == 'Exit':
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.stop_loop()
|
2017-07-11 13:46:44 +00:00
|
|
|
exitcode = args[0]
|
|
|
|
|
|
|
|
def err_cb(error):
|
|
|
|
print(error, file=sys.stderr)
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.stop_loop()
|
2017-07-11 13:46:44 +00:00
|
|
|
exitcode = 1
|
|
|
|
|
2017-12-03 15:35:11 +00:00
|
|
|
nvr.server.run_loop(None, notification_cb, None, err_cb)
|
2018-03-01 20:08:05 +00:00
|
|
|
nvr.server.close()
|
2017-07-11 13:46:44 +00:00
|
|
|
sys.exit(exitcode)
|
|
|
|
|
2016-06-06 10:15:14 +00:00
|
|
|
|
2016-06-06 11:58:55 +00:00
|
|
|
if __name__ == '__main__':
|
2016-06-06 10:15:14 +00:00
|
|
|
main()
|
2016-02-17 00:22:49 +00:00
|
|
|
|