Esempio n. 1
0
def shell_path():
    pathregex = re.compile(r'\bpython[/\-]?\d\.\d+\b', re.IGNORECASE)

    lines = []

    def _findpybin(pycmd):
        code = 'import sys, simplejson; print(simplejson.dumps(sys.path))'
        raw = execute([pycmd, '-c', code], stdout=True)[1].decode('utf-8')
        paths = simplejson.loads(raw)
        for path in paths:
            if not path.startswith(os.environ['HOME']):
                continue
            if not pathregex.search(path):
                continue
            suffix = '/lib/python/site-packages'
            if not path.endswith(suffix):
                continue
            binpath = path[0:-len(suffix)] + '/bin'
            if not os.path.exists(binpath):
                continue
            yield 'PATH_HIGH="{}:$PATH_HIGH"'.format(binpath)

    if want_python2_anything and haveexecutable('python2'):
        lines += list(_findpybin('python2'))
    if haveexecutable('python3') and haveexecutable('pip3'):
        lines += list(_findpybin('python3'))

    # if we are installing pip modules into separate bin paths, add them to our $PATH now
    pippaths = getpippaths()
    try:
        lines.append('PATH_HIGH="%s:$PATH_HIGH"' % pippaths['pip3'])
    except KeyError:
        pass
    try:
        if want_python2_anything:
            lines.append('PATH_HIGH="%s:$PATH_HIGH"' % pippaths['pip2'])
    except KeyError:
        pass

    lines.append('PATH_HIGH="$HOME/bin:$PATH_HIGH"')

    blockinfile('~/.shellrc',
                lines,
                '# start of PATH modifications',
                '# end of PATH modifications')
Esempio n. 2
0
def main():
    # TODO to auto rename to an "x.old" and warn?
    files.symlink("bashrc", ".bashrc")
    files.symlink("bash_profile", ".bash_profile")
    files.symlink("profile", ".profile")  # TODO maybe add lines instead?
    files.symlink("editorconfig", ".editorconfig")
    if system.haveexecutable("task"):
        files.symlink("taskrc", ".taskrc")
    if system.haveexecutable("asdf"):
        files.symlink("tool-versions", ".tool-versions")
        files.symlink("asdfrc", ".asdfrc")
        files.symlink("default-golang-pkgs", ".default-golang-pkgs")

    # git common config:
    # TODO error if git not present
    # TODO into separate function
    gitpath = os.path.join(HERE, "common.gitconfig")
    system.execute(["git", "config", "--global", "include.path", gitpath])
    # NOTE this might overwrite if there's another include.path already present
    # TODO revert/cleanup somehow?
    # TODO check that path specification using ~/ works

    # TODO does pipinstall use system pip or HOMELY's one?

    files.symlink("vimrc", ".vimrc")
    # install vim-plug
    files.mkdir(".vim")
    files.mkdir(".vim/autoload")
    files.mkdir(".vim/swaps")
    files.mkdir(".vim/backups")
    files.mkdir(".vim/doc")
    files.download(
        "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim",
        "~/.vim/autoload/plug.vim",
    )
    # link custom ftplugin files
    files.symlink("vim-ftplugin", ".vim/ftplugin")

    if system.haveexecutable("pipenv"):
        # TODO warn that they need to reload for this to take effect
        files.lineinfile(".bashrc.local", 'eval "$(pipenv --completion)"')

    if system.haveexecutable("i3"):
        # ~/.local/bin is towards the front of PATH thanks to .profile
        files.symlink("i3exit.sh", "~/.local/bin/i3exit")
        files.symlink("locker.sh", "~/.local/bin/locker")
        files.symlink("i3.conf", "~/.i3/config")

    if system.haveexecutable("kitty"):
        files.mkdir("$XDG_CONFIG_HOME/kitty")
        files.symlink("kitty.conf", "$XDG_CONFIG_HOME/kitty/kitty.conf")

    if system.haveexecutable("pre-commit"):
        # Install pre-commit in all new/cloned repos
        # See also https://pre-commit.com/#pre-commit-init-templatedir
        template_path = "{}/.git-template".format(os.environ["HOME"])
        system.execute(["git", "config", "--global", "init.templateDir", template_path])
        system.execute(["pre-commit", "init-templatedir", template_path])

    return 0
Esempio n. 3
0
def init_composer():
    global INIT_DONE

    if not haveexecutable('composer'):
        raise Exception("TODO: composer is not installed")  # noqa

    composer_config = {
        'minimum-stability': 'dev',
        'prefer-stable': True,
    }
    mkdir('~/.config')
    mkdir('~/.config/composer')
    with writefile('~/.config/composer/composer.json') as f:
        json.dump(composer_config, f)

    INIT_DONE = True
Esempio n. 4
0
def nvim_install():
    if install_nvim_via_apt():
        installpkg('neovim')
        installpkg('python-neovim')
        return

    if (allow_installing_stuff and haveexecutable('brew')
            and yesno('install_nvim_package', 'Install nvim from apt/brew?')):
        installpkg('neovim')
        return

    the_hard_way = yesno('compile_nvim',
                         'Compile/install nvim from source?',
                         recommended=allow_installing_stuff)
    if not the_hard_way:
        raise Exception('No way to install neovim')

    need_installpkg(
        apt=(
            'libtool',
            'libtool-bin',
            'autoconf',
            'automake',
            'cmake',
            'g++',
            'pkg-config',
            'unzip',
            'gettext',
        ),
        yum=('cmake', 'gcc-c++', 'unzip'),
        brew=('cmake', 'libtool', 'gettext'),
    )
    n = InstallFromSource('https://github.com/neovim/neovim.git',
                          '~/src/neovim.git')
    n.select_tag(NVIM_TAG)
    n.compile_cmd([
        ['make', 'distclean'],
        ['make'],
        ['sudo', 'make', 'install'],
    ])
    run(n)
Esempio n. 5
0
def vim_config():
    # install vim-plug into ~/.vim
    mkdir('~/.vim')
    mkdir('~/.nvim')
    mkdir('~/.config')
    mkdir('~/.config/nvim')
    symlink('~/.vimrc', '~/.config/nvim/init.vim')
    mkdir('~/.vim/autoload')
    download(
        'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim',
        '~/.vim/autoload/plug.vim')

    def mkdir_r(path):
        assert len(path)
        if os.path.islink(path):
            raise Exception(
                "Cannot mkdir_r(%r): path already exists but is a symlink" %
                path)

        # if the thing already exists but isn't a dir, then we can't create it
        if os.path.exists(path) and not os.path.isdir(path):
            raise Exception(
                "Cannot mkdir_r(%r): path already exists but is not a dir" %
                path)

        # create the parent then our target path
        parent = os.path.dirname(path)
        if len(parent) > 5:
            mkdir_r(parent)
        mkdir(path)

    def _static(url, dest):
        dest = HOME + '/.vimstatic/' + dest
        mkdir_r(os.path.dirname(dest))
        download(url, dest)

    vprefs = HOME + '/.vim/prefs.vim'
    nprefs = HOME + '/.nvim/prefs.vim'

    # chuck in a reference to our shiny new vimrc.vim (this will end up below the rtp magic block)
    lineinfile('~/.vimrc', 'source %s/vimrc.vim' % HERE, where=WHERE_TOP)

    # do we want a debugger plugin in vim?
    for varname, varval in get_vim_options().items():
        lineinfile(
            '~/.vim/prefs.vim',
            f'let {varname} = {"1" if varval else "0"}  " set by phodge\'s dotfiles'
            .format(varname, '1' if varval else '0'),
            where=WHERE_END,
        )

    # put our magic &rtp block at the top of our vimrc
    blockinfile('~/.vimrc', [
        '  " reset rtp',
        '  set runtimepath&',
        '  " let other scripts know they\'re allowed to modify &rtp',
        '  let g:allow_rtp_modify = 1',
        '  " grab local preferences',
        '  if filereadable(%r)' % vprefs,
        '    source %s' % vprefs,
        '  endif',
        '  if has(\'nvim\') && filereadable(%r)' % nprefs,
        '    source %s' % nprefs,
        '  endif',
    ],
                '" {{{ START OF dotfiles runtimepath magic',
                '" }}} END OF dotfiles runtimepath magic',
                where=WHERE_TOP)

    # if the .vimrc.preferences file doesn't exist, create it now
    if not os.path.exists(vprefs):
        with open(vprefs, 'w') as f:
            f.write('let g:vim_peter = 1\n')

    # make sure we've made a choice about clipboard option in vprefs file
    @whenmissing(vprefs, 'clipboard')
    def addclipboard():
        if allowinteractive():
            if yesno(None, 'Use system clipboard in vim? (clipboard=unnamed)',
                     None):
                rem = "Use system clipboard"
                val = 'unnamed'
            else:
                rem = "Don't try and use system clipboard"
                val = ''
            with open(vprefs, 'a') as f:
                f.write('" %s\n' % rem)
                f.write("set clipboard=%s\n" % val)

    # put a default value about whether we want the hacky mappings for when the
    # terminal type isn't set correctly
    @whenmissing(vprefs, 'g:hackymappings')
    def sethackymappings():
        with open(vprefs, 'a') as f:
            f.write('" Use hacky mappings for F-keys and keypad?\n')
            f.write('let g:hackymappings = 0\n')

    # in most cases we don't want insight_php_tests
    @whenmissing(vprefs, 'g:insight_php_tests')
    def setinsightphptests():
        with open(vprefs, 'a') as f:
            f.write('" Do we want to use insight to check PHP code?\n')
            f.write('let g:insight_php_tests = []\n')

    # lock down &runtimepath
    lineinfile('~/.vimrc', 'let g:allow_rtp_modify = 0', where=WHERE_END)

    # if we have jerjerrod installed, add an ALWAYSFLAG entry for git repos in ~/src/plugedit
    if False and wantjerjerrod():
        mkdir('~/.config')
        mkdir('~/.config/jerjerrod')
        lineinfile('~/.config/jerjerrod/jerjerrod.conf',
                   'PROJECT ~/src/plugedit/*.git ALWAYSFLAG')

    # icinga syntax/filetype
    if yesno('want_vim_icinga_stuff',
             'Install vim icinga2 syntax/ftplugin?',
             default=False):
        files = ['syntax/icinga2.vim', 'ftdetect/icinga2.vim']
        for name in files:
            url = 'https://raw.githubusercontent.com/Icinga/icinga2/master/tools/syntax/vim/{}'
            _static(url.format(name), name)

    # <est> utility
    hasphp = haveexecutable('php')
    if yesno('install_est_utility', 'Install <vim-est>?', hasphp):
        est = InstallFromSource('https://github.com/phodge/vim-est.git',
                                '~/src/vim-est.git')
        est.select_branch('master')
        est.symlink('bin/est', '~/bin/est')
        run(est)
Esempio n. 6
0
def powerline_theme():
    right = [
        {
            "function": "todonext.powerline.firstitem"
        },
    ]

    if haveexecutable('jerjerrod') and wantjerjerrod():
        wsnames = "jerjerrod.powerline.wsnames"
        right += [
            {
                "function": "jerjerrod.powerline.wsscancount"
            },
            {
                "function": wsnames,
                "args": {
                    "category": "JERJERROD:CHANGED"
                }
            },
            {
                "function": wsnames,
                "args": {
                    "category": "JERJERROD:UNTRACKED"
                }
            },
            {
                "function": wsnames,
                "args": {
                    "category": "JERJERROD:UNPUSHED"
                }
            },
            {
                "function": wsnames,
                "args": {
                    "category": "JERJERROD:UNKNOWN"
                }
            },
        ]

    right.append({
        "function": "homely.powerline.shortstatus",
        "args": {
            "autoupdate":
            True,
            "reattach_to_user_namespace":
            haveexecutable('reattach-to-user-namespace'),
            "colors": {
                "paused": "HOMELY:PAUSED",
                "running": "HOMELY:RUNNING",
                "failed": "HOMELY:FAILED",
                "noconn": "HOMELY:NOCONN",
                "dirty": "HOMELY:DIRTY",
                "never": "HOMELY:NEVER",
                "ok": "HOMELY:OK",
            }
        },
    })
    right.append({
        "function": "powerline.segments.common.time.date",
        "name": "time",
        "args": {
            "format": "%H:%M",
            "istime": True,
        },
    })
    right.append({"function": "powerline.segments.common.net.hostname"})

    config = {"segments": {"right": right}}
    if want_unicode_fix():
        config["segment_data"] = {"time": {"before": ""}}

    import simplejson
    dumped = simplejson.dumps(config)
    mkdir('~/.config')
    mkdir('~/.config/powerline')
    mkdir('~/.config/powerline/themes')
    mkdir('~/.config/powerline/themes/tmux')
    with writefile('~/.config/powerline/themes/tmux/default.json') as f:
        f.write(dumped)
Esempio n. 7
0
from HOMELY import (allow_installing_stuff, getpippaths, section_macos,
                    want_python2_anything, wantjerjerrod, wantzsh)

bash_profile = os.environ['HOME'] + '/.bash_profile'
bashrc = os.environ['HOME'] + '/.bashrc'
zshrc = os.environ['HOME'] + '/.zshrc'
HERE = os.path.dirname(__file__)


def install_completions(rcfile):
    lineinfile(rcfile, 'want_click_completion homely')
    if wantjerjerrod():
        lineinfile(rcfile, 'want_click_completion jerjerrod')


@section_macos(enabled=allow_installing_stuff and haveexecutable('brew'))
def bash_install():
    if not yesno('upgrade_bash', 'Upgrade bash?', default=False):
        return

    # install newer version of bash using homebrew or some other mechanism
    execute(['brew', 'install', 'bash'])

    bash_exec = '/usr/local/bin/bash'

    # how to add /usr/local/bin/bash to /etc/shells?
    for line in open('/etc/shells').readlines():
        if line.strip() == bash_exec:
            break
    else:
        # TODO: this line needs testing
Esempio n. 8
0
def tmux_keys():
    import re

    lines = []

    # needs to be installed for the current version of python
    mypipinstall('pyyaml', ['pip%d' % sys.version_info.major])
    import yaml

    with open(HERE + '/keybindings/keys.yaml') as f:
        document = yaml.safe_load(f)
    regex = re.compile(r"^(C-)?(O-)?(M-)?(S-)?([ -~]|CR|BS|SPACE|ESC)$")
    if 'tmux' in document:
        static = {}
        dynamic = {}
        if haveexecutable("reattach-to-user-namespace"):
            static[
                'tmux_copy_cmd'] = 'copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"'
        elif haveexecutable("pbcopy"):
            static['tmux_copy_cmd'] = 'copy-pipe-and-cancel "pbcopy"'
        elif True:
            # XXX: I've been having issues with Ubuntu terminal lately where it
            # can't decipher the terminal codes coming from tmux's
            # copy-selection command
            static['tmux_copy_cmd'] = 'copy-pipe-and-cancel "xsel -b -i"'
        else:
            static['tmux_copy_cmd'] = 'copy-selection'

        sections = [
            ('direct', 'bind-key -n {key} {binding}'),
            ('prefixed', 'bind-key {key} {binding}'),
            ('copy-mode-vi',
             'bind-key -T copy-mode-vi {key} send-keys -X {binding}'),
        ]

        for sectionname, template in sections:
            for keycombo, binding in document["tmux"].get(sectionname,
                                                          {}).items():
                if hasattr(binding, 'keys'):  # is it a dict?
                    if 'static' in binding:
                        binding = static[binding['static']]
                    elif 'dynamic' in binding:
                        binding = dynamic[binding['dynamic']]()
                    else:
                        raise Exception("Invalid binding %r" % binding)
                m = regex.match(keycombo)
                if not m:
                    warn("Invalid keycombo for tmux: direct: %r" % keycombo)
                    continue
                ctrl, opt, meta, shift, key = m.groups()
                if key == "CR":
                    key = "Enter"
                elif key == "ESC":
                    key = "Escape"
                elif key == "SPACE":
                    key = "Space"
                else:
                    assert not key.islower(
                    ), "Lowercase keycombo %r is not allowed" % keycombo
                    key = key.lower()
                modifiers = ''
                if ctrl:
                    modifiers += 'C-'
                assert not opt, "O- prefix not allowed for tmux keybinding %r" % keycombo
                if meta:
                    modifiers += 'M-'
                if shift:
                    assert key.islower(), "Invalid keycombo %r" % keycombo
                    key = key.upper()
                lines.append(
                    template.format(key=modifiers + key, binding=binding))

    # we also want to make our special PANE mode
    pm = TmuxCustomMode(
        'panemode',
        "PANEMODE: Move between panes using h, j, k, l. Resize panes using H, J, K, L"
    )
    pm.prefixkeybind('p')
    pm.prefixkeybind('C-p')
    pm.bindkey('h', 'select-pane -L')
    pm.bindkey('j', 'select-pane -D')
    pm.bindkey('k', 'select-pane -U')
    pm.bindkey('l', 'select-pane -R')
    pm.bindkey('H', 'resize-pane -L 2')
    pm.bindkey('J', 'resize-pane -D 2')
    pm.bindkey('K', 'resize-pane -U 2')
    pm.bindkey('L', 'resize-pane -R 2')
    lines.extend(pm.getlines())

    with writefile('~/.tmux/keybindings.conf') as f:
        for line in lines:
            f.write(line)
            f.write("\n")
Esempio n. 9
0
from pathlib import Path
from homely.files import symlink
from homely.system import haveexecutable, execute
from homely.install import installpkg


if haveexecutable('apt'):
    if not haveexecutable('git'):
        installpkg('git')
    if not haveexecutable('curl'):
        installpkg('curl')
    if not haveexecutable('wget'):
        installpkg('wget')
    if not haveexecutable('zsh'):       
        installpkg('zsh')
    if not haveexecutable('vim'):
        installpkg('vim')
    if not haveexecutable('tmux'):
        installpkg('tmux')


omz_dir = Path('~/.oh-my-zsh')
if not omz_dir.is_dir():
    execute(['sh', '-c', "'$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)'")
    
vundle_dir = Path('~/.vim/bundle/Vundle.vim')
if not vundle_dir.is_dir():
    execute(['git','clone','https://github.com/VundleVim/Vundle.vim.git', '~/.vim/bundle/Vundle.vim'])
    execute(['vim','+PluginInstall'])