Utwórz prosty edytor linii


19

W: ciąg bez podziałów linii *
Zezwól użytkownikowi na edycję i przesłanie wiersza
Wyjście: zmodyfikowany ciąg (opcjonalnie z końcowym łamaniem linii)

Edytor linii musi przynajmniej pozwolić użytkownikowi na:

  1. przesuń widoczny kursor w lewo i prawo

  2. wstawianie i / lub zastępowanie znaków w pozycji kursora

  3. usuń znaki w pozycji kursora

  4. prześlij nowy ciąg, tzn. zaprzestań edycji, aby zmodyfikowany ciąg został zwrócony / wydrukowany / wyświetlony / zapisany… (bez innego tekstu)

Doceniany, ale nie wymagany:

  • wyjaśnienie twojego kodu.

  • link do strony testowej online, która może zademonstrować Twój program / funkcję

  • animowany obraz demonstrujący użycie (na przykład TIO nie pozwala na interaktywność)

Uwaga:

  • powiązania klawiszy są tylko sugestiami

  • GUI lub styl wizualny nie jest wymagany

Przykłady

Poniżej pokazano kursor _.

W: Just some text
Zezwól użytkownikowi na edycję:
Just some text_  Użytkownik naciska (lewy klawisz strzałki) dziewięć razy
Just ̲some text  Użytkownik naciska Delcztery razy
Just ̲ text  Użytkownik naciska  Użytkownik naciska :any
Just any_text Enter
Just any text

W: Remove me
Pozwól użytkownikowi na edycję:
Remove me_  Użytkownik naciska Backspacedziewięć razy
_  Użytkownik naciska Out: (pusty ciąg)Enter
 


* Aby zapobiec trywialnym rozwiązaniom edytora, musi to być dostarczone za pomocą innej metody wprowadzania niż polecenia edycji, lub musi być oddzielone od nich znakiem nowej linii lub podobnym.


Czy musimy używać tych dokładnych naciśnięć klawiszy dla operacji we / wy? Czy możemy również utworzyć plik, w którym zostanie zapisany tekst?
Rɪᴋᴇʀ 24.04.17

1
Powiązania klawiszy @Riker są tylko sugestiami . Metody wejścia i wyjścia są zgodne z wartościami domyślnymi PPCG .
Adám

Czy ciąg może zawierać znaki nowej linii? Czy można użyć nowego wiersza do „przesłania”?
Conor O'Brien

@ ConorO'Brien No; Prosty edytor linii . Tak; Redaktor musi przynajmniej pozwolić użytkownikowi na: (...) 4. przesłanie nowego ciągu
Adám

1
Byłoby miło, gdybyś podał wiersz w treści pytania, ponieważ tytuły na tej stronie nie są dokładnie specyfikacjami ...
Conor O'Brien

Odpowiedzi:


3

APL (Dyalog) , 5 bajtów

⍞←⍞⋄⍞

To jest tradfn, więc skorzystaj z niego

a
⍞←⍞⋄⍞

A następnie wywołaj go za pomocą a, po czym podasz ciąg początkowy, a następnie możesz edytować ciąg.


8

JavaScript (ES6), 15 14 bajtów

Nie rozumiem, dlaczego jest tak dużo entuzjastów!

s=>prompt(s,s)

Oszczędność bajtu dzięki Adámowi sugestii , że wyświetlam oryginalne wejście wprompt .


Spróbuj

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


1
Zapisz bajt, zastępując ""go 0lub nawet s(aby użytkownik mógł nadal zobaczyć oryginalny tekst podczas edycji - fajna funkcja).
Adám

5

Bash 4.x, 25 znaków

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

Przykładowy przebieg:

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

(Wiersz 2 powyżej był interaktywną edycją, wiersz 3 wyjściem tekstu wynikowego.)


1
Dla mnie nie działa -bash: read: -i: invalid option? manmówi, że ersdozwolone są tylko flagi.
Rɪᴋᴇʀ 24.04.17

Tak, miałem już zapytać o-ei
Adám

-izostał wprowadzony w wersji Bash 4.0 (wydanej w lutym 2009 r.) - „-i tekst Użyj TEKSTU jako tekstu początkowego dla Readline”.
manatwork

Zastanawiam się, czy kot zadziała?
Matthew Roh

catpo prostu czeka na strumień przychodzący, dla którego powłoka nie zapewni żadnej funkcji edycji. Przynajmniej nie domyślnie.
manatwork

3

Bash + Vi / Vim, 14 bajtów

echo $1>a;vi a

vijest aliasowany vimna macOS, nie wiem o innych systemach operacyjnych.


Może czegoś mi brakuje, ale czy to spełnia wymóg wyprowadzenia zmodyfikowanego ciągu?
Grayson Kent,

1
@GraysonKent możesz zapisać i wyjść, naciskając :wq!lub :x, tak myślę. OP jest nieco niejasne, co się do tego kwalifikuje.
Rɪᴋᴇʀ

3

HTML + JavaScript (ES6), 77 66 64 bajtów

HTML

<input id=t

JavaScript

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

Zaoszczędzono 10 bajtów dzięki Jörgowi Hülsermannowi i 2 bajty dzięki Lukeowi.

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

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


2
możesz usunąć przypisany typ elementu wejściowego
Jörg Hülsermann 24.04.17

Prawdopodobnie powinieneś użyć oninputzamiast tego.
Matthew Roh

@SIGSEGV Nie wydaje mi się, aby strzelał oninputpo Enternaciśnięciu
Tom

1
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)zapisuje dwa bajty.
Łukasz

3

Python 2 , 275 200 bajtów

Nie jest zwycięzcą, ale oto:

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)

Wyjaśnienie:

Działa poprzez odwrócenie danych wejściowych (za pomocą [::-1]) oraz wykluczanie i wstawianie znaków w tym odwróconym danych wejściowych, aby kursor nie musiał się poruszać. Odwraca go ponownie podczas drukowania.

Stosowanie:

Klawisz [Tab], aby przejść w prawo
[Ctrl + C], aby przejść w lewo
[Backspace], aby usunąć
[Return], aby zakończyć edycję
Każdy inny klawisz zostanie wstawiony do tekstu

Przykład:

Na przykładzie OP

W: Just some text
Just some text>
Just some> text  Użytkownik naciska Ctrl+Cpięć razy
Just > text  Użytkownik naciska Backspacecztery razy
Just any> text  Użytkownik naciska  Użytkownik naciska :any
Just any> text Enter
Just any text

Wersja edytora wbudowanego:

Jeśli chcesz, aby tekst był edytowany w wierszu, dołącz ,'\r',na końcu printinstrukcji:

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

6
+1 Bardzo miło. Pierwsza odpowiedź, która faktycznie implementuje prawdziwy edytor, a nie poleganie na wcześniejszej funkcjonalności. Zastanawiałem się nad tym, by właśnie to zrobić.
Adám

Czy nie możesz zapisać bajtów za pomocą innych klawiszy dla lewej i prawej strony?
Adám

Mogę założyć, jako znaki -i +aby to zrobić, ale redaktor nie byłaby w stanie zaakceptować te znaki następnie
Felipe Nardi Batista

Co powiesz na \ti \v?
Adám

1
To jest problem użytkownika, nie? Może Control + K?
Adám

3

C + NCURSES, 573 bajtów

#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

  • Kompiluj i uruchamiaj z wejściem Just some text.

enter image description here

enter image description here

  • Naciśnij przycisk strzałki w lewo dziewięć razy.

enter image description here

  • Naciśnij przycisk Usuń cztery razy.

enter image description here

  • Naciśnij, aa nnastępnie y.

enter image description here

  • Naciśnij, Enteraby zakończyć.

enter image description here

Szczegółowe

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

Czy nie można zastąpić KEY_*odpowiednimi liczbami całkowitymi, aby zaoszczędzić niektóre bajty?
sergiol


2

C #, 53 bajty

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

Gdzie s ciąg do zmodyfikowania, a dane wyjściowe to nowa wartość.

SendKeys.SendWait : Wysyła podane klucze do aktywnej aplikacji, a następnie czeka na przetworzenie wiadomości.

lub 74 bajty, jeśli nie jesteśmy w kontekście Windows Forms:

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

gif demo


2

Ruby, 9 19 22 84 bajtów

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

Spowoduje to utworzenie haka przed wprowadzeniem Readline, który wstawia tekst s, a następnie wyświetla ponownie. Po tym irb zostaje pomieszany, więc upewnij się, że uruchomiłeś to z pliku. Uruchom jako lambda, pobiera ciąg wejściowy jako argument i zwraca ciąg wyjściowy.

puts Readline.readline

Wykorzystuje bibliotekę Readline do edycji linii. Moja poprzednia odpowiedź dopuszczała tylko spacje.

puts gets

To jest naprawdę, bardzo oczywiste.

Edycja: Poproszono mnie o wyjaśnienie. Jest to równoważne z puts(gets). getswprowadza ciąg znaków za pomocą edytora linii. putswyprowadza to.


Połącz wywołania metod: r.insert_text(s).redisplayi usuń następujące elementy ;. BTW, jak rozumiem nasze zasady, powinieneś wspomnieć, że Twój kod działa irb, ponieważ w przeciwnym razie będziesz musiał wymagać Readlinew swoim kodzie.
manatwork

1

PHP + HTML, 26 bajtów

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

Przeglądarka automatycznie dodaje znacznik zamykający

$ _GET Używanie adresu URL takiego http://example.com?0=inputjak Input Tworzy w HTML<input value=input

I to jest dane wyjściowe dla ciągu wejściowego

<input value=input


Czy powinienem założyć, że to działa? Może możesz dodać wyjaśnienie, link lub animację?
Adám

@ Adám Tak, możesz to założyć Być może poprawisz to i ustawisz atrybut tak, autofocusaby kursor znajdował się na początku. Inne elementy HTML, które możesz edytować, jeśli ustawisz atrybutcontenteditable
Jörg Hülsermann

Dane wejściowe =test></input><script>alert("Hi");//some malicious code\n</script>
Roman Gräf

@ RomanGräf Bad Boy. Tak, lepiej filtrować Javascript
Jörg Hülsermann 24.04.17

1

Tcl, 17

puts [gets stdin]

Tłumacze online są do niczego, aby to zademonstrować, a następnie prezentuję niektóre obrazy z powłoki poleceń Windows:

Przypadek testowy 1

enter image description hereenter image description hereenter image description hereenter image description hereenter image description here

Przypadek testowy 2

enter image description hereenter image description here enter image description here


Czy możesz to wyjaśnić?
Adám

1
Mogę dodać jego obrazy działające w wierszu poleceń systemu Windows.
sergiol

@ Adám: Czy nadal chcesz, abym wyjaśnił, co robi kod, czy też wystarczają obrazy?
sergiol

Wystarczy.
Adám

1

AHK , 32 bajty

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

InputBoxprzechowuje wszystko, co jest wpisane jako zmienna si wyświetla monit o podanie zmiennej, 1która jest pierwszym przekazanym parametrem.
Sendwysyła naciśnięcia klawiszy do bieżącego okna. W tym przypadku będzie to zawartość s.
MsgBoxbyła opcją, ale dla golfa Sendjest o 2 bajty krótsza.

Animation


@ Adám Źle odczytałem tę część. Zaktualizowałem odpowiedź.
Inżynier Toast

Teraz jest dobrze.
Adám

1

Polecenie natychmiastowego okna Excel VBA - 22 bajty

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

enter image description here


2
Jest to tylko częściowe rozwiązanie, ponieważ początkowa wartość („Cześć”) jest zakodowana na stałe. Wartość początkową należy skądś odczytać (komórkę, monit lub plik ...), a wartość końcową należy gdzieś umieścić (komórkę, skrzynkę wiadomości, plik, ...).
Adám

inputbox(0,,"Hi")zapisuje bajt
Felipe Nardi Batista

@ Adám Thanks. Naprawiono teraz odczyt z komórki A1
Rohan

Myślę, że potrzebujesz [a1]=inputbox(0,,[a1])czy coś takiego, gdzie indziej a? Przechowywanie w zmiennej nie jest prawidłową metodą wyjściową .
Adám

Idzie tam, skąd pochodzi z komórki A1
Rohan

0

ZX Spectrum BASIC, 7 bajtów

Trywialne, uwzględnione dla kompletności ( INPUTi PRINTsą jednobajtowe tokeny każdy).

INPUT a$: PRINT a$

1
Jak otrzymuje wartość początkową a$?
Adám

@ Adám pobiera wartość początkową z a$klawiatury; a$zostanie zastąpione INPUTsłowem kluczowym.
Shaun Bebbers

0

SmileBASIC, 138 bajtów

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

Tworzy funkcję Ez 1 argumentem i 0 wyjściami. (Dane wyjściowe są wyświetlane w konsoli)

Znaki ucieczki powinny być rzeczywistymi symbolami, ale nie pojawią się tutaj.

Sterownica:

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.

Wstawianie / usuwanie znaków odbywa się wstecz, więc korzystanie z nich jest bardzo denerwujące (ale nadal powinno spełniać wymagania).

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

Interpreter poleceń systemu Windows, 16 bajtów

set/pa=
echo %a%

To jest bardzo trywialne; interpreter poleceń jest trywialnie „edytorem linii”.


0

Commodore BASIC (C64Mini, C64 / 128, VIC-20 itd ...) 179 tokenizowanych bajtów BASIC

Należy to wpisać w trybie biznesowym (wielkie / małe litery)

 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

Umożliwia podstawową edycję tekstu + usuwanie + nowy wiersz. Maksymalny rozmiar a$wszystkich łańcuchów w Commodore BASIC wynosi 255 znaków, więc więcej niż to spowoduje awarię programu. Znajdę sposób na zrobienie> 255 znaków, jeśli będzie to konieczne.

Simple type-em-up simulator

Simple type-em-up simulator in action

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.