เป็นไปได้หรือไม่ที่จะกำหนดค่าวิธีทุบตีชื่อไดเรกทอรีให้สมบูรณ์


8

ฉันต้องการสั่งทุบตีให้ใช้วิธีพิเศษเพื่อดำเนินการให้เสร็จสมบูรณ์ในชื่อไดเรกทอรีบางอย่าง ตัวอย่างเช่นทุบตีจะเรียกโปรแกรมของฉันเพื่อดำเนินการให้เสร็จสมบูรณ์หากเส้นทางเริ่มต้นด้วย "$$" และดำเนินการเสร็จตามปกติมิฉะนั้น

เป็นไปได้ไหม? คุณจะใช้มันอย่างไร?

เงินรางวัล : ฉันขอขอบคุณคำตอบสำหรับคำถามนั้น เป้าหมายคืออนุญาตให้autojumpดำเนินการกับพา ธสำหรับคำสั่งทั้งหมดเมื่อผู้ใช้เริ่มต้นด้วยคำนำหน้าบางอย่าง ตัวอย่างเช่นเมื่อคัดลอกไฟล์จากไดเรกทอรีไกลคุณสามารถพิมพ์:

cp $$patern + <Tab>

และการกระโดดอัตโนมัติจะเสร็จสมบูรณ์

cp /home/user/CompliCatedDireCTOry/long/path/bla/bla

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


ดูหัวข้อ "การทำให้โปรแกรมเสร็จสมบูรณ์" ในหน้า bash man

หากคุณโหวตให้ปิดคำถามของฉันโปรดอธิบายว่าทำไม
Peltier

2
"สมบูรณ์" รองรับ "รูปแบบ -G" เพื่อให้ตรงกับ $$ จุดเริ่มต้นและ "-F func" เพื่อเรียกใช้ฟังก์ชันของคุณเอง แต่ต้องใช้ชื่อคำสั่งอย่างน้อยหนึ่งชื่อเพื่อทำงาน

ทำไมไม่ใช้ตัวแปรสภาพแวดล้อม? ตัวอย่างเช่น: cp $ คำนำหน้า / ไฟล์ / เส้นทาง / ถึง / ปลายทาง /
Xenoactive

@ Xenoactive: เนื่องจาก autojump เป็นระบบอัตโนมัติเต็มรูปแบบและทำงานได้มากกว่าหนึ่งเส้นทาง การใช้ตัวแปรสภาพแวดล้อมตั้งค่าด้วยตนเองไม่ได้ช่วยอะไร หรือบางทีคุณมีความคิดอันทรงพลังที่ฉันไม่เข้าใจ?
Peltier

คำตอบ:


3

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

ฟังก์ชันนี้ใช้บรรทัดคำสั่งปัจจุบันและเปลี่ยนอักขระสองตัวสุดท้ายเป็น 'huugs'

function my_awesome_tab_completion_function () {
  set -- $READLINE_LINE
  command="$1"
  shift
  argument="$*"
  argument_length=$(echo -n $argument | wc -c)
  if echo $argument | grep '^$$' >/dev/null 2>&1; then
    new_argument=$(echo $argument | sed 's/..$/huugs/') # put your autojump here
  else
    new_argument=$(compgen -d $argument)
  fi
  new_argument_length=$(echo -n $new_argument | wc -c)
  READLINE_POINT=$(( $new_argument_length - $argument_length + $READLINE_POINT ))
  READLINE_LINE="$command $new_argument"
}

สำหรับตัวอย่างของคุณคุณอาจต้องการเปลี่ยนบรรทัด new_argument เป็นแบบนี้:

  new_argument=$(autojump $argument)

ตอนนี้แทนที่การผูก ^ i:

$ bind -x '"\C-i"':'my_awesome_tab_completion_function'

ตอนนี้ทดสอบว่าใช้งานได้:

$ cd /ro<TAB>
changes my command to:
$ cd /root

ดังนั้นการทำให้สมบูรณ์ตามปกติยังใช้งานได้คุณสามารถทดสอบส่วน $$ โดยทำ cd $$ ... ฯลฯ

หากคุณพบปัญหาเปิดโหมด verbose:

$ set -x

มันจะพิมพ์ทุกอย่างที่ฟังก์ชันกำลังทำอยู่

ฉันทดสอบสิ่งนี้บน Ubuntu 11 โดยใช้ bash 4.2.8 (1) -release (ค่าเริ่มต้น)


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

ทีนี้มันกำลังผ่าน $ * ดังนั้นมันจะ 'ทำงาน' มากกว่าแค่พารามิเตอร์ตัวแรก (ฉันไม่รู้ autojump เลยดังนั้นฉันไม่แน่ใจว่ามันสามารถใช้อาร์กิวเมนต์หลายตัวได้หรือไม่) คุณสามารถเลื่อนไปยังจุดสิ้นสุดและส่งล่าสุดไปที่ autojump หรือใช้ READLINE_POINT เพื่อกำหนดว่าเคอร์เซอร์อยู่ที่ไหนในบรรดาอาร์กิวเมนต์คำสั่งและส่งเฉพาะ 'word' ไปยัง autojump ด้วยเช่นกัน
พหุนาม

โซลูชันของคุณน่าสนใจ แต่คุณต้องยอมรับว่าการยึดคีย์แท็บค่อนข้างรุนแรง ไม่มีทางที่คุณจะสามารถคาดการณ์ได้ทุกกรณี
harrymc

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

Ya ฉันเห็นด้วยกับ harrymc ด้วย แต่พยายามตอบคำถามตามที่ถาม โดยส่วนตัวแล้วฉันจะผูกสิ่งนี้กับปุ่มควบคุมอื่น ๆ เช่น ^ G หรืออะไรบางอย่างดังนั้นฉันสามารถออกจากแท็บเพียงอย่างเดียว แต่ยังคงใช้ฟังก์ชั่นนี้
พหุนาม

1

รูทีนการเติมเต็มของ bash สามารถตั้งโปรแกรมเป็นเชลล์สคริปต์

นี่คือตัวอย่างของ shell-script ที่จะแทนที่ในพารามิเตอร์ใด ๆ$$[Tab]โดยmy replacement stringเฉพาะสำหรับคำสั่งเฉพาะmycommandและเฉพาะถ้าพารามิเตอร์เป็น "$$" เท่านั้น:

_mycomplete()
{
        if [ ${COMP_WORDS[COMP_CWORD]} == \$\$ ]
        then
                COMPREPLY='my replacement string'
        fi
}
complete -o default -o bashdefault -F _mycomplete mycommand

คุณต้องแหล่งสคริปต์เพื่อ bash ผ่านsource <file-name>(หรือคำสั่ง dot) เพื่อเริ่มการทำงานแล้ว:

mycommand $$[Tab] -> mycommand my replacement string
mycommand $$$[Tab] -> mycommand $$$ (beep)
mycommand whatever[Tab] -> (will complete "whatever" in the normal bash manner)

มักจะมีการทำงานบางส่วนหรือทั้งหมดผู้ใช้นี้รวมอยู่ในหนึ่งในกิจวัตรรายละเอียดทุบตี

ปัญหาเกี่ยวกับcompleteคำสั่งคือมันจะทำงานได้กับชื่อคำสั่งอย่างน้อยหนึ่งชื่อที่ระบุเป็นพารามิเตอร์เท่านั้น เราสามารถให้รายการคำสั่งทั้งหมดที่ผู้ใช้อาจใช้หรือในกรณีที่สิ้นหวังขยาย/bin/* /usr/bin/* ~/bin/*ออกไป

ทดสอบบน CentOS 5.5

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


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