Tạo một trình soạn thảo dòng đơn giản


19

Trong: một chuỗi không ngắt dòng *
Cho phép người dùng chỉnh sửa và gửi dòng
Out: chuỗi đã sửa đổi (tùy chọn có ngắt dòng)

Trình chỉnh sửa dòng tối thiểu phải cho phép người dùng:

  1. di chuyển một con trỏ hiển thị sang trái và phải

  2. chèn và / hoặc ghi đè các ký tự ở vị trí con trỏ

  3. xóa các ký tự ở vị trí con trỏ

  4. gửi chuỗi mới, tức là ngừng chỉnh sửa khiến chuỗi đã sửa đổi được trả về / in / hiển thị / lưu lại (không có văn bản nào khác)

Đánh giá cao, nhưng không bắt buộc:

  • giải thích về mã của bạn.

  • liên kết đến một trang web thử nghiệm trực tuyến có thể chứng minh chương trình / chức năng của bạn

  • một hình ảnh hoạt hình thể hiện việc sử dụng (ví dụ TIO, không cho phép tương tác)

Chú thích:

  • ràng buộc chính chỉ là đề xuất

  • GUI hoặc kiểu dáng hình ảnh là không cần thiết

Ví dụ

Sau đây, con trỏ được minh họa bằng _.

Trong: Just some text
Cho phép người dùng chỉnh sửa:
Just some text_  Người dùng nhấn (phím mũi tên trái) chín lần
Just ̲some text  Người dùng nhấn Delbốn lần
Just ̲ text  Người dùng nhấn  Người dùng nhấn Ra:any
Just any_text Enter
Just any text

Trong: Remove me
Cho phép người dùng chỉnh sửa:
Remove me_  Người dùng nhấn Backspacechín lần
_  Người dùng nhấn Out: (chuỗi trống)Enter
 


* Để ngăn các giải pháp biên tập tầm thường, điều này phải được cung cấp thông qua một phương thức nhập khác với các lệnh chỉnh sửa hoặc phải được phân tách khỏi chúng bằng một dòng mới hoặc tương tự.


Chúng ta có phải sử dụng những phím bấm chính xác cho i / o không? Ngoài ra, chúng ta có thể tạo một tập tin để lưu văn bản không?
Rɪᴋᴇʀ

1
@Riker ràng buộc khóa chỉ là đề xuất . Phương thức nhập và xuất theo mặc định PPCG .
Adám

Chuỗi có thể chứa dòng mới? Và một dòng mới có thể được sử dụng để "gửi"?
Conor O'Brien

@ ConorO'Brien Không; Trình chỉnh sửa dòng đơn giản . Vâng; Trình chỉnh sửa tối thiểu phải cho phép người dùng: (...) 4. gửi chuỗi mới
Adám

1
Sẽ thật tuyệt nếu bạn chỉ định dòng trong phần thực tế của câu hỏi, vì các tiêu đề trên trang web này không chính xác thông số kỹ thuật ...
Conor O'Brien

Câu trả lời:


3

APL (Dyalog) , 5 byte

⍞←⍞⋄⍞

Đây là một tradfn, vì vậy để sử dụng nó, hãy làm

a
⍞←⍞⋄⍞

Và sau đó gọi nó bằng cách sử dụng a, sau đó bạn cung cấp chuỗi bắt đầu, và sau đó bạn có thể chỉnh sửa chuỗi.


8

JavaScript (ES6), 15 14 byte

Tôi không hiểu tại sao điều này lại nhận được rất nhiều sự ủng hộ!

s=>prompt(s,s)

Đã lưu một byte nhờ đề xuất của Adám rằng tôi hiển thị đầu vào ban đầu trong prompt.


Thử nó

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


1
Lưu một byte bằng cách thay thế ""bằng 0hoặc thậm chí s(để người dùng vẫn có thể thấy văn bản gốc trong khi chỉnh sửa - một tính năng gọn gàng).
Adám

5

Bash 4.x, 25 ký tự

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

Chạy mẫu:

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

(Dòng 2 ở trên là phần chỉnh sửa tương tác, dòng 3 là đầu ra của văn bản kết quả.)


1
Nó không hoạt động, đối với tôi , -bash: read: -i: invalid option? mannói chỉ ersđược phép cờ.
Rɪᴋᴇʀ

Vâng, tôi đã định hỏi về-ei
Adám

-iđã được giới thiệu trong Bash 4.0 (phát hành vào tháng 2 năm 2009) - Văn bản -i Sử dụng văn bản gốc làm văn bản ban đầu cho Readline.
manatwork

Tôi đang tự hỏi, con mèo sẽ làm việc?
Matthew Roh

catchỉ chờ luồng đến, mà shell sẽ không cung cấp chức năng chỉnh sửa. Ít nhất là không theo mặc định.
manatwork

3

Bash + Vi / Vim, 14 byte

echo $1>a;vi a

viđược đặt bí danh vimtrên macOS, tôi không biết về các hệ điều hành khác.


Có thể tôi đang thiếu một cái gì đó, nhưng điều này có đáp ứng yêu cầu xuất ra chuỗi đã sửa đổi không?
Grayson Kent

1
@GraysonKent bạn có thể lưu và thoát bằng cách nhấn :wq!hoặc :x, vì vậy tôi nghĩ vậy. OP là một chút không rõ ràng về những gì đủ điều kiện như vậy.
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;

Đã lưu 10 byte nhờ vào Jörg Hülsermann và 2 byte nhờ Luke.

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

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


2
bạn có thể xóa thuộc tính loại cho Phần tử đầu vào
Jörg Hülsermann

Bạn có lẽ nên sử dụng oninputthay thế.
Matthew Roh

@SIGSEGV Tôi không nghĩ oninputhỏa hoạn khi Enterbị ép
Tom

1
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)lưu hai byte.
Lu-ca

3

Python 2 , 275 200 byte

Không phải là một người chiến thắng, nhưng đây là:

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)

Giải trình:

Nó hoạt động bằng cách đảo ngược đầu vào (với [::-1]), và loại trừ và chèn các ký tự trong đầu vào đảo ngược đó để con trỏ không phải di chuyển. Đảo ngược nó một lần nữa khi in.

Sử dụng:

Phím [Tab] để di chuyển sang phải
[Ctrl + C] để di chuyển sang trái
[Backspace] để xóa
[Trở về] để hoàn tất chỉnh sửa
Bất kỳ phím nào khác, sẽ được chèn vào văn bản

Thí dụ:

Sử dụng ví dụ của OP

Trong: Just some text
Just some text>
Just some> text  Người dùng nhấn Ctrl+Cnăm lần
Just > text  Người dùng nhấn Backspacebốn lần
Just any> text  Người dùng nhấn  Người dùng nhấn Ra:any
Just any> text Enter
Just any text

Phiên bản biên tập nội tuyến:

Nếu bạn muốn văn bản được chỉnh sửa nội tuyến, hãy thêm ,'\r',vào cuối printcâu lệnh:

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

6
+1 Rất đẹp. Câu trả lời đầu tiên thực sự thực hiện một trình soạn thảo thực sự, trái ngược với việc dựa vào chức năng có sẵn. Tôi đã xem xét đăng một thách thức khác để làm điều này.
Adám

Bạn không thể lưu byte bằng cách sử dụng các phím khác cho trái và phải?
Adám

Tôi có thể giả sử các nhân vật -+làm như vậy, nhưng biên tập viên sẽ không thể chấp nhận các nhân vật đó sau đó
Felipe Nardi Batista

Làm thế nào về \t\v?
Adám

1
Đó là vấn đề của người dùng, phải không? Kiểm soát + K, có thể?
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;}

Kiểm tra

  • Biên dịch và chạy với đầu vào Just some text.

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

  • Nhấn nút mũi tên trái chín lần.

nhập mô tả hình ảnh ở đây

  • Nhấn nút Xóa bốn lần.

nhập mô tả hình ảnh ở đây

  • Nhấn asau đó nsau đó y.

nhập mô tả hình ảnh ở đây

  • Nhấn Enterđể chấm dứt.

nhập mô tả hình ảnh ở đây

Chi tiết

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

Bạn không thể thay thế KEY_*bằng các số nguyên tương ứng để lưu một số byte?
sergiol


2

C #, 53 byte

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

Trường hợp smột chuỗi để sửa đổi và đầu ra là giá trị mới.

SendKeys.SendWait : Gửi các khóa đã cho đến ứng dụng đang hoạt động, sau đó chờ các tin nhắn được xử lý.

hoặc 74 byte nếu chúng ta không ở trong bối cảnh Windows Forms:

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

bản demo gif


2

Ruby, 9 19 22 84 byte

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

Điều này tạo ra một hook đầu vào Preline chèn các văn bản và sau đó hiển thị lại. Sau này, irb bị rối, vì vậy hãy đảm bảo chạy nó từ một tệp. Chạy như một lambda, nó lấy chuỗi đầu vào làm đối số và trả về chuỗi đầu ra.

puts Readline.readline

Điều này sử dụng thư viện Readline để thực hiện chỉnh sửa dòng. Câu trả lời trước của tôi chỉ cho phép không gian phía sau.

puts gets

Điều này thực sự, thực sự tự giải thích.

Chỉnh sửa: Tôi đã được yêu cầu một lời giải thích. Điều này tương đương với puts(gets). getsnhập một chuỗi với một trình soạn thảo dòng. putsđầu ra nó.


Xâu chuỗi các cuộc gọi phương thức: r.insert_text(s).redisplayvà loại bỏ các mục sau ;. BTW, như tôi hiểu chính sách của chúng tôi, bạn nên đề cập rằng mã của bạn chạy trong irb, bởi vì nếu không bạn sẽ cần phải yêu cầu Readlinemã của mình.
manatwork

1

PHP + HTML, 26 byte

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

Trình duyệt tự động thêm thẻ đóng

$ _GET Sử dụng một url như http://example.com?0=inputđầu vào Tạo trong HTML<input value=input

Và đây là đầu ra cho đầu vào chuỗi

<input value=input


Tôi có nên cho rằng điều này làm việc? Có lẽ bạn có thể thêm một lời giải thích, hoặc liên kết, hoặc hình ảnh động?
Adám

@ Adám Có, bạn có thể giả sử điều này Có lẽ bạn sẽ cải thiện và đặt thuộc tính autofocusthành con trỏ ở đầu. Các yếu tố HTML khác bạn cũng có thể chỉnh sửa nếu bạn đặt thuộc tínhcontenteditable
Jörg Hülsermann

Đầu vào =test></input><script>alert("Hi");//some malicious code\n</script>
Roman Gräf

@ RomanGräf Cậu bé hư. Có, tốt hơn là lọc Javascript
Jörg Hülsermann

1

Tcl, 17

puts [gets stdin]

Thông dịch viên trực tuyến chỉ cần mút để chứng minh điều đó, sau đó tôi giới thiệu một số hình ảnh từ trình vỏ lệnh Windows:

Trường hợp kiểm tra 1

nhập mô tả hình ảnh ở đâynhập mô tả hình ảnh ở đâynhập mô tả hình ảnh ở đâynhập mô tả hình ảnh ở đâynhập mô tả hình ảnh ở đây

Trường hợp thử nghiệm 2

nhập mô tả hình ảnh ở đâynhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


Bạn có thể giải thích điều này?
Adám

1
Tôi có thể thêm hình ảnh của nó chạy trên một dòng lệnh Windows.
sergiol

@ Adám: Bạn vẫn muốn tôi giải thích những gì mã đang làm hoặc những hình ảnh là đủ?
sergiol

Thế là đủ.
Adám

1

AHK , 32 byte

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

InputBoxlưu trữ bất cứ thứ gì được gõ dưới dạng biến svà đưa ra dấu nhắc bắt đầu của biến 1là tham số được truyền đầu tiên.
Sendgửi tổ hợp phím đến cửa sổ hiện tại. Trong trường hợp này, nó sẽ là nội dung củas .
MsgBoxlà một lựa chọn nhưng, để chơi gôn, Sendngắn hơn 2 byte.

Hoạt hình


@ Adám tôi đọc sai phần đó. Tôi đã cập nhật câu trả lời.
Kỹ sư Toast

Bây giờ nó là tốt.
Adám

1

Lệnh cửa sổ ngay lập tức VBA Excel - 22 byte

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

nhập mô tả hình ảnh ở đây


2
Đây chỉ là một giải pháp một phần, vì giá trị ban đầu của bạn ("Hi") được mã hóa cứng. Giá trị ban đầu phải được đọc từ một nơi nào đó (một ô hoặc một dấu nhắc hoặc một tệp ...) và giá trị cuối cùng phải được đặt ở đâu đó (một ô, một hộp thông báo, một tệp, ...).
Adám

inputbox(0,,"Hi")tiết kiệm một byte
Felipe Nardi Batista

@ Adám Cảm ơn. Đã sửa lỗi, nó đang đọc từ ô A1
Rohan

Tôi nghĩ bạn cần [a1]=inputbox(0,,[a1])hoặc một cái gì đó, nếu không, ađi đâu? Lưu trữ trong một biến không phải là một phương thức đầu ra hợp lệ .
Adám

Nó đi đến nơi nó đến từ ô A1
Rohan

0

ZX Spectrum BASIC, 7 byte

Không đáng kể, bao gồm tính đầy đủ ( INPUTPRINTlà một byte cho mỗi byte).

INPUT a$: PRINT a$

1
Làm thế nào để nó có được giá trị ban đầu a$?
Adám

@ Adám, nó nhận được giá trị ban đầu của a$đầu vào bàn phím; a$sẽ được viết quá mức với INPUTtừ khóa.
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

Tạo một hàm Evới 1 đối số và 0 đầu ra. (Đầu ra được hiển thị trong bảng điều khiển)

Các nhân vật trốn thoát phải là biểu tượng thực tế, nhưng họ sẽ không xuất hiện ở đây.

Điều khiển:

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.

Chèn / xóa các ký tự là ngược nên rất khó sử dụng (nhưng vẫn phải đáp ứng các yêu cầu).

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

Trình thông dịch lệnh Windows, 16 byte

set/pa=
echo %a%

Điều này rất tầm thường; trình thông dịch lệnh không quan trọng là "trình soạn thảo dòng".


0

Hàng hóa BASIC (C64Mini, C64 / 128, VIC-20, v.v ...) 179 byte BASIC được mã hóa

Điều này nên được gõ trong chế độ kinh doanh (ký tự chữ hoa / thường)

 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

Cho phép chỉnh sửa văn bản cơ bản + xóa + dòng mới. Kích thước tối đa a$giống như tất cả các chuỗi trong Commodore BASIC là 255 ký tự, do đó, nhiều hơn thế sẽ làm hỏng chương trình. Tôi sẽ tìm cách làm> 255 ký tự nếu điều đó là cần thiết.

Trình mô phỏng kiểu đơn giản

Trình giả lập kiểu đơn giản trong hành động

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.