สร้างเครื่องมือแก้ไขเส้นอย่างง่าย


19

ใน:สตริงที่ไม่มีตัวแบ่งบรรทัด *
อนุญาตให้ผู้ใช้แก้ไขและส่งบรรทัด
ออก:สตริงที่แก้ไข (อาจเป็นทางเลือกที่มีการลากบรรทัดต่อท้าย)

ตัวแก้ไขบรรทัดอย่างน้อยต้องอนุญาตให้ผู้ใช้:

  1. เลื่อนเคอร์เซอร์ที่มองเห็นไปทางซ้ายและขวา

  2. แทรกและ / หรือเขียนทับอักขระที่ตำแหน่งเคอร์เซอร์

  3. ลบอักขระที่ตำแหน่งเคอร์เซอร์

  4. ส่งสตริงใหม่นั่นคือการหยุดแก้ไขทำให้สตริงที่แก้ไขถูกส่งคืน / พิมพ์ / แสดง / บันทึก ... (โดยไม่มีข้อความอื่น)

ชื่นชม แต่ไม่จำเป็น:

  • คำอธิบายรหัสของคุณ

  • ลิงก์ไปยังเว็บไซต์ทดสอบออนไลน์ที่สามารถสาธิตโปรแกรม / ฟังก์ชั่นของคุณ

  • ภาพเคลื่อนไหวแสดงการใช้งาน (ตัวอย่างเช่น TIO ไม่อนุญาตการโต้ตอบ)

บันทึก:

  • การโยงคีย์เป็นคำแนะนำเท่านั้น

  • ไม่จำเป็นต้องใช้ GUI หรือการออกแบบภาพ

ตัวอย่าง

_ในต่อไปนี้เคอร์เซอร์จะมีภาพประกอบด้วย

ใน: Just some text
อนุญาตให้ผู้ใช้แก้ไข:
Just some text_  ผู้ใช้กด(ปุ่มลูกศรซ้าย) เก้าครั้ง
Just ̲some text  ผู้ใช้กดDelสี่ครั้ง
Just ̲ text  ผู้ใช้กด ผู้ใช้กดออก:any
Just any_text Enter
Just any text

ใน: Remove me
อนุญาตให้ผู้ใช้แก้ไข:
Remove me_  ผู้ใช้กดBackspaceเก้าครั้ง
_  ผู้ใช้กดออก: (สตริงว่าง)Enter
 


* เพื่อป้องกันวิธีแก้ไขปัญหาเรื่องไม่สำคัญสิ่งนี้จะต้องได้รับการจัดหาผ่านวิธีการป้อนข้อมูลที่แตกต่างจากคำสั่งการแก้ไขหรือจะต้องแยกออกจากพวกเขาโดยขึ้นบรรทัดใหม่หรือคล้ายกัน


เราจำเป็นต้องใช้การกดคีย์ที่แน่นอนเหล่านั้นสำหรับ i / o หรือไม่? นอกจากนี้เราสามารถสร้างไฟล์เพื่อบันทึกข้อความได้หรือไม่?
Rɪᴋᴇʀ

1
@Riker คีย์ผูกเป็นคำแนะนำเท่านั้น input และ output วิธีการปฏิบัติตามค่าเริ่มต้น PPCG
Adám

สตริงสามารถมีการขึ้นบรรทัดใหม่ได้หรือไม่ ขึ้นบรรทัดใหม่และสามารถใช้เพื่อ "ส่ง"?
Conor O'Brien

@ ConorO'Brien No; ง่ายเส้นบรรณาธิการ ใช่; อย่างน้อยที่สุดผู้แก้ไขจะต้องอนุญาตให้ผู้ใช้: (... ) 4. ส่งสตริงใหม่
2560

1
มันจะดีถ้าคุณระบุบรรทัดในเนื้อความที่แท้จริงของคำถามเนื่องจากชื่อเรื่องในเว็บไซต์นี้ไม่ตรงตามข้อกำหนด ...
Conor O'Brien

คำตอบ:


3

APL (Dyalog) 5 ไบต์

⍞←⍞⋄⍞

นี่คือ tradfn เพื่อที่จะใช้ทำ

a
⍞←⍞⋄⍞

แล้วเรียกมันโดยใช้aหลังจากที่คุณใส่สตริงเริ่มต้นแล้วคุณสามารถแก้ไขสตริงได้


8

JavaScript (ES6), 15 14 ไบต์

ฉันไม่เข้าใจว่าทำไมสิ่งนี้ถึงได้เพิ่มขึ้นมากมาย!

s=>prompt(s,s)

บันทึกขอบคุณไบต์ADAMpromptข้อเสนอแนะของที่ฉันแสดงการป้อนข้อมูลเดิมใน


ลองมัน

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ɪᴋᴇʀ

ใช่ฉันกำลังจะถามถึง-ei
2560

-iเปิดตัวใน Bash 4.0 (เปิดตัวในเดือนกุมภาพันธ์ 2009) -“ -i text ใช้ TEXT เป็นข้อความเริ่มต้นสำหรับ Readline”
ผลิต

ฉันสงสัยว่าแมวจะทำงานได้ไหม
Matthew Roh

catแค่รอกระแสที่เข้ามาซึ่งเชลล์จะไม่ให้ฟังก์ชันการแก้ไข อย่างน้อยก็ไม่ใช่โดยปริยาย
ผลิต

3

Bash + Vi / Vim, 14 ไบต์

echo $1>a;vi a

viเป็นนามแฝงvimบน macOS ฉันไม่รู้เกี่ยวกับระบบปฏิบัติการอื่น


บางทีฉันอาจขาดอะไรบางอย่าง แต่สิ่งนี้ตอบสนองความต้องการในการแสดงผลสตริงที่แก้ไขหรือไม่?
เกรย์สันเคนต์

1
@GraysonKent คุณสามารถบันทึกและออกโดยการกดปุ่ม:wq!หรือ:xดังนั้นฉันจึงคิดอย่างนั้น OP ค่อนข้างชัดเจนในสิ่งที่มีคุณสมบัติเหมือนกัน
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 ไบต์ขอบคุณJörgHülsermannและ 2 ไบต์ขอบคุณ Luke

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

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


2
คุณสามารถลบประเภทขององค์ประกอบการป้อนข้อมูลได้
JörgHülsermann

คุณควรใช้oninputแทน
Matthew Roh

@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

ใน: Just some text
Just some text>
Just some> text  ผู้ใช้กดCtrl+Cห้าครั้ง
Just > text  ผู้ใช้กดBackspaceสี่ครั้ง
Just any> text  ผู้ใช้กด ผู้ใช้กดออก:any
Just any> text Enter
Just any text

เวอร์ชันเครื่องมือแก้ไขแบบอินไลน์:

หากคุณต้องการให้ข้อความถูกแก้ไขแบบอินไลน์ผนวก,'\r',ท้ายprintคำสั่ง:

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

6
+1 ดีมาก คำตอบแรกซึ่งใช้เครื่องมือแก้ไขจริงซึ่งต่างจากการใช้ฟังก์ชันที่มีอยู่แล้ว ฉันกำลังพิจารณาที่จะโพสต์ความท้าทายอื่นเพื่อทำสิ่งนี้
อดัม

คุณไม่สามารถบันทึกไบต์โดยใช้ปุ่มอื่นสำหรับซ้ายและขวาได้หรือไม่
อดัม

ฉันสามารถสมมติตัวละครเป็น-และ+จะทำเช่นนั้น แต่บรรณาธิการจะไม่สามารถยอมรับตัวละครเหล่านั้นแล้ว
Felipe Nardi Batista

วิธีการเกี่ยวกับ\tและ\v?
อดัม

1
นั่นเป็นปัญหาของผู้ใช้ใช่ไหม Control + K อาจจะ?
Adám

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คอมไพล์และเรียกใช้ด้วยการป้อนข้อมูล

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

  • กดปุ่มลูกศรซ้ายเก้าครั้ง

ป้อนคำอธิบายรูปภาพที่นี่

  • กดปุ่ม Delete สี่ครั้ง

ป้อนคำอธิบายรูปภาพที่นี่

  • กดaแล้วนั้นny

ป้อนคำอธิบายรูปภาพที่นี่

  • กด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 demo


2

Ruby, 9 19 22 84 ไบต์

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

สิ่งนี้จะสร้างเบ็ดการป้อนข้อมูลล่วงหน้าของ Readline ที่จะแทรกข้อความและแสดงซ้ำ หลังจากนี้ IRB ก็จะสับสนดังนั้นโปรดเรียกใช้จากไฟล์ เรียกใช้เป็นแลมบ์ดามันใช้สตริงอินพุตเป็นอาร์กิวเมนต์และส่งคืนสตริงเอาต์พุต

puts Readline.readline

ใช้ไลบรารี Readline เพื่อทำการแก้ไขบรรทัด คำตอบก่อนหน้าของฉันอนุญาต backspaces เท่านั้น

puts gets

นี่คือจริงๆมันอธิบายตนเอง

แก้ไข: ฉันถูกขอคำอธิบาย puts(gets)นี้จะเทียบเท่ากับ getsอินพุตสตริงด้วยตัวแก้ไขบรรทัด putsเอาท์พุทมัน


เชนเรียกวิธีนี้และลบต่อไปนี้r.insert_text(s).redisplay ;BTW ตามที่ฉันเข้าใจนโยบายของเราคุณควรพูดถึงว่าโค้ดของคุณทำงานirbเพราะไม่เช่นนั้นคุณจะต้องใช้Readlineรหัสของคุณ
ระหว่าง

1

PHP + HTML, 26 ไบต์

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

เบราว์เซอร์จะเพิ่มแท็กปิดอัตโนมัติ

$ _GETการใช้ url เช่นเดียวhttp://example.com?0=inputกับ Input สร้างขึ้นใน HTML<input value=input

และนี่คือผลลัพธ์สำหรับอินพุตสตริง

<input value=input


ฉันควรสมมติว่าใช้งานได้หรือไม่ บางทีคุณสามารถเพิ่มคำอธิบายหรือลิงค์หรือภาพเคลื่อนไหวได้?
อดัม

@ Adam ใช่คุณสามารถสันนิษฐานได้ว่าบางทีคุณอาจจะปรับปรุงและกำหนดคุณลักษณะautofocusให้มีเคอร์เซอร์ที่จุดเริ่มต้นในนั้น องค์ประกอบ HTML อื่น ๆ ที่คุณสามารถแก้ไขได้หากคุณตั้งค่าแอตทริบิวต์contenteditable
JörgHülsermann

อินพุต =test></input><script>alert("Hi");//some malicious code\n</script>
Roman Gräf

@ RomanGräf Bad Boy ใช่ดีกว่าที่จะกรอง Javascript
JörgHülsermann

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เป็นตัวเลือก แต่สำหรับการเล่นกอล์ฟSendนั้นสั้นกว่า 2 ไบต์

นิเมชั่น


@ Adámฉันอ่านผิดส่วนนั้น ฉันได้อัพเดตคำตอบแล้ว
Engineer Toast

ตอนนี้มันดี
Adám

1

Excel VBA คำสั่งหน้าต่างทันที - 22 ไบต์

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

ป้อนคำอธิบายรูปภาพที่นี่


2
นี่เป็นเพียงวิธีการแก้ปัญหาบางส่วนเนื่องจากค่าเริ่มต้นของคุณ ("สวัสดี") เป็นรหัสตายตัว ค่าเริ่มต้นจะต้องอ่านจากที่ใดที่หนึ่ง (เซลล์หรือพรอมต์หรือไฟล์ ... ) และค่าสุดท้ายจะต้องใส่ที่อื่น (เซลล์, กล่องข้อความ, ไฟล์, ... )
อดัม

inputbox(0,,"Hi")บันทึกไบต์
Felipe Nardi Batista

@ Adámขอบคุณ แก้ไขแล้วตอนนี้มันกำลังอ่านจากเซลล์ A1
Rohan

ฉันคิดว่าคุณต้องการ[a1]=inputbox(0,,[a1])หรืออะไรอย่างอื่นจะaไปที่ไหน การจัดเก็บในตัวแปรไม่ได้เป็นวิธีการส่งออกที่ถูกต้อง
อดัม

มันไปยังที่ที่มันมาจากเซลล์ A1
Rohan

0

ZX Spectrum BASIC ขนาด 7 ไบต์

เล็กน้อยรวมถึงความสมบูรณ์ ( INPUTและPRINTเป็นหนึ่งโทเค็นไบต์ละ)

INPUT a$: PRINT a$

1
มันจะได้รับค่าเริ่มต้นได้a$อย่างไร
อดัม

@ Adam มันได้รับค่าเริ่มต้นa$จากการป้อนข้อมูลด้วยแป้นพิมพ์; a$จะถูกเขียนทับด้วยINPUTคำหลัก
Shaun Bebbers

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 โทเค็นพื้นฐานไบต์

ควรพิมพ์ในโหมดธุรกิจ (อักขระตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็ก)

 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 ตัวอักษรหากจำเป็น

โปรแกรมจำลองประเภท em-up ง่าย ๆ

การจำลองแบบ em-up อย่างง่าย ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.