Crea un semplice editor di linee


19

In: una stringa senza interruzioni di riga *
Consenti all'utente di modificare e inviare la riga
Out: la stringa modificata (facoltativamente con un'interruzione di riga finale)

L'editor di riga deve almeno consentire all'utente di:

  1. sposta un cursore visibile a sinistra e a destra

  2. inserire e / o sovrascrivere i caratteri nella posizione del cursore

  3. rimuove i caratteri nella posizione del cursore

  4. invia la nuova stringa, ovvero interrompi la modifica per restituire / stampare / visualizzare / salvare la stringa modificata ... (senza altro testo)

Apprezzato, ma non richiesto:

  • spiegazione del tuo codice.

  • collegamento a un sito di test online in grado di dimostrare il tuo programma / funzione

  • un'immagine animata che dimostra l'utilizzo (TIO, ad esempio, non consente l'interattività)

Nota:

  • le combinazioni di tasti sono solo suggerimenti

  • Non è richiesta la GUI o lo stile visivo

Esempi

Di seguito, il cursore è illustrato con _.

In: Just some text
Consenti all'utente di modificare: L'
 Just some text_  utente preme ←(tasto freccia sinistra) nove volte L'
 Just ̲some text  utente preme Delquattro volte L'
 Just ̲ text  utente preme L'  utente preme Out:any
 Just any_text Enter
Just any text

In: Remove me
Consenti all'utente di modificare: L'
 Remove me_  utente preme Backspacenove volte L'
 _  utente preme Out: (stringa vuota)Enter
 


* Per evitare banali soluzioni editor, questo deve essere fornito tramite un metodo di input diverso rispetto ai comandi di modifica, oppure deve essere separato da essi da una nuova riga o simile.


Dobbiamo usare quei tasti premuti per l'I / O? Inoltre, possiamo creare un file in cui salvare il testo?
— Rɪᴋᴇʀ

1
Le associazioni di tasti @Riker sono solo suggerimenti . I metodi di input e output seguono le impostazioni predefinite PPCG .
— Adám,

La stringa può contenere newline? E una newline può essere usata per "inviare"?
— Conor O'Brien,

@ ConorO'Brien No; Editor di linee semplice . Sì; L'editore deve almeno consentire all'utente di: (...) 4. inviare la nuova stringa
— Adám

1
Sarebbe bello se hai specificato la riga nel corpo reale della domanda, poiché i titoli su questo sito non sono esattamente le specifiche ...
— Conor O'Brien

Risposte:


3

APL (Dyalog) , 5 byte

⍞←⍞⋄⍞

Questo è un tradfn, quindi per usarlo, fallo

∇a
⍞←⍞⋄⍞
∇

Quindi chiamalo utilizzando a, dopo di che fornisci la stringa iniziale e quindi puoi modificare la stringa.


8

JavaScript (ES6), 15 14 byte

Non capisco perché questo ottenga così tanti voti!

s=>prompt(s,s)

Salvataggio di un byte grazie al suggerimento di Adám di visualizzare l'input originale in prompt.


Provalo

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


1
Salvare un byte sostituendolo ""con 0o anche s(in questo modo l'utente può ancora vedere il testo originale durante la modifica - una funzionalità accurata).
— Adám,

5

Bash 4.x, 25 caratteri

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

Esecuzione di esempio:

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

(La riga 2 sopra era l'editing interattivo, la riga 3 l'output del testo risultante.)


1
Per me non funziona -bash: read: -i: invalid option? mandice solo erssono ammessi flag.
— Rɪᴋᴇʀ

Sì, stavo per chiedere-ei
— Adám il

-iè stato introdotto in Bash 4.0 (rilasciato nel febbraio 2009) - "-i testo Usa TEXT come testo iniziale per Readline".
— arte

Mi chiedo, funzionerebbe un gatto?
— Matthew Roh,

catattende solo il flusso in entrata, per il quale la shell non fornirà alcuna funzionalità di modifica. Almeno non di default.
— arte

3

Bash + Vi / Vim, 14 byte

echo $1>a;vi a

viè alias vimsu macOS, non conosco altri sistemi operativi.


Forse mi manca qualcosa, ma questo soddisfa il requisito di produrre la stringa modificata?
— Grayson Kent,

1
@GraysonKent puoi salvare ed uscire colpendo :wq!o :x, quindi penso di si. OP non è chiaro su cosa si qualifichi come quello.
— Rɪᴋᴇʀ

3

HTML + JavaScript (ES6), 77 66 64 byte

HTML

<input id=t

JavaScript

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

Salvataggio di 10 byte grazie a Jörg Hülsermann e 2 byte grazie a Luke.

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

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


2
puoi rimuovere l'attributo type per l'elemento Input
— Jörg Hülsermann

Probabilmente dovresti usare oninputinvece.
— Matthew Roh,

@SIGSEGV Non credo che i oninputfuochi vengano Enterpremuti
— Tom,

1
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)salva due byte.
— Luca

3

Python 2 , 275 200 byte

Non un vincitore, ma eccolo qui:

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)

Spiegazione:

Funziona invertendo l'input (con [::-1]), escludendo e inserendo caratteri in quell'input invertito in modo che il cursore non debba spostarsi. Lo inverte di nuovo durante la stampa.

Uso:

Tasto [Tab] per spostare a destra
[Ctrl + C] per spostare a sinistra
[Backspace] per cancellare
[Return] per terminare la modifica
Qualsiasi altro tasto verrà inserito nel testo

Esempio:

Usando l'esempio di OP

In: L' Just some text
 Just some text>
 Just some> text  utente preme Ctrl+Ccinque volte L'
 Just > text  utente preme Backspacequattro volte L'
 Just any> text  utente preme L'  utente preme Out:any
 Just any> text Enter
Just any text

Versione dell'editor in linea:

Se desideri che il testo venga modificato in linea, aggiungi ,'\r',alla fine printdell'istruzione:

def p(a):print''.join(a)[::-1],'\r',

6
+1 Molto bello. Prima risposta che implementa effettivamente un vero editor, invece di affidarsi a funzionalità preesistenti. Stavo pensando di pubblicare un'altra sfida per fare proprio questo.
— Adám,

Non puoi salvare byte usando altri tasti per sinistra e destra?
— Adám,

Potrei assumere i personaggi come -e +per farlo, ma l'editore non sarebbe in grado di accettarli allora
— Felipe Nardi Batista,

Che ne dici di \te \v?
— Adám,

1
Questo è il problema dell'utente, no? Control + K, forse?
— Adám,

3

C + NCURSES, 573 byte

#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;}

Test

  • Compila ed esegui con input Just some text.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

  • Premi il pulsante freccia sinistra nove volte.

inserisci qui la descrizione dell'immagine

  • Premi il pulsante Elimina quattro volte.

inserisci qui la descrizione dell'immagine

  • Premere aquindi nquindi y.

inserisci qui la descrizione dell'immagine

  • Premere Enterper terminare.

inserisci qui la descrizione dell'immagine

dettagliata

#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;
}

Non è possibile sostituire KEY_*con i rispettivi numeri interi per salvare alcuni byte?
— sergiol


2

C #, 53 byte

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

Dove sè una stringa da modificare e l'output è il nuovo valore.

SendKeys.SendWait : invia le chiavi fornite all'applicazione attiva, quindi attende l'elaborazione dei messaggi.

o 74 byte se non ci troviamo in un contesto Windows Form:

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

demo gif


2

Rubino, 9 19 22 84 byte

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

Questo crea un hook di pre input di Readline che inserisce il testo e poi visualizza di nuovo. Dopo questo, irb viene incasinato, quindi assicurati di eseguirlo da un file. Eseguito come lambda, accetta la stringa di input come argomento e restituisce la stringa di output.

puts Readline.readline

Questo utilizza la libreria Readline per eseguire la modifica delle linee. La mia risposta precedente consentiva solo backspaces.

puts gets

Questo è davvero, davvero autoesplicativo.

Modifica: mi è stata chiesta una spiegazione. Questo equivale a puts(gets). getsimmette una stringa con un editor di linee. putslo emette.


Incatenare il metodo chiama: r.insert_text(s).redisplaye rimuovere quanto segue ;. A proposito, come ho capito la nostra politica, dovresti menzionare che il tuo codice viene eseguito irb, perché altrimenti dovresti richiedere Readlinenel tuo codice.
— arte

1

PHP + HTML, 26 byte

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

Il browser aggiunge automaticamente il tag di chiusura

$ _GET Usando un URL come http://example.com?0=inputInput Crea in un HTML<input value=input

E questo è l'output per l'input della stringa

<input value=input


Dovrei supporre che funzioni? Forse puoi aggiungere una spiegazione, un link o un'animazione?
— Adám,

@Adám Sì, puoi supporre che forse migliorerai e imposti l'attributo autofocusper avere il cursore all'inizio. Altri elementi HTML che puoi anche modificare se imposti l'attributocontenteditable
— Jörg Hülsermann

Input =test></input><script>alert("Hi");//some malicious code\n</script>
— Roman Gräf

@ RomanGräf Bad Boy. Sì, è meglio filtrare Javascript
— Jörg Hülsermann

1

Tcl, 17

puts [gets stdin]

Gli interpreti online fanno semplicemente schifo per dimostrarlo, quindi mostro alcune immagini da una shell dei comandi di Windows:

Caso di prova 1

inserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagine

Caso di prova 2

inserisci qui la descrizione dell'immagineinserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine


Puoi spiegarlo?
— Adám,

1
Posso aggiungere immagini di esso in esecuzione su una riga di comando di Windows.
— sergiol

@Adám: Vuoi ancora che ti spieghi cosa sta facendo il codice o sono sufficienti le immagini?
— sergiol

È abbastanza.
— Adám,

1

AHK , 32 byte

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

InputBoxmemorizza tutto ciò che viene digitato come variabile se fornisce un prompt iniziale della variabile 1che è il primo parametro passato.
Sendinvia i tasti alla finestra corrente. In questo caso, sarà il contenuto di s.
MsgBoxera un'opzione ma, per il golf, Sendè più breve di 2 byte.

Animazione


@Adám Ho letto male quella parte. Ho aggiornato la risposta.
— Ingegnere Toast,

Adesso va bene
— Adám,

1

Comando finestra immediata VBA di Excel - 22 byte

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

inserisci qui la descrizione dell'immagine


2
Questa è solo una soluzione parziale, poiché il valore iniziale ("Ciao") è hardcoded. Il valore iniziale deve essere letto da qualche parte (una cella o un prompt o un file ...) e il valore finale deve essere inserito da qualche parte (una cella, una finestra di messaggio, un file, ...).
— Adám,

inputbox(0,,"Hi")salva un byte
— Felipe Nardi Batista,

@Adám Grazie. Risolto il problema con la lettura dalla cella A1
— Rohan,

Penso che tu abbia bisogno [a1]=inputbox(0,,[a1])o qualcosa, altrimenti, dove ava? La memorizzazione in una variabile non è un metodo di output valido .
— Adám,

Va da dove proviene dalla cella A1
— Rohan,

0

ZX Spectrum BASIC, 7 byte

Trivial, incluso per completezza ( INPUTe PRINTsono token di un byte ciascuno).

INPUT a$: PRINT a$

1
Come ottiene il valore iniziale di a$?
— Adám,

@ Adám ottiene il valore iniziale di a$tramite input da tastiera; a$verrà sovrascritto con la INPUTparola chiave.
— Shaun Bebbers,

0

SmileBASIC, 138 byte

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 funzione Econ 1 argomento e 0 output. (L'output viene visualizzato nella console)

I personaggi fuggiti dovrebbero essere i simboli reali, ma non dovrebbero apparire qui.

controlli:

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.

L'inserimento / eliminazione di caratteri è all'indietro, quindi è molto fastidioso da usare (ma dovrebbe comunque soddisfare i requisiti).

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)

0

Interprete dei comandi di Windows, 16 byte

set/pa=
echo %a%

Questo è molto banale; l'interprete dei comandi è banalmente un "line editor".


0

Commodore BASIC (C64Mini, C64 / 128, VIC-20 ecc ...) 179 byte BASIC tokenizzati

Questo dovrebbe essere digitato in modalità business (caratteri maiuscoli / minuscoli)

 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

Consente la modifica di base del testo + elimina + nuova riga. La dimensione massima di a$come tutte le stringhe in Commodore BASIC è di 255 caratteri, quindi non solo il programma andrà in crash. Troverò un modo per fare> 255 caratteri se è necessario.

Simulatore di tipo em-up semplice

Simulatore di tipo em-up semplice in azione

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.