Crea un editor de línea simple

19

In: una cadena sin saltos de línea *
Permitir al usuario editar y enviar la línea
Out: la cadena modificada (opcionalmente con un salto de línea final)

El editor de línea debe, como mínimo, permitir al usuario:

  1. mover un cursor visible hacia la izquierda y hacia la derecha

  2. insertar y / o sobrescribir caracteres en la posición del cursor

  3. eliminar caracteres en la posición del cursor

  4. enviar la nueva cadena, es decir, dejar de editar, la cadena modificada se devolverá / imprimirá / mostrará / guardará ... (sin otro texto)

Apreciado, pero no requerido:

  • explicación de tu código.

  • enlace a un sitio de prueba en línea que puede demostrar su programa / función

  • Una imagen animada que demuestra el uso (TIO, por ejemplo, no permite la interactividad)

Nota:

  • las combinaciones de teclas son solo sugerencias

  • No se requiere GUI o estilo visual

Ejemplos

A continuación, el cursor se ilustra con _.

In: Just some text
permite al usuario editar: el
Just some text_  usuario presiona (tecla de flecha izquierda) nueve veces El
Just ̲some text  usuario presiona Delcuatro veces El
Just ̲ text  usuario presiona El  usuario presiona Out:any
Just any_text Enter
Just any text

In: Remove me
permite al usuario editar: el
Remove me_  usuario presiona Backspacenueve veces El
_  usuario presiona Out: (cadena vacía)Enter
 


* Para evitar soluciones triviales del editor, esto debe proporcionarse a través de un método de entrada diferente al de los comandos de edición, o debe separarse de ellos mediante una nueva línea o similar.

Adán
fuente
¿Tenemos que usar esas teclas exactas para E / S? Además, ¿podemos crear un archivo para guardar el texto?
Rɪᴋᴇʀ
1
Las combinaciones de teclas de @Riker son solo sugerencias . Los métodos de entrada y salida siguen los valores predeterminados de PPCG .
Adám
¿Puede la cadena contener nuevas líneas? ¿Y se puede usar una nueva línea para "enviar"?
Conor O'Brien
@ ConorO'Brien No; Editor de línea simple . Si; El editor debe, como mínimo, permitir al usuario: (...) 4. enviar la nueva cadena
Adám
1
Sería bueno si especificara la línea en el cuerpo real de la pregunta, ya que los títulos en este sitio no son exactamente especificaciones ...
Conor O'Brien

Respuestas:

3

APL (Dyalog) , 5 bytes

⍞←⍞⋄⍞

Este es un tradfn, así que para usarlo, haga

a
⍞←⍞⋄⍞

Y luego llámelo usando a, después de lo cual proporciona la cadena de inicio, y luego puede editar la cadena.

Kritixi Lithos
fuente
8

JavaScript (ES6), 15 14 bytes

¡No entiendo por qué esto está recibiendo tantos votos positivos!

s=>prompt(s,s)

Guarde un byte gracias a la sugerencia de Adám de que muestre la entrada original en el prompt.


Intentalo

f=
s=>prompt(s,s)
console.log(f("Edit this ..."))

Lanudo
fuente
1
Guarde un byte reemplazándolo ""con 0o incluso s(para que el usuario pueda ver el texto original mientras lo edita, una característica ordenada).
Adám
5

Bash 4.x, 25 caracteres

read -ei "$*" t
echo "$t"

Ejecución de muestra:

bash-4.3$ bash interactive.sh hello world
hello golfing world
hello golfing world

(La línea 2 anterior era la edición interactiva, la línea 3 la salida del texto resultante).

hombre trabajando
fuente
1
¿No funciona para mí -bash: read: -i: invalid option? mandice que solo ersse permiten banderas.
Rɪᴋᴇʀ
Sí, estaba a punto de preguntar-ei
Adám
-ise introdujo en Bash 4.0 (lanzado en febrero de 2009) - "-i text Use TEXT como el texto inicial de Readline".
manatwork
Me pregunto, ¿funcionaría el gato?
Matthew Roh el
catsolo espera la transmisión entrante, para lo cual el shell no proporcionará funcionalidad de edición. Al menos no por defecto.
manatwork
3

Bash + Vi / Vim, 14 bytes

echo $1>a;vi a

vitiene un alias vimen macOS, no sé sobre otros sistemas operativos.

Rɪᴋᴇʀ
fuente
Tal vez me falta algo, pero ¿cumple esto el requisito de generar la cadena modificada?
Grayson Kent el
1
@GraysonKent puede guardar y salir presionando :wq!o :x, así que creo que sí. OP es un poco confuso sobre lo que califica como eso.
Rɪᴋᴇʀ
3

HTML + JavaScript (ES6), 77 66 64 bytes

HTML

<input id=t

JavaScript

onkeyup=e=>e.which-13||alert(t.value);f=a=>t.value=a;

Ahorró 10 bytes gracias a Jörg Hülsermann y 2 bytes gracias a Luke.

onkeyup=e=>e.which-13||alert(t.value);f=a=>t.value=a;

f("Remove Me");
<input id=t>

Tom
fuente
2
puede eliminar el atributo tipo para el Elemento de entrada
Jörg Hülsermann
Probablemente deberías usar oninputen su lugar.
Matthew Roh el
@SIGSEGV No creo que se oninputdispare cuando Enterse presiona
Tom
1
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)guarda dos bytes.
Lucas
3

Python 2 , 275 200 bytes

No es un ganador, pero aquí está:

from msvcrt import*
s=list(input())[::-1]
c=i=0
def p(a):print''.join(a)[::-1]
while'\r'!=c:p(s[:i]+['<']+s[i:]);c=getch();x=c!='\b';exec["s[i:i+1-x]=c*x","i=(i-1+2*(c<'\\t'))%-~len(s)"][x*' '>c]
p(s)

Explicación:

Funciona invirtiendo la entrada (con [::-1]) y excluyendo e insertando caracteres en esa entrada invertida para que el cursor no tenga que moverse. Lo invierte nuevamente al imprimir.

Uso:

Tecla [Tab] para mover a la derecha
[Ctrl + C] para mover a la izquierda
[Retroceso] para borrar
[Volver] para finalizar la edición
Cualquier otra tecla, se insertará en el texto

Ejemplo:

Usando el ejemplo de OP

In: el Just some text
Just some text>
Just some> text  usuario presiona Ctrl+Ccinco veces El
Just > text  usuario presiona Backspacecuatro veces El
Just any> text  usuario presiona El  usuario presiona Out:any
Just any> text Enter
Just any text

Versión del editor en línea:

Si desea que el texto se edite en línea, agregue ,'\r',al final de la printdeclaración:

def p(a):print''.join(a)[::-1],'\r',
Felipe Nardi Batista
fuente
66
+1 Muy bien. Primera respuesta que realmente implementa un editor real, en lugar de depender de una funcionalidad preexistente. Estaba considerando publicar otro desafío para hacer precisamente esto.
Adám
¿No puede guardar bytes usando otras teclas para izquierda y derecha?
Adám
Podría asumir personajes como -y +para hacerlo, pero el editor no podría aceptar esos personajes entonces
Felipe Nardi Batista
¿Qué tal \ty \v?
Adám
1
Ese es el problema del usuario, ¿no? Control + K, tal vez?
Adám
3

C + ENFERMEDADES, 573 bytes

#include <curses.h>
i;j;k;s;c;p;int main(a,b)char**b;{char*q;char t[999];if(a&&(q=b[1]))while(*q)t[s++]=*q++;i=s;initscr();noecho();keypad(stdscr,1);do{for(j=0;j<i;j++)addch(t[j]);addch('|');for(j=i;t[j];j++)addch(t[j]);c=getch();switch(c){case KEY_LEFT:if(i)i--;break;case KEY_RIGHT:if(i<s)i++;break;case 8:case 127:case KEY_BACKSPACE:if(i){for(k=i-1;k<s;k++)t[k]=t[k+1];i--;s--;}break;case KEY_DC:if(i<s){for(k=i;k<s;k++)t[k]=t[k+1];s--;}break;default:if(c>31&c<127){for(k=s;k>i;k--)t[k]=t[k-1];t[i]=c;i++;s++;}}clear();}while(c!=10);printw(t);getch();endwin();return 0;}

Prueba

  • Compilar y ejecutar con entrada Just some text.

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

  • Presione el botón de flecha izquierda nueve veces.

ingrese la descripción de la imagen aquí

  • Presione el botón Eliminar cuatro veces.

ingrese la descripción de la imagen aquí

  • Presione aentonces y nluego y.

ingrese la descripción de la imagen aquí

  • Presione Enterpara terminar.

ingrese la descripción de la imagen aquí

Detallado

#include <curses.h>

int main(int argc, char ** argv)
{
    char*q = 0;
    char t[999] = {0};
    int j = 0, k = 0;
    int i = 0; // cursor before first char
    int s = 0; // current size
    int c = 0; // current input
    int p = 0;

    // copy first command-line argument
    if(argc>0 && (q=argv[1]))while(*q)t[s++]=*q++; i=s;

    initscr(); // initiate NCURSES
    noecho(); // input does not echo on entry
    keypad(stdscr,TRUE); // handle all input

    do
    {
        // print current content with cursor
        for(j=0;j<i;j++) addch(t[j]);
        addch('|'); for(j=i;t[j];j++) addch(t[j]);

//      printw("\n\n> key %d pressed",c); // debug

        c = getch(); // read next char

        switch(c)
        {
            case KEY_LEFT: // left arrow; cursor left
            if(i > 0) i--;
            break;

            case KEY_RIGHT: // right arrow; cursor right
            if(i < s) i++;
            break;

            case 8: // backspace; remove previous char
            case 127:
            case KEY_BACKSPACE:
            if(i > 0)
            {
                for(k=i-1; k<s; k++) t[k]=t[k+1];
                i--;s--;
            }
            break;

            case KEY_DC: // delete; remove next char
            if(i < s)
            {
                for(k=i; k<s; k++) t[k]=t[k+1];
                s--;
            }
            break;

            default: // none of the above

            if(c > 31 && c < 127) // printable char
            {
                for(k=s; k>i; k--) t[k]=t[k-1];
                t[i] = c;i++;s++;
            }
        }

        clear(); // clear screen
        if(c == 10) break;
    }
    while(c);

    addch('\n');
    printw(t); // print final result
    getch(); // wait for any input
    endwin();
    return 0;
}
Khaled.K
fuente
¿No se puede reemplazar KEY_*por los enteros respectivos para guardar algunos bytes?
sergiol
2

VBScript, 23 40 bytes

MsgBox InputBox("",,Wscript.Arguments(0))

ingrese la descripción de la imagen aquí

Johan du Toit
fuente
2

C #, 53 bytes

s=>{SendKeys.SendWait(s);return Console.ReadLine();};

Donde ses una cadena para modificar y la salida es el nuevo valor.

SendKeys.SendWait : envía las claves dadas a la aplicación activa y luego espera a que se procesen los mensajes.

o 74 bytes si no estamos en un contexto de formularios Windows Forms:

s=>{System.Windows.Forms.SendKeys.SendWait(s);return Console.ReadLine();};

demo de gif

aloisdg dice Reinstate Monica
fuente
2

Ruby, 9 19 22 84 bytes

->s{r=Readline;r.pre_input_hook=->{r.insert_text s;r.redisplay};r.readline}

Esto crea un enlace de entrada previa de Readline que inserta el texto sy luego vuelve a mostrar. Después de esto, irb se equivoca, así que asegúrese de ejecutar esto desde un archivo. Ejecutar como lambda, toma la cadena de entrada como argumento y devuelve la cadena de salida.

puts Readline.readline

Esto usa la biblioteca Readline para realizar la edición de línea. Mi respuesta anterior solo permitía retroceder espacios.

puts gets

Esto es muy, muy autoexplicativo.

Editar: me han pedido una explicación. Esto es equivalente a puts(gets). getsintroduce una cadena con un editor de línea. putslo emite.

dkudriavtsev
fuente
Encadena las llamadas al método: r.insert_text(s).redisplayy elimina lo siguiente ;. Por cierto, según entiendo nuestra política, debe mencionar que su código se ejecuta irb, porque de lo contrario necesitaría solicitarlo Readline.
manatwork
1

PHP + HTML, 26 bytes

<input value=<?=$_GET[0]?>

El navegador agrega automáticamente la etiqueta de cierre

$ _GET Usar una url http://example.com?0=inputcomo la entrada crea en un HTML<input value=input

Y esta es la salida para la entrada de cadena

<input value=input

Jörg Hülsermann
fuente
¿Debo asumir que esto funciona? ¿Quizás pueda agregar una explicación, un enlace o una animación?
Adám
@ Adám Sí, puede asumir esto. Tal vez lo mejorará y establecerá el atributo autofocuspara que tenga el cursor al principio. Otros elementos HTML que también puede editar si establece el atributocontenteditable
Jörg Hülsermann
Entrada =test></input><script>alert("Hi");//some malicious code\n</script>
Roman Gräf
@ RomanGräf Bad Boy. Sí, es mejor filtrar Javascript
Jörg Hülsermann
1

Tcl, 17

puts [gets stdin]

Los intérpretes en línea simplemente apestan para demostrarlo, luego muestro algunas imágenes de un shell de comandos de Windows:

Caso de prueba 1

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquíingrese la descripción de la imagen aquíingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí

Caso de prueba 2

ingrese la descripción de la imagen aquíingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

sergiol
fuente
¿Puedes explicar esto?
Adám
1
Puedo agregar imágenes de él ejecutándose en una línea de comandos de Windows.
sergiol
@ Adám: ¿Todavía quieres que te explique qué está haciendo el código o son suficientes las imágenes?
sergiol
Esto es suficiente.
Adám
1

AHK , 32 bytes

InputBox,s,,,,,,,,,,%1%
Send,%s%

InputBoxalmacena lo que se escribe como variable sy proporciona un mensaje inicial de la variable, 1que es el primer parámetro pasado.
Sendenvía pulsaciones de teclas a la ventana actual. En este caso, será el contenido de s.
MsgBoxera una opción pero, para jugar al golf, Sendes 2 bytes más corta.

Animación

Tostadas de ingeniero
fuente
@ Adám, leí mal esa parte. He actualizado la respuesta.
Engineer Toast
Ahora esta bien.
Adám
1

Comando de ventana inmediata de Excel VBA - 22 bytes

[a1]=inputbox(0,,[a1])

ingrese la descripción de la imagen aquí

Rohan
fuente
2
Esta es solo una solución parcial, ya que su valor inicial ("Hola") está codificado. El valor inicial debe leerse desde algún lugar (una celda o un indicador o un archivo ...) y el valor final debe colocarse en algún lugar (una celda, un cuadro de mensaje, un archivo, ...).
Adám
inputbox(0,,"Hi")guarda un byte
Felipe Nardi Batista
@ Adám Gracias. Corregido ahora, está leyendo desde la celda A1
Rohan
Creo que necesitas [a1]=inputbox(0,,[a1])o algo, de lo contrario, ¿a dónde ava? Almacenar en una variable no es un método de salida válido .
Adám
Va de donde vino la celda A1
Rohan
0

ZX Spectrum BASIC, 7 bytes

Trivial, incluido para completar ( INPUTy PRINTson tokens de un byte cada uno).

INPUT a$: PRINT a$
Radovan Garabík
fuente
1
¿Cómo se obtiene el valor inicial de a$?
Adám
@ Adám obtiene el valor inicial de a$por entrada de teclado; a$se sobreescribirá con la INPUTpalabra clave.
Shaun Bebbers
0

SmileBASIC, 138 bytes

DEF E S@L
WAIT
B=BUTTON(1)C=C-(B==4&&C)+(B>7&&C<LEN(S))I$=INKEY$()IF"\u0008"<I$THEN B=I$<"\u000E"S=SUBST$(S,C,B,I$*!B)?S?" "*C;1IF"\u0008"!=I$GOTO@L
END

Crea una función Econ 1 argumento y 0 salidas. (La salida se muestra en la consola)

Los caracteres escapados deberían ser los símbolos reales, pero no aparecerían aquí.

Control S:

Normal keys: Insert a character before the cursor.
Enter: Delete the character at the cursor.
Backspace: Submit.
D-pad left: Move cursor left.
All buttons except up, down, and left on the d-pad: Move cursor right.

Insertar / eliminar caracteres es al revés, por lo que es muy molesto de usar (pero aún debe cumplir con los requisitos).

Just some text
1             
'(press right 5 times)
Just some text
     1
'(press enter 4 times)
Just  text
     1
'(press a)
Just a text
     1
'(press right)
Just a text
      1
'(...)
Just any text
       1
'(press backspace)
12Me21
fuente
0

Intérprete de comandos de Windows, 16 bytes

set/pa=
echo %a%

Esto es muy trivial; el intérprete de comandos es trivialmente un "editor de línea".

UN
fuente
0

Commodore BASIC (C64Mini, C64 / 128, VIC-20, etc.) 179 bytes BASIC tokenizados

Esto debe escribirse en modo comercial (letras mayúsculas / minúsculas)

 0a$="Just some text":?"{SHIFT+CLR/HOME}"a$"_":fOi=0to1step0:getk$:on-(k$<>"")goS2:goS1:nE
 1?"{CTRL+N}{CLR/HOME}"a$"_  ";:return
 2ifasc(k$)<>20thena$=a$+k$:on-(asc(k$)=13)goS4:return
 3if-(len(a$))thena$=leF(a$,len(a$)-1):goS4:return
 4?"{ARROW LEFT}{ARROW LEFT}{ARROW LEFT}  ":return

Permite la edición básica de texto + eliminar + nueva línea. El tamaño máximo de a$todas las cadenas en Commodore BASIC es de 255 caracteres, por lo que cualquier cantidad mayor que eso bloqueará el programa. Encontraré una manera de hacer> 255 caracteres si es necesario.

Simulador simple de tipo em-up

Simulador simple de tipo em-up en acción

Shaun Bebbers
fuente