O processo do Vim para depois de executar um comando externo

4

Eu tenho usado o vim recentemente para programar em C. Eu criei atalhos para compilar e executar os programas a partir do próprio vim, mas recentemente o processo do vim parou após a execução do programa.

foo.c:

#include <stdio.h>

int main() {
    printf("Hello World!\n");
    return 0;
}

.vimrc:

set shellcmdflag=-ic

syntax on

autocmd FileType c map <F6> :!gcc -o "%:p:r.out" "%:." <bar> more<CR>
autocmd FileType c map <F7> :!%:p:r.out<CR>

Se eu clicar em F6 , o programa compila bem. Mas se eu acertar F7 , eu obtenho o seguinte:

Hello World!
[1]+  Stopped                 vim test.c

Eu posso usar fg para iniciar o processo de backup, mas está ficando um pouco chato fazê-lo. Alguém sabe como consertar isso?

    
por Jeffrey 16.09.2013 / 21:50

2 respostas

7

Não use um shell interativo para executar comandos. (Esse é o i em -ic .)

O shellcmdflag padrão ( -c ) deve funcionar bem.

Se você está especificando -i para obter o bash para ler seu arquivo .bashrc (que é um efeito colateral de iniciar um shell interativo), então seria melhor dizer bash para ler um ambiente de inicialização roteiro. Citando o bash manpage:

When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:

          if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

but the value of the PATH variable is not used to search for the file name.

Você pode definir variáveis de ambiente dentro do vim com :let

    
por 17.09.2013 / 00:04
0

Concordo que não se deve usar um subshell interativo, como aponta rici em sua resposta . (Apreciei particularmente a análise do problema em seu comentário .)

No entanto, definir BASH_ENV é perigoso: se você fizer isso, deve certificar-se de que o Bash seja nunca invocado a partir desse arquivo, direta ou indiretamente, ou terminará em um loop infinito de gerar processos de Bash. Isso pode ser difícil se você tiver uma configuração bastante sofisticada, já que é fácil não perceber que um programa que você está chamando é na verdade um script Bash.

Minha solução é simplesmente para set shell=bash-rcc , que é o seguinte script:

#!/usr/bin/env bash
#
#   bash-rcc - source ~/.bashrc and run bash -c command
#
#   This is used as the shell by programs such as vim where we want
#   ':!' commands to be able to use shell functions and aliases
#   defined in '~/.bashrc' but do not want the shell started in
#   interactive mode. Interactive mode does various things, such as
#   setting up its own process group, that can cause problems when
#   used to run a single command from another program.

[[ $1 = -c ]] && shift
. ~/.bashrc
eval "$1"
    
por 09.07.2018 / 23:57

Tags