Создайте простой редактор строк


19

In: строка без разрывов строки *
Разрешить пользователю редактировать и отправлять строку
Out: измененную строку (опционально с завершающим переводом строки)

Редактор строк должен как минимум позволить пользователю:

  1. переместить видимый курсор влево и вправо

  2. вставлять и / или перезаписывать символы в позиции курсора

  3. удалить символы в позиции курсора

  4. отправить новую строку, т.е. прекратить редактирование, заставить измененную строку вернуть / распечатать / отобразить / сохранить… (без другого текста)

Ценится, но не обязательно:

  • объяснение вашего кода.

  • ссылка на сайт онлайн-тестирования, который может продемонстрировать вашу программу / функцию

  • анимированное изображение, демонстрирующее использование (например, TIO не допускает интерактивность)

Замечания:

  • привязки клавиш только предложения

  • GUI или визуальный стиль не требуется

Примеры

Далее курсор обозначен с помощью _.

In: Just some text
разрешить пользователю редактировать:
Just some text_  пользователь нажимает (левая клавиша со стрелкой) девять раз
Just ̲some text  пользователь нажимает Delчетыре раза
Just ̲ text  пользователь нажимает  пользователь нажимает Out:any
Just any_text Enter
Just any text

In: Remove me
разрешить пользователю редактирование:
Remove me_  пользователь нажимает Backspaceдевять раз.
_  Пользователь нажимает Out: (пустая строка)Enter
 


* Чтобы избежать тривиальных решений редактора, это должно быть либо предоставлено с помощью другого метода ввода, чем команды редактирования, или должно быть отделено от них новой строкой или аналогичным.


Нужно ли использовать эти точные нажатия клавиш для ввода-вывода? Кроме того, мы можем создать файл для сохранения текста?
R '24

1
Привязка клавиш @Riker - это только предложения . Методы ввода и вывода соответствуют настройкам PPCG по умолчанию .
Адам

Может ли строка содержать символы новой строки? И можно ли использовать новую строку для «отправки»?
Конор О'Брайен

@ ConorO'Brien Нет; Простой редактор строк . Да; Редактор должен как минимум разрешить пользователю: (...) 4. отправить новую строку
Adám

1
Было бы неплохо, если бы вы указали строку в фактической части вопроса, так как заголовки на этом сайте не совсем
Конор О'Брайен,

Ответы:


3

APL (Dyalog) , 5 байтов

⍞←⍞⋄⍞

Это tradfn, поэтому, чтобы использовать его, сделайте

a
⍞←⍞⋄⍞

И затем вызвать его с помощью a, после чего вы вводите начальную строку, а затем вы можете редактировать строку.


8

JavaScript (ES6), 15 14 байт

Я не понимаю, почему так много голосов!

s=>prompt(s,s)

Сохраненный байт благодаря предложению Адама , чтобы я отобразил исходный ввод в prompt.


Попытайся

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


1
Сохранить байт, заменяя ""с 0или даже s(так что пользователь все еще может увидеть оригинальный текст , а редактирование - аккуратный функция).
Адам

5

Bash 4.x, 25 символов

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

Образец прогона:

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

(Строка 2 выше - интерактивное редактирование, строка 3 - вывод полученного текста.)


1
У меня не работает -bash: read: -i: invalid option? manговорит только ersразрешенные флаги.
R '24

Да, я собирался спросить об этом-ei
Адам

-iбыл представлен в Bash 4.0 (выпущен в феврале 2009 г.) - «-i text Использовать TEXT в качестве исходного текста для Readline».
manatwork

Мне интересно, сработает ли кошка?
Мэтью Ро,

catпросто ожидает входящий поток, для которого оболочка не будет предоставлять никаких функций редактирования. По крайней мере, не по умолчанию.
manatwork

3

Bash + Vi / Vim, 14 байтов

echo $1>a;vi a

vivimна MacOS есть псевдоним , я не знаю о других ОС.


Может быть, я что-то упустил, но соответствует ли это требованию вывода измененной строки?
Грейсон Кент

1
@GraysonKent вы можете сохранить и выйти, нажав :wq!или :x, так что я так думаю. ОП немного неясно, что можно отнести к этому.
Rɪᴋᴇʀ

3

HTML + JavaScript (ES6), 77 66 64 байта

HTML

<input id=t

JavaScript

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

Сэкономили 10 байт благодаря Йоргу Хюльсерманну и 2 байта благодаря Люку.

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

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


2
Вы можете удалить атрибут типа для входного элемента
Йорг Хюльсерманн

Вы, вероятно, должны использовать oninputвместо этого.
Мэтью Ро

@SIGSEGV Я не думаю, что oninputсрабатывает при Enterнажатии
Том

1
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)сохраняет два байта.
Лука

3

Python 2 , 275 200 байт

Не победитель, но вот он:

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)

Объяснение:

Он работает путем реверсирования ввода (с помощью [::-1]), исключения и вставки символов в этот инвертированный ввод, чтобы курсор не перемещался. Снова переворачивает при печати.

Использование:

Клавиша [Tab] для перемещения вправо
[Ctrl + C] для перемещения влево
[Backspace] для стирания
[Return] для завершения редактирования
Любая другая клавиша, будет вставлена ​​в текст

Пример:

Используя пример OP

In: Just some text
Just some text>
Just some> text  пользователь нажимает Ctrl+Cпять раз
Just > text  пользователь нажимает Backspaceчетыре раза
Just any> text  пользователь нажимает  пользователь нажимает Out:any
Just any> text Enter
Just any text

Версия встроенного редактора:

Если вы хотите, чтобы текст редактировался внутри строки, добавьте ,'\r',в конце printоператора:

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

6
+1 Очень мило. Первый ответ, который на самом деле реализует настоящий редактор, а не полагается на уже существующую функциональность. Я подумывал опубликовать еще одну задачу, чтобы сделать именно это.
Адам

Вы не можете сохранить байты, используя другие клавиши для левой и правой?
Адам

Я мог бы принимать символы как -и +для этого, но редактор не смог бы принять эти символы тогда
Фелипе Нарди Батиста

Как насчет \tа \v?
Адам

1
Это проблема пользователя, нет? Control + K, может быть?
Адам

3

C + NCURSES, 573 байта

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

Тестовое задание

  • Скомпилируйте и запустите с вводом Just some text.

введите описание изображения здесь

введите описание изображения здесь

  • Нажмите кнопку со стрелкой влево девять раз.

введите описание изображения здесь

  • Нажмите кнопку Удалить четыре раза.

введите описание изображения здесь

  • Нажмите aзатем, nзатем y.

введите описание изображения здесь

  • Нажмите, Enterчтобы прекратить.

введите описание изображения здесь

Детальнее

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

Вы не можете заменить KEY_*на соответствующие целые числа, чтобы сохранить несколько байтов?
sergiol


2

C #, 53 байта

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

Где sстрока, которую нужно изменить, и вывод нового значения.

SendKeys.SendWait : отправляет данные ключи активному приложению, а затем ожидает обработки сообщений.

или 74 байта, если мы не в контексте Windows Forms:

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

GIF демо


2

Рубин, 9 19 22 84 байта

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

Это создает хук предварительного ввода Readline, который вставляет текст s, а затем снова отображается. После этого irb испортится, поэтому обязательно запустите его из файла. Запускается как лямбда, он принимает входную строку в качестве аргумента и возвращает выходную строку.

puts Readline.readline

Это использует библиотеку Readline для выполнения редактирования строки. Мой предыдущий ответ позволял только пробелы.

puts gets

Это действительно очень понятно.

Изменить: меня попросили объяснить. Это эквивалентно puts(gets). getsвводит строку с помощью редактора строк. putsвыводит это.


Цепочка вызовов метода: r.insert_text(s).redisplayи удалите следующее ;. Кстати, как я понимаю нашу политику, вы должны упомянуть, что ваш код работает irb, потому что в противном случае вам потребуется его использование Readline.
manatwork

1

PHP + HTML, 26 байт

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

Браузер автоматически добавляет закрывающий тег

$ _GET Использование URL-адреса, подобного тому, http://example.com?0=inputкак Input создает в HTML<input value=input

И это выход для ввода строки

<input value=input


Должен ли я считать, что это работает? Может быть, вы можете добавить объяснение, или ссылку, или анимацию?
Адам

@ Adám Да, вы можете предположить, что это может быть, вы улучшите его и установите атрибут, autofocusчтобы курсор находился в начале. Другие элементы HTML, которые вы также можете редактировать, если установите атрибутcontenteditable
Jörg Hülsermann,

Вход =test></input><script>alert("Hi");//some malicious code\n</script>
Роман Грэф

@ RomanGräf Bad Boy. Да, лучше отфильтровать Javascript
Йорг Хюльсерманн

1

Tcl, 17

puts [gets stdin]

Онлайн-переводчики просто отстой, чтобы продемонстрировать это, а затем я демонстрирую некоторые изображения из командной оболочки Windows:

Тестовый пример 1

введите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесь

Контрольный пример 2

введите описание изображения здесьвведите описание изображения здесь введите описание изображения здесь


Вы можете объяснить это?
Адам

1
Я могу добавить образы, запущенные в командной строке Windows.
sergiol

@ Adám: Вы все еще хотите, чтобы я объяснил, что делает код, или изображений достаточно?
sergiol

Достаточно.
Адам

1

AHK , 32 байта

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

InputBoxсохраняет все, что введено в качестве переменной, sи выдает начальную подсказку для переменной, 1которая является первым переданным параметром.
Sendотправляет нажатия клавиш в текущее окно. В этом случае это будет содержимое s.
MsgBoxбыл вариант, но для игры в гольф на Send2 байта короче.

Анимация


@ Adám Я неправильно понял эту часть. Я обновил ответ.
Тост инженера

Теперь это хорошо.
адам

1

Команда непосредственного окна Excel VBA - 22 байта

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

введите описание изображения здесь


2
Это только частичное решение, поскольку ваше начальное значение («Привет») жестко запрограммировано. Начальное значение должно быть прочитано откуда-то (ячейка, приглашение или файл ...), а конечное значение должно быть где-то помещено (ячейка, окно сообщения, файл, ...).
Адам

inputbox(0,,"Hi")сохраняет байт
Фелипе Нарди Батиста,

@ Adám Спасибо. Исправлено: теперь он читает из ячейки A1
Рохан,

Я думаю, что вам нужно [a1]=inputbox(0,,[a1])или что-то, в противном случае, куда aидти? Хранение в переменной не является допустимым методом вывода .
адам

Он идет туда, откуда пришел из камеры А1
Рохан,

0

ZX Spectrum BASIC, 7 байтов

Тривиально, включено для полноты ( INPUTи PRINTкаждый токен по одному байту).

INPUT a$: PRINT a$

1
Как это получить начальное значение a$?
Адам

@ Adám получает начальное значение a$с клавиатуры; a$будет INPUTперезаписано ключевым словом.
Шон Бебберс

0

SmileBASIC, 138 байт

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

Создает функцию E с 1 аргументом и 0 выходами. (Вывод отображается в консоли)

Экранированные символы должны быть реальными символами, но они не будут отображаться здесь.

Управление:

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.

Вставка / удаление символов - это задом наперед, поэтому это очень раздражает в использовании (но все равно должно соответствовать требованиям).

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

Интерпретатор команд Windows, 16 байт

set/pa=
echo %a%

Это очень тривиально; интерпретатор команд - это тривиальный редактор строк.


0

Commodore BASIC (C64Mini, C64 / 128, VIC-20 и т. Д.) 179 токенов BASIC

Это должно быть набрано в бизнес-режиме (прописные / строчные буквы)

 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

Позволяет базовое редактирование текста + удаление + новая строка. Максимальный размер a$как и всех строк в Commodore BASIC составляет 255 символов, так что больше, чем это может привести к сбою программы. Я найду способ сделать> 255 символов, если это необходимо.

Простой симулятор

Простой симулятор типа в действии

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.