Pergunta

Estou tentando escrever uma concha em Ruby e, para implementar a conclusão da guia, estou usando a função Winapi getch ler em um personagem de cada vez do usuário, verificando as guias.

O problema com isso é o backspace chave:

  1. Ele move o cursor mais para trás do que o prompt (por exemplo, com rápido hello>, o usuário pode apoiar o cursor para o h. Eu gostaria que parasse no espaço final.
  2. Quando o texto do usuário transborda na próxima linha do console, o backspace não vai voltar para a linha anterior.

(Eu sei que esses dois comportamentos são por design.)

Minha solução imaginada para esses problemas envolve o controle do movimento do cursor; Eu preciso saber para onde está o cursor e ser capaz de movê -lo.

No Linux, eu usaria sequências de escape da ANSI, mas elas não são suportadas pelo console do Windows.

Eu olhei para o Winapi e tentei encontrar funções que me deixariam fazer isso, mas tudo que eu poderia encontrar foi GetConsoleCursorInfo função, que retorna apenas o tamanho e a visibilidade do cursor.

Exemplos seriam apreciados, pois não tenho esperança em usar a classe Win32API para qualquer outra coisa que não seja funções primitivas.

Obrigado.

Foi útil?

Solução

Você provavelmente é melhor usar o ReadLine. Está incluído no instalador de um clique do Ruby. Uma configuração básica é:

require 'readline'

while line = Readline.readline('hello> ', true)
  #do something with line
  break if line == 'quit'
end

Você já terá recursos de readline padrão, como backspacing, alt+backspace, para excluir uma palavra, histórico e conclusão da guia. Há uma boa documentação sobre como personalizá -lo para suas necessidades aqui.


Editar:

Se você não possui o ReadLine instalado, pode obtê -lo e outras bibliotecas externas aqui. Você vai querer o ReadLine-4.3-2-MSWIN32 pacote. Copie o arquivo readline.dll (localizado no bin diretório) para o seu ruby\bin diretório. Isso deve resolver.

Embora não esteja documentado na página inicial do Ruby, parece que você também pode usar o ReadLine 5, disponível aqui. Especificamente, você precisa do binários distribuição. Copiar readLine5.dll (no bin diretório) para o seu ruby\bin diretório e renomeie -o para readline.dll.

Além disso, como uma nota lateral, não se assuste se require 'readline' Retorna falsa ao usar o IRB, pois parece pré-carregá-lo.

Outras dicas

Hmm, é certamente possível fazer backup e com código razoavelmente portátil, pois o Bash (1) pode fazer o backup da linha anterior, mesmo em uma caixa DOS. Eu imagino que está usando termcap ou ncurses, e possui no banco de dados Termcap um conjunto de códigos de controle que funcionam para a caixa DOS.

No Ruby, não acredito que haja nenhuma ligação de terminais, então você usa ncurses, em vez de usar o seu programa, um conjunto de códigos de controle dependentes do dispositivo. (Você gostaria de Ncurses sobre o TermCap de qualquer maneira.)

Depois de mudar para os NCurses, acredito que você encontrará elementos da API para fazer tudo o que precisa, incluindo backup de linhas e não substituir o prompt. (E certamente você não deve fazer backup de nada que não tenha saído para começar, independentemente do que a biblioteca está em uso.)

Na verdade, eu meio que gosto PestoResposta. Use ncurses se readline Não funciona ou se você precisar de abordagem do cursor por algum outro motivo.

Para uma implementação de readlina para o Windows, tente isto READLINE baseado em Ruby

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top