วิธีการดีบั๊กแมป


65

ฉันเห็นคำถามมากมายที่นี่ซึ่งผู้ใช้มีการแมปซึ่งไม่ได้ผลและส่วนใหญ่แล้วเหตุผลก็ค่อนข้างคล้ายคลึงกัน

ฉันขอแนะนำให้ทำให้คำถามนี้เป็นข้อมูลอ้างอิงสำหรับคำถามประเภทนี้เพื่อให้กระบวนการที่สมบูรณ์ในการดีบักการแมป หากผู้ใช้มีปัญหากับการทำแผนที่พวกเขาสามารถถูกเปลี่ยนเส้นทางที่นี่เพื่อกำจัดปัญหาที่พบบ่อยที่สุด

แน่นอนว่ายังมีบางกรณีที่จะต้องใช้คำถามเฉพาะและจะไม่ได้รับการแก้ไขที่นี่

คำตอบ:


88

การแมปของคุณไม่ได้ทำในสิ่งที่ควรทำหรือทำงานแตกต่างไปจากที่คาดไว้มีหลายขั้นตอนในการแก้ไขปัญหา:

ตรวจสอบว่าคีย์ถูกแมปอย่างมีประสิทธิภาพกับสิ่งที่ควรทำ

:mapเป็นกลุ่มให้คำสั่ง โดยค่าเริ่มต้น (เมื่อไม่มีการกำหนดอาร์กิวเมนต์) คำสั่งจะแสดงการแมปทั้งหมดที่สร้างขึ้นในปัจจุบัน นี่คือตัวอย่างของผลลัพธ์ของคำสั่ง:

ผลลัพธ์ของ <code>: แผนที่ </code>

เช่นเคยที่ doc เป็นเพื่อนของคุณ: :h map-listing

คุณสามารถเห็นในโหมดแรกของโหมดการแมปในคอลัมน์แรก ( nสำหรับโหมดปกติสำหรับโหมด vภาพ ฯลฯ ) คอลัมน์ที่สองแสดงปุ่มที่แมปและคอลัมน์สุดท้ายที่แมปไป โปรดทราบว่าก่อนที่จะมีการดำเนินการแมปอักขระเพิ่มเติมอาจปรากฏขึ้นเป็นสิ่งสำคัญที่จะเข้าใจพวกเขา:

  • * ระบุว่าไม่สามารถใช้ซ้ำได้ (เช่นไม่ใช่การแมปแบบเรียกซ้ำให้ดูknow when to use noreภายหลังในคำตอบนี้)
  • & บ่งชี้ว่าการแม็พสคริปต์โลคัลสามารถรีเมคได้
  • @ บ่งชี้ถึงการแมปบัฟเฟอร์ท้องถิ่น

เมื่อขอความช่วยเหลือเกี่ยวกับการทำแผนที่มันเป็นสิ่งที่ดีที่จะเพิ่มข้อมูลนี้เพราะมันสามารถช่วยให้คนอื่นเข้าใจพฤติกรรมของการทำแผนที่ของคุณ

มันเป็นไปได้ที่จะ จำกัด พรอมต์ไปที่โหมดโดยเฉพาะอย่างยิ่งกับน้องสาวของคำสั่ง:mapเช่น:vmap, :nmap, :omapฯลฯ

ทีนี้เพื่อ จำกัด การค้นหาของคุณไปยังการแมปที่มีปัญหาคุณสามารถผ่านลำดับคีย์ที่คุณกำลังดีบั๊กเป็นพารามิเตอร์ของคำสั่งดังนี้:

:map j
:map <Leader>m
:map <F5>

โปรดทราบว่า<Leader>คีย์จะถูกแทนที่ด้วยค่าจริงในรายการ

หากผลลัพธ์ของคำสั่งแสดงว่าคีย์ของคุณถูกแมปอย่างถูกต้องอาจหมายความว่าปัญหาไม่ได้มาจาก Vim แต่มาจากเทอร์มินัลหรือสภาพแวดล้อมเดสก์ท็อปของคุณ ดูที่ส่วนตรวจสอบว่าการจับคู่ของคุณถูกดักจับโดย Vim หรือไม่

หากผลลัพธ์ของคำสั่งแสดงว่าคีย์ของคุณไม่ได้รับการแมปอย่างถูกต้องให้ดูส่วนต่อไปนี้

ตรวจสอบสิ่งที่เอาชนะการทำแผนที่ของคุณ

การใช้:mapคำสั่งอื่นที่สะดวกคือการรวมเข้ากับverbose: ซึ่งจะเป็นการแจ้งให้ไฟล์ล่าสุดที่แก้ไขการแมปของคุณ

ตัวอย่างเช่นดูภาพหน้าจอสองภาพเหล่านี้ซึ่งเป็นผลลัพธ์ของ:verbose map: ภาพแรกคือการจับคู่ที่แก้ไขโดยการทำแผนที่ของฉัน.vimrcและครั้งที่สองที่สร้างโดยปลั๊กอิน:

การแม็พที่ตั้งค่าจาก vimrc

การแม็พที่ตั้งค่าจากปลั๊กอิน

ตอนนี้ถ้าคุณเห็นว่าสคริปต์อื่นปรับเปลี่ยนการแมปของคุณคุณจะต้องดูว่าคุณสามารถลบออกหรือแก้ไขพฤติกรรมของมัน (โปรดทราบว่าปลั๊กอินบางตัวมีตัวแปรในการเปิด / ปิดการใช้งานการแมป แต่น่าเสียดายที่ปลั๊กอินทั้งหมดไม่สามารถทำได้)

หากไฟล์สุดท้ายที่เปลี่ยนการแมปของคุณเป็นของคุณ.vimrcตรวจสอบให้แน่ใจว่าไม่มีบรรทัดอื่นที่กำหนดการแมปสำหรับคีย์เดียวกัน .vimrcไฟล์อย่างมีความสุขจะแทนที่แมปใด ๆ กับคนสุดท้ายของชนิดในแฟ้ม

ตรวจสอบว่าการจับคู่ของคุณถูกดักจับโดย Vim หรือไม่

หลายสถานการณ์อาจบ่งบอกว่าเสียงเรียกเข้าไม่ได้ขัดขวางคีย์ของคุณ:

  • คำสั่ง:mapแสดงให้เห็นว่าคีย์ของคุณถูกแมปอย่างถูกต้อง แต่การกดไม่ทำอะไรเลย
  • การจับคู่ของคุณทำงานบน gVim (GUI) แต่ไม่ทำอะไรเลยใน terminal Vim
  • การแมปของคุณใช้งานได้กับเทอร์มินัลอีมูเลเตอร์ที่กำหนด
  • การแมปของคุณทำงานบนระบบปฏิบัติการที่กำหนด แต่ไม่ใช่การแมปอื่น

อาจเกิดจากหนึ่งในสองสิ่งต่อไปนี้:

  • มีบางอย่างตัดกุญแจก่อนที่จะเป็นกลุ่ม : มันอาจเป็นแอพพลิเคชั่นที่แตกต่างกัน: ระบบปฏิบัติการของคุณ, สภาพแวดล้อมเดสก์ท็อปของคุณ, เทอร์มินัลอีมูเลเตอร์, Tmux (ถ้าคุณใช้)

    ในการแก้ไขปัญหานั้นคุณควร:

    • ลองลบชั่วคราว.tmux.confหากคุณใช้ tmux
    • อ้างถึงเอกสารของเครื่องเทอร์มินัลหรือสภาพแวดล้อมเดสก์ท็อปของคุณ

    คุณสามารถอ้างถึงเว็บไซต์ในเครือเช่นผู้ใช้ขั้นสูง , Unix และ Linux , AskUbuntu , ฯลฯ ...

    หากนี่คือปัญหาคุณมีวิธีแก้ไขสองวิธี: คุณใช้เวลา (มาก) ในการเปลี่ยนพฤติกรรมของแอปพลิเคชันซึ่งเป็นสาเหตุของปัญหาหรือคุณพบกุญแจอีกชุดหนึ่งในแผนที่ซึ่งไม่ได้ถูกขัดขวางโดยแอปพลิเคชันอื่น

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

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

ตรวจสอบข้อผิดพลาดทั่วไป

ปัญหาบางอย่างในการแมปนั้นเกิดขึ้นอีกและส่วนใหญ่เกี่ยวข้องกับไวยากรณ์ของวิมสcript หากการทำแผนที่ของคุณมีพฤติกรรมที่ไม่คาดคิดอย่าลืมตรวจสอบประเด็นต่อไปนี้:

  • อย่าใส่ความคิดเห็นในบรรทัดเดียวกับการจับคู่ของคุณแทนที่จะใส่ความคิดเห็นลงในบรรทัดข้างต้น ตัวอย่าง:

    อย่าทำอย่างนั้น:

    inoremap ii <esc>    " ii to go back into normal mode
    

    เป็นกลุ่มจะพิจารณาช่องว่าง"และความคิดเห็นเป็นส่วนหนึ่งของการทำแผนที่ซึ่งจะทำให้เกิดพฤติกรรมที่ไม่คาดคิด

    ทำอย่างนั้นแทน:

    " ii to go back into normal mode
    inoremap ii <esc>
    

    ง่ายต่อการอ่านและไม่ทำให้การทำแผนที่ของคุณยุ่ง

  • |อย่าท่อคำสั่งของคุณด้วย ตัวอย่าง:

    อย่าทำอย่างนั้น:

    nnoremap <Leader>x :w | !% python -m json.tools
    

    กลุ่มจะพิจารณาไปป์|เป็นคำสั่งยกเลิก: เมื่อคุณแหล่งที่มาของคุณ.vimrcการทำแผนที่nnoremap <Leader>x :wจะถูกสร้างขึ้นแล้วคำสั่งภายนอก!% python -m json.toolsจะถูกดำเนินการ

    ทำอย่างนั้นแทน:

    nnoremap <Leader>x :w <bar> !% python -m json.tools
    

    ดูคำอธิบายเกี่ยวกับ<bar>

  • ทราบเมื่อมีการใช้งานnore:เสมอ

    LearnVimscriptTheHardWayอธิบายมันสวยอย่างชัดเจน: ไม่เคยใช้map, nmap, vmapฯลฯ ... มักจะชอบรุ่น nore นี้: noremap, nnoremap, vnoremapฯลฯ ... ทำไม? noreย่อมาจากการnon-recursiveทำแผนที่หมายความว่าด้านขวามือของการทำแผนที่จะถูกพิจารณาว่าเป็นคุณสมบัติในตัวแม้ว่าคุณจะทำแผนที่ใหม่ ตัวอย่าง:

    สมมติว่าคุณต้องการแมป>เพื่อลบบรรทัดและ-เพิ่มการเยื้องของบรรทัด หากคุณไม่ใช้การแมปที่ไม่เกิดซ้ำคุณจะทำดังนี้

    ( อย่าทำเพื่อเป็นตัวอย่าง )

    nmap > dd
    nmap - >
    

    เมื่อคุณไปถึง>สายของคุณจะถูกลบนั่นก็ดี แต่เมื่อคุณกดปุ่ม-จะถูกลบออกแทนที่จะถูกเยื้อง ทำไม? เพราะเป็นกลุ่มเข้าใจ "ฉันได้รับความนิยม-ซึ่งฉันควรจะแปล>ซึ่งฉันควรหันไปแปลdd"

    แทนที่จะทำเช่นนั้น

    nnoremap > dd
    nnoremap - >
    

    วิธีนี้เป็นกลุ่มจะแปล-เป็น>และจะไม่พยายามที่จะทำคำแปลอื่น ๆ noreเพราะ

    แก้ไขบันทึกย่อ "เสมอ" อาจเป็นคำตอบที่พูดเกินจริงในบางกรณีคุณจะต้องใช้แบบฟอร์มการเรียกซ้ำ แต่มันไม่ธรรมดา เพื่อชี้แจงฉันจะพูด @romainl จากคำตอบนี้ :

    ใช้การทำแผนที่แบบเรียกซ้ำถ้าคุณตั้งใจจะใช้การทำแผนที่อื่น ๆ ในการทำแผนที่ของคุณ ใช้การแมปที่ไม่เกิดซ้ำหากคุณไม่ทำ

  • โปรดจำไว้ว่าชุดคีย์บางชุดมีค่าเทียบเท่า : เนื่องจากรหัสเลขฐานสิบหกที่สร้างชุดคีย์บางชุดจะตีความโดย Vim เป็นคีย์อื่น ตัวอย่างเช่น

    • <C-h> เทียบเท่ากับ <backspace>
    • <C-j> เช่น <enter>
    • บนแป้นพิมพ์ภาษาฝรั่งเศส<M-a>จะเหมือนกับáและเหมือนกันกับการ <m-แมปทั้งหมด @LucHermitte ชี้ให้เห็นในความคิดเห็นที่เป็นปัญหากับปลั๊กอินที่ใช้การแม็พประเภทนี้เช่น vim-latex
    • <C-S-a><C-a>เทียบเท่ากับ การแม็พ Ctrl + อักษรตัวพิมพ์ใหญ่แยกจาก Ctrl + อักษรตัวพิมพ์เล็กไม่ได้เพราะวิธีที่เทอร์มินัลส่งรหัส ASCII

    เมื่อการจับคู่ของคุณดูเหมือนว่าจะมีผลกับคีย์อื่นให้ลองใช้ชุดค่าผสม lhs อื่นหากแก้ปัญหาได้ตรวจสอบว่ารหัสเลขฐานสิบหกใดถูกส่งไปยัง Vim

  • ตรวจสอบว่าผู้นำของคุณได้รับการกำหนดอย่างถูกต้อง : หากการแมปที่เกี่ยวข้อง<leader>ไม่ทำงานและคุณเปลี่ยนผู้นำด้วยคำสั่งmapleaderให้ตรวจสอบว่าคำจำกัดความของผู้นำของคุณเสร็จสิ้นก่อนที่จะมีคำจำกัดความของการแมป มิฉะนั้นเป็นกลุ่มจะพยายามสร้างการแมปด้วยคีย์ซึ่งไม่ใช่สิ่งที่คุณคิด นอกจากนี้หากคุณต้องการใช้สเปซบาร์ในฐานะผู้นำของคุณ (ซึ่งปัจจุบันค่อนข้างสวย)ให้แน่ใจว่าคุณใช้สัญลักษณ์ที่ถูกต้อง:let mapleader = "\<Space>"

การทำแผนที่ของคุณยังไม่ทำงาน

หากคุณทำตามขั้นตอนทั้งหมดของคำตอบนี้และการแมปของคุณยังไม่ทำงานอย่างที่คุณต้องการคุณอาจต้องขอความช่วยเหลือจากไซต์นี้

เพื่อช่วยให้ผู้คนช่วยเหลือคุณอย่าลืมให้ข้อมูลที่สำคัญเช่น:

  • คำสั่งที่คุณใช้เพื่อกำหนดการแมปของคุณ
  • สิ่งที่คุณคาดหวังในการทำแผนที่
  • คำอธิบายปัญหาอย่างแม่นยำ:

    "ใช้งานไม่ได้" จะไม่เป็นประโยชน์กับคนที่จะพยายามช่วยคุณ คุณควรแม่นยำถ้าการทำแผนที่ไม่ได้ทำอะไรหรือมันทำงานอย่างไรแตกต่างจากที่คุณคาดหวัง

  • ระบุด้วยว่าคุณได้ทำตามขั้นตอนที่อธิบายไว้ที่นี่และผลลัพธ์ที่ได้รับด้วย:mapและ:verbose map

ทั้งหมดนี้จะช่วยให้คุณและผู้ใช้เว็บไซต์ประหยัดเวลาได้มาก


คำสั่งที่มีประโยชน์: :unmap

บางครั้งอาจมีประโยชน์ในการรีเซ็ตการแมปโดยไม่ต้องใช้ Vim เพื่อช่วยในการดีบักพฤติกรรมของมัน

ในการทำเช่นนั้นคุณสามารถใช้คำสั่ง:unmap <key>ซึ่งจะลบการแมปที่กำหนดให้<key>สำหรับโหมดปกติ, ภาพและโหมดรอดำเนินการ :iunmapจะลบการแมปสำหรับโหมดแทรก สำหรับโหมดอื่น ๆ :help :unmapดู


อ้างอิง

การแนะนำการทำแผนที่ที่ยอดเยี่ยม: เรียนรู้นักเขียนยาก (และด้านอื่น ๆ ของ Vim)

หมอ: :h mapping, :h :map

ส่วนที่ 20 ของคำถามที่พบบ่อยของ Vimนั้นเกี่ยวกับการทำแผนที่และมีคำถามที่น่าสนใจ:

และโบนัส: คำถามเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดในการค้นหาคีย์ที่จะใช้ในการทำแผนที่ของคุณ


2
ที่จะแบ่งปันประสบการณ์ของฉันกับผู้ใช้งานอื่นเป็นผู้ดูแลของเราแนะนำให้ทำ และเพราะI see a lot of questions on here where a user has a mapping which doesn't work and most of the time the reasons are pretty similarอย่างที่ฉันพูดในบรรทัดแรกของคำถามของฉันดังนั้นการรวบรวมเหตุผลเหล่านี้ควรอนุญาตให้ลดจำนวนคำถามที่ซ้ำกันเกี่ยวกับการจับคู่
statox

1
ปัญหาที่เกิดขึ้นซ้ำ ๆ กับ vim-latex และแป้นพิมพ์ภาษาฝรั่งเศส: <m-i>และéจะเหมือนกันสำหรับ vim และมันก็เหมือนกันกับ meta + key ทั้งหมด: พวกมันเชื่อมโยงกับการออกเสียงอื่น
Luc Hermitte

1
สิ่งสำคัญคือต้องรู้วิธีอ่านการแม็พบัฟเฟอร์ในเครื่องเมื่อเราขอคำจำกัดความด้วย:map {sequence}-> มี*ไฮไลต์ย้อนกลับในสิ่งที่ vim พิมพ์ก่อนการกระทำที่เกี่ยวข้อง
Luc Hermitte

2
บางครั้งเราต้องการดีบักสิ่งที่เกิดขึ้น โดยทั่วไปเมื่อการแมปเรียกใช้การแมปปลั๊กหรือฟังก์ชั่นที่มีชื่อที่จำไม่ได้หรือด้วยพารามิเตอร์ที่ซับซ้อน ในกรณีที่เราสามารถดำเนินการ: :debug normal {keysequence}(ไม่มีปังใด ๆ ) หรือ:debug i{keysequence}สำหรับแมปโหมดแทรก ฯลฯ ถ้าลำดับที่สำคัญมีสิ่งเช่นปุ่มพิเศษ ( <cr>, <left>, <c-x>, <m-i>, <leader>... ) แล้วเราต้องเล่นกับรัน + ราคาสองครั้ง + ทับขวา :debug execute "normal \<leader>\<cr>Z"->
Luc Hermitte

2
<m-i>เกี่ยวกับเมตาลำดับนี้เป็นจุดที่เก่าคำถามที่พบบ่อยเป็นกลุ่มน้ำยางไม่เลือกที่จะใช้สิ่งที่ต้องการ ผู้ใช้ส่วนใหญ่ไม่ได้ใช้เมตาคีย์เนื่องจากพวกเขามุ่งเน้นอย่างมากต่อการเรียกใช้ Vim ในเทอร์มินัลซึ่งไม่สามารถใช้เมตาคีย์ได้อย่างง่ายดาย เราจำเป็นต้องใช้ gvim หรือ macvim เพื่อสังเกตเห็นปัญหา
Luc Hermitte
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.