<commit_before>import contextlib

from .lib import neovim
from .lib import util

NEOVIM_PATH = util.which('nvim')
if not NEOVIM_PATH:
    raise Exception('cannot find nvim executable')

INSERT_MODES = ['i']
VISUAL_MODES = ['V', 'v', '\x16']


class Vim:
    def __init__(self, nv=None):
        self.nv = nv
        if nv is None:
            self.nv = neovim.attach('child', argv=[NEOVIM_PATH, '--embed'])
            self.cmd('set noswapfile')
            self.cmd('set hidden')

    def cmd(self, *args, **kwargs):
        return self.nv.command_output(*args, **kwargs)

    def eval(self, *cmds):
        if len(cmds) == 1:
            return self.nv.eval(cmds[0])
        else:
            return [self.nv.eval(c) for c in cmds]

    # buffer methods
    def buf_activate(self, buf):
        self.cmd('b! {:d}'.format(buf.number))

    def buf_new(self):
        self.cmd('enew')
        return max((b.number, b) for b in self.nv.buffers)[1]

    def buf_close(self, buf):
        self.cmd('bw! {:d}'.format(buf.number))

    def press(self, key):
        self.nv.input(key)

    @property
    def sel(self):
        r1, c1, r2, c2 = self.eval('line(".")', 'col(".")', 'line("v")', 'col("v")')
        return (r2 - 1, c2 - 1), (r1 - 1, c1 - 1)

    def setpos(self, expr, line, col):
        return self.eval('setpos("{}", [0, {:d}, {:d}])'.format(expr, line, col))

    def select(self, a, b=None, block=False):
        add1 = lambda x: [n + 1 for n in x]
        a = add1(a)
        if b is None:
            if self.mode in VISUAL_MODES:
                # TODO: map key?
                self.press('\033')
            self.eval('cursor({:d}, {:d}, {:d})'.format(a[0], a[1], a[1]))
        else:
            b = add1(b)
            # don't exit visual mode if we're already in it
            # this prevents drag from flickering
            if not self.mode in VISUAL_MODES:
                # TODO: map key?
                self.press('\033')
                self.setpos('.', *a)
                self.cmd('normal! v')
            self.setpos('.', *b)

    @property
    def mode(self):
        return self.eval('mode()')
<commit_msg>tweak selection<commit_after>import contextlib

from .lib import neovim
from .lib import util

NEOVIM_PATH = util.which('nvim')
if not NEOVIM_PATH:
    raise Exception('cannot find nvim executable')

INSERT_MODES = ['i']
VISUAL_MODES = ['V', 'v', '\x16']


class Vim:
    def __init__(self, nv=None):
        self.nv = nv
        if nv is None:
            self.nv = neovim.attach('child', argv=[NEOVIM_PATH, '--embed'])
            self.cmd('set noswapfile')
            self.cmd('set hidden')

    def cmd(self, *args, **kwargs):
        return self.nv.command_output(*args, **kwargs)

    def eval(self, *cmds):
        if len(cmds) == 1:
            return self.nv.eval(cmds[0])
        else:
            return [self.nv.eval(c) for c in cmds]

    # buffer methods
    def buf_activate(self, buf):
        self.cmd('b! {:d}'.format(buf.number))

    def buf_new(self):
        self.cmd('enew')
        return max((b.number, b) for b in self.nv.buffers)[1]

    def buf_close(self, buf):
        self.cmd('bw! {:d}'.format(buf.number))

    def press(self, key):
        self.nv.feedkeys(self.nv.replace_termcodes(key))

    @property
    def sel(self):
        r1, c1, r2, c2 = self.eval('line(".")', 'col(".")', 'line("v")', 'col("v")')
        return (r2 - 1, c2 - 1), (r1 - 1, c1 - 1)

    def setpos(self, expr, line, col):
        return self.eval('setpos("{}", [0, {:d}, {:d}])'.format(expr, line, col))

    def select(self, a, b=None, block=False):
        add1 = lambda x: [n + 1 for n in x]
        a = add1(a)
        if b is None:
            if self.mode in VISUAL_MODES:
                # TODO: map key?
                self.press('\033')
            self.eval('cursor({:d}, {:d}, {:d})'.format(a[0], a[1], a[1]))
        else:
            b = add1(b)

            self.press('\033')
            self.setpos('.', *a)
            self.cmd('normal! v')
            # fix right hand side alignment
            if a < b:
                b = [b[0], b[1] - 1]
            self.setpos('.', *b)

    @property
    def mode(self):
        return self.eval('mode()')

{'fraction_non_alphanumeric': 0.17291271347248577, 'fraction_numerical': 0.015417457305502846, 'mean_word_length': 1.961376404494382, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2412059', 'n_tokens_mistral': 1537, 'n_tokens_neox': 1461, 'n_words': 381}