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.