2010-03-04 27 views
18

que tienen estas líneas en mi ~/.inputrc:modo de entrada vi en línea de comandos Matlab?

set editing-mode vi 
set keymap vi 

Esto me permite utilizar combinaciones de teclas vi en cada programa que utiliza readlines GNU para la entrada de texto. Ejemplos: python, irb, sftp, bash, sqlite3, y así sucesivamente. Hace que trabajar con una línea de comando sea muy fácil. Matlab no usa readlines, pero vi keybindings sería increíble tener al depurar o trabajar interactivamente. ¿Hay una solución existente?

que tienden a utilizar matlab -nosplash -nodesktop desde la línea de comandos y que me hizo pensar: ¿sería posible escribir un envoltorio que hace readlines uso y pasar la entrada a matlab? (Si tengo que poner en práctica esto, probablemente yo prefiero hacerlo en Ruby.)

Actualización:

Gracias por la ayuda. Esto casi funciona:

# See also: http://bogojoker.com/readline/ 
require 'readline' 

puts 'Starting Matlab...' 
io = IO.popen('matlab -nosplash -nodesktop 2>&1', 'w+') 

while input_line = Readline.readline('>> ', true) 
    io.puts input_line 
    puts io.gets 
end 

Pero sólo se lee una sola línea de Matlab a la vez (porque estoy usando gets). ¿Alguna idea sobre cómo obtener todo hasta la próxima vez que está esperando la entrada? Esto es lo que está pasando (Estoy entrando cosas en el >> rápida):

Starting Matlab... 
>> 1 

>> 2 
          < M A T L A B (R) > 
>> 3 
        Copyright 1984-2009 The MathWorks, Inc. 
>> 4 
       Version 7.8.0.347 (R2009a) 32-bit (glnx86) 
>> 5 
          February 12, 2009 
>> 6 

>> 7 

>> 8 
    To get started, type one of these: helpwin, helpdesk, or demo. 
>> 9 
    For product information, visit www.mathworks.com. 
>> 0 

>> 1 
>> 
>> 2 
ans = 
>> 3 

>> 4 
    1 
>> 5 

>> 6 
>> 
>> 7 
ans = 
>> 8 

>> 9 
    2 
>> 0 

>> 1 
>> 
>> 2 
ans = 
>> 3 

>> 4 
    3 

Respuesta

4

Sí, eso debería ser bastante fácil. Es solo un caso especial del problema general de "abrir un proceso y vincularlo a su stdin y stdout", y eso no es difícil.

Un poco de búsqueda en Google encuentra que IO.popen() es la pieza correcta de Ruby para eso, y hay un poco más de detalle en las respuestas aquí: http://groups.google.com/group/ruby-talk-google/browse_thread/thread/0bbf0a3f1668184c. ¡Con suerte, eso es suficiente para comenzar!

Actualización: Parece que ya casi está allí con su envoltorio. Lo que necesita para terminar es reconocer cuándo Matlab está pidiendo información, y solo pedirle al usuario que la ingrese. Yo sugeriría probar este pseudocódigo:

while input_line = Readline.readline('>> ', true) 
    io.puts input_line 
    while ((output_line = io.gets) != '>> ') // Loop until we get a prompt. 
    puts io.gets 
    end 
end 

Eso no está del todo bien, ya que tiene que hacer el bucle interno una vez antes de pedir la primera línea de entrada, pero debe darle la idea. Es posible que también deba ajustar el texto del mensaje que está buscando.

Actualización 2: Bien, así que también tenemos que dar cuenta del hecho de que no hay EOL después de un aviso y que io.gets se bloqueará. Aquí hay una versión revisada que utiliza el hecho de que puede dar una línea en blanco a un aviso de Matlab y simplemente le dará otro aviso sin hacer nada. He reorganizado el ciclo para hacer las cosas un poco más claras, aunque esto significa que ahora tienes que agregar lógica para averiguar cuándo terminaste.

while [not done] // figure this out somehow 
    io.puts blank_line      // This will answer the first 
              // prompt we get. 
    while ((output_line = io.gets) != '>> ') // Loop until we get a prompt. 
    puts io.gets       // This won't hang, since the 
    end          // prompt will get the blank 
              // line we just sent. 

    input_line = Readline.readline('>> ', true) // Get something, feed it 
    io.puts input_line       // to the next prompt. 

    output_line = io.gets // This will eat the prompt that corresponds to 
          // the line we just fed in. 
end 
+0

Sí, intenté algo similar antes, pero no funciona. 'gets' espera una línea completa, por lo que simplemente se cuelga. Estoy intentando algo con 'getc' ahora, pero el jurado todavía está afuera en eso. –

+0

IIRC, si presiona Intro en un aviso de Matlab, simplemente le devolverá otro aviso sin hacer nada. Creo que puedes usar eso para evitar el ahorcamiento. Editaré el código en mi respuesta para reflejar eso. –

3

En realidad, usted puede ser mejor de escribir esto en C - entonces usted puede llamar a la matlab engine directamente. Básicamente, esto le permite escribir su propio front-end a matlab, si así lo desea, utilizando la librería GNU Readline.

4

Usted podría haber usado rlwrap de una manera directa.

rlwrap is a wrapper that uses the GNU readline library to allow the editing 
of keyboard input for any other command. 

http://utopia.knoware.nl/~hlub/rlwrap/#rlwrap

Por desgracia, se bloqueará contextual del tabulador en MATLAB, que es útil por sí misma.

+0

Interesante. Gracias por compartir eso. No sabía que existía. –

+0

Un enfoque similar (es decir, usar un contenedor), pero con la finalización de pestañas es [IMatlab] (https://github.com/imatlab/imatlab). Vea [esta respuesta] (https://superuser.com/a/1288031/865050) para más detalles. – hugke729

Cuestiones relacionadas