รันโค้ด Python ใน Vim


106

ฉันกำลังเขียนโค้ด Python โดยใช้ Vim และทุกครั้งที่ฉันต้องการเรียกใช้โค้ดฉันพิมพ์สิ่งนี้ภายใน Vim:

:w !python

สิ่งนี้น่าหงุดหงิดดังนั้นฉันจึงมองหาวิธีที่เร็วกว่าในการเรียกใช้โค้ด Python ภายใน Vim การเรียกใช้สคริปต์ Python จากเทอร์มินัลอาจจะ? ฉันใช้ Linux

คำตอบ:


151

วิธีการเพิ่มไฟล์ลงใน -file autocmdของคุณ~/.vimrcสร้างการแมป:

autocmd FileType python map <buffer> <F9> :w<CR>:exec '!python3' shellescape(@%, 1)<CR>
autocmd FileType python imap <buffer> <F9> <esc>:w<CR>:exec '!python3' shellescape(@%, 1)<CR>

จากนั้นคุณสามารถกด<F9>เพื่อดำเนินการบัฟเฟอร์ปัจจุบันด้วยpython

คำอธิบาย:

  • autocmd: คำสั่งที่ Vim จะดำเนินการโดยอัตโนมัติ{event}(ที่นี่: ถ้าคุณเปิดไฟล์ python)
  • [i]map: สร้างแป้นพิมพ์ลัด<F9>ในโหมดแทรก / ปกติ
  • <buffer>: หากเปิดบัฟเฟอร์ / ไฟล์หลายไฟล์: ให้ใช้ไฟล์ที่ใช้งานอยู่
  • <esc>: ออกจากโหมดแทรก
  • :w<CR>: บันทึกไฟล์ของคุณ
  • !: รันคำสั่งต่อไปนี้ในเชลล์ของคุณ (ลอง:!ls)
  • %: ถูกแทนที่ด้วยชื่อไฟล์ของบัฟเฟอร์ที่ใช้งานอยู่ของคุณ แต่เนื่องจากอาจมีสิ่งต่างๆเช่นช่องว่างและสิ่งที่ "ไม่ดี" อื่น ๆ จึงควรไม่ควรเขียน:python %แต่ใช้
  • shellescape: หลีกเลี่ยงอักขระพิเศษ 1วิธีการที่มีเครื่องหมาย

TL; DR: บรรทัดแรกจะทำงานในโหมดปกติและเมื่อคุณกด<F9>ก่อนจะบันทึกไฟล์ของคุณจากนั้นเรียกใช้ไฟล์ด้วย python อย่างที่สองทำสิ่งเดียวกัน แต่ออกจากโหมดแทรกก่อน


6
คุณช่วยขยายคำตอบและอธิบายได้ไหมว่าฉันควรเพิ่มบรรทัดนั้นที่ไหน ภายในไฟล์คอนฟิกูเรชัน Vim อาจ? ฉันเป็นคนใหม่
multigoodverse

5
@ArditSulce ในไฟล์ vimrc ของคุณเพิ่มบรรทัด:autocmd FileType python nnoremap <buffer> ....
Kent

2
หากคุณใช้ os x (และฉันถือว่า unix) ".vimrc" อยู่ในโฮมไดเร็กทอรี คุณสามารถตรวจสอบได้โดยพิมพ์ ': version' ในโหมดคำสั่งเพื่อตรวจสอบว่าคุณเห็นบรรทัดที่เรียกว่า 'user vimrc file: "... "'
ThinkBonobo

มีวิธีบันทึกและเรียกใช้ไฟล์เดียวกันหรือไม่แทนที่จะเรียกใช้
Bharat

5
nnoremap <buffer> <F9> :!python %<cr>ดูเหมือนว่าจะทำงานใน Vim 7.4.1689 Shellescape มีไว้ทำอะไร?
Matt Kleinsmith

36

เพียงไปที่โหมดปกติโดยกด<esc>และพิมพ์:

! clear; python %

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

คำอธิบายทีละขั้นตอน:

! ให้คุณรันคำสั่งเทอร์มินัล

clear จะทำให้หน้าจอเทอร์มินัลของคุณว่างเปล่า

; จบคำสั่งแรกทำให้คุณสามารถแนะนำคำสั่งที่สองได้

pythonจะใช้ python เพื่อเรียกใช้สคริปต์ของคุณ (อาจถูกแทนที่ด้วย ruby)

%เชื่อมต่อชื่อไฟล์ปัจจุบันส่งผ่านเป็นพารามิเตอร์ไปยัง pythonคำสั่ง


28

ฉันมีสิ่งนี้ในไฟล์. vimrc ของฉัน:

imap <F5> <Esc>:w<CR>:!clear;python %<CR>

เมื่อฉันทำแก้ไขสคริปต์ Python <F5>ฉันเพียงแค่กด สคริปต์จะถูกบันทึกและดำเนินการในหน้าจอว่างเปล่า


ขอบคุณ! มันทำงานได้ดี ฉันสงสัยว่าฉันจะตั้งค่าทางลัดเป็นmคีย์บวก,แทนF5คีย์ได้อย่างไร
Jay Wong

ฉันไม่เห็นว่านี่เป็นการบันทึกไฟล์ก่อน?
Thomas Browne

ขอโทษค่ะลืมใส่ ": w" ฉันแก้ไขแล้วและเพิ่ม <Esc> ด้วย
czayas

2
ควรสังเกตว่าสิ่งนี้ดำเนินการในInsertโหมด สำหรับการดำเนินการในNormalโหมดใช้nmapแทนimap.
Marcin

17

ฉันชอบเอาต์พุต Python ที่เปลี่ยนเส้นทางไปยังหน้าต่าง Vim ใหม่ (และหากหน้าต่างนั้นเปิดทิ้งไว้ให้อัปเดตเนื้อหาในครั้งต่อไปที่คุณรันโค้ด Python ด้วยฟังก์ชันนี้):

" Bind F5 to save file if modified and execute python script in a buffer.
nnoremap <silent> <F5> :call SaveAndExecutePython()<CR>
vnoremap <silent> <F5> :<C-u>call SaveAndExecutePython()<CR>

function! SaveAndExecutePython()
    " SOURCE [reusable window]: https://github.com/fatih/vim-go/blob/master/autoload/go/ui.vim

    " save and reload current file
    silent execute "update | edit"

    " get file path of current file
    let s:current_buffer_file_path = expand("%")

    let s:output_buffer_name = "Python"
    let s:output_buffer_filetype = "output"

    " reuse existing buffer window if it exists otherwise create a new one
    if !exists("s:buf_nr") || !bufexists(s:buf_nr)
        silent execute 'botright new ' . s:output_buffer_name
        let s:buf_nr = bufnr('%')
    elseif bufwinnr(s:buf_nr) == -1
        silent execute 'botright new'
        silent execute s:buf_nr . 'buffer'
    elseif bufwinnr(s:buf_nr) != bufwinnr('%')
        silent execute bufwinnr(s:buf_nr) . 'wincmd w'
    endif

    silent execute "setlocal filetype=" . s:output_buffer_filetype
    setlocal bufhidden=delete
    setlocal buftype=nofile
    setlocal noswapfile
    setlocal nobuflisted
    setlocal winfixheight
    setlocal cursorline " make it easy to distinguish
    setlocal nonumber
    setlocal norelativenumber
    setlocal showbreak=""

    " clear the buffer
    setlocal noreadonly
    setlocal modifiable
    %delete _

    " add the console output
    silent execute ".!python " . shellescape(s:current_buffer_file_path, 1)

    " resize window to content length
    " Note: This is annoying because if you print a lot of lines then your code buffer is forced to a height of one line every time you run this function.
    "       However without this line the buffer starts off as a default size and if you resize the buffer then it keeps that custom size after repeated runs of this function.
    "       But if you close the output buffer then it returns to using the default size when its recreated
    "execute 'resize' . line('$')

    " make the buffer non modifiable
    setlocal readonly
    setlocal nomodifiable
endfunction

ฉันควรใส่สิ่งนี้ลงในของฉัน.vimrcหรือไม่? ถ้าไม่ฉันจะให้สคริปต์นี้เป็นกลุ่มได้อย่างไร (Noob ที่นี่)
Benjamin Chausse

1
@BenjaminChausse ขออภัยในการตอบกลับที่ล่าช้า ฉันได้ทำการทดสอบกับ. vimrc ซึ่งมีรหัสนั้นโดยเฉพาะและได้ผลจากสิ่งที่ฉันบอกได้ การทดสอบของฉัน จำกัด เฉพาะการเปิดไฟล์. py และกดปุ่ม F5 ซึ่งส่งผลให้เอาต์พุต python ปรากฏในหน้าต่างกลุ่มแยกต่างหาก "ฉันจะให้สคริปต์นี้เป็นกลุ่มได้อย่างไร". ขึ้นอยู่กับระบบปฏิบัติการของคุณ ฉันใช้ Windows ดังนั้นฉันจึงมีไฟล์ข้อความ C: \ Program Files (x86) \ Vim \ .vimrc ซึ่งมีรหัสนั้น (คุณสามารถตั้งชื่อว่า "_vimrc" ใน Windows ได้) ใน Linux หรือ mac คุณจะมีไฟล์ข้อความ. vimrc ในโฟลเดอร์บ้านของคุณเช่น ~ /
.vimrc

4
แม้ว่าเราจะรู้สึกซาบซึ้งว่าสิ่งนี้อาจทำให้คุณต้องใช้เวลามากในการสร้าง แต่การใส่ลิงก์ paypal ในคำตอบนั้นไม่เหมาะสม
Martijn Pieters

11

จากคำตอบก่อนหน้านี้หากคุณต้องการดูโค้ดในขณะที่ดูที่ผลลัพธ์คุณจะพบว่าคำสั่ง:ter( :terminal) มีประโยชน์

autocmd Filetype python nnoremap <buffer> <F5> :w<CR>:ter python2 "%"<CR>
autocmd Filetype python nnoremap <buffer> <F6> :w<CR>:vert ter python3 "%"<CR>

การใช้vertในบรรทัดที่สองจะรันโค้ดในแนวตั้งแทนที่จะเป็นแนวนอน

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

(ฉันเก็บเส้นเหล่านี้ไว้ข้างใน/home/user/.vimrc)


5

โปรดทราบว่าคุณสามารถทำซ้ำคำสั่งที่ใช้ล่าสุดได้@:ดังนั้นสิ่งที่คุณต้องทำซ้ำก็คืออักขระสองตัวนั้น

หรือคุณสามารถบันทึกสตริงw !pythonลงในรีจิสเตอร์ (เช่น"aตัวอย่าง) จากนั้นกด:<C-R>a<CR>เพื่อแทรกเนื้อหาของรีจิสเตอร์ลงaในคอมมานด์ไลน์แล้วเรียกใช้

หรือคุณสามารถทำสิ่งที่ฉันทำและแผนที่<leader>zเพื่อ:!python %<CR>ที่จะเรียกใช้ไฟล์ปัจจุบัน


4

ปลั๊กอิน: jupyter-vim

ดังนั้นคุณสามารถส่งเส้น ( <leader>E) การเลือกภาพ ( <leader>e) ไปยังการวิ่งjupyter-client(การแทนที่ipython)

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

ฉันชอบที่จะแยกบรรณาธิการและล่าม (แต่ละคนอยู่ในเชลล์) ลองนึกภาพคุณส่งคำสั่งการอ่านอินพุตที่ไม่ดี ...


3

หากคุณไม่ต้องการเห็น " :exec python file.py" พิมพ์ทุกครั้งให้ใช้สิ่งนี้:

nnoremap <F9> :echo system('python2 "' . expand('%') . '"')<cr>
nnoremap <F10> :echo system('python3 "' . expand('%') . '"')<cr>

มันไม่ได้ทำให้แถบสถานะสายการบิน / สายการบินของฉันวุ่นวายเช่นกัน


2

สำหรับการใช้งานทั่วไป (วิ่งหลาม / Haskell / ทับทิม / C ++ ... จากกลุ่มขึ้นอยู่กับfiletype) มีความสุขปลั๊กอินที่เรียกว่าเป็นกลุ่ม-quickrun รองรับภาษาโปรแกรมหลายภาษาโดยค่าเริ่มต้น สามารถกำหนดค่าได้ง่ายเช่นกันดังนั้นเราจึงสามารถกำหนดพฤติกรรมที่ต้องการสำหรับประเภทไฟล์ใด ๆ ได้หากจำเป็น github repo ไม่มี readme ที่สวยงาม แต่มีการบันทึกไว้อย่างดีด้วยไฟล์ doc


2

คำตอบที่ยอมรับใช้ได้กับฉัน (บน Linux) แต่ฉันต้องการให้คำสั่งนี้บันทึกบัฟเฟอร์ก่อนที่จะรันด้วยดังนั้นฉันจึงแก้ไขเล็กน้อย:

nnoremap <buffer> <F9> :w <bar> :exec '!python' shellescape(@%, 1)<cr>

:w <bar>บันทึกบัฟเฟอร์จากนั้นก็วิ่งรหัสในนั้น


2

ลองนึกถึงการใช้ shebang line ดังนั้นคุณจะสามารถใช้งานได้กับทุกภาษาไม่ใช่เฉพาะ Python

การเพิ่ม Shebang:

เพิ่มสิ่งนี้ในบรรทัดแรกของสคริปต์ของคุณ:

#!/usr/bin/env python3

หรือสิ่งนี้หากคุณใช้ Python 2:

#!/usr/bin/env python2

คีย์แมปกลุ่ม:

เพิ่มสิ่งนี้ใน~/.vimrc:

nmap <F7> :w<cr>:!clear;"%:p"<cr>

ทำให้ไฟล์ปฏิบัติการ:

พิมพ์เป็นกลุ่ม:

:!chmod +x %

หรือในอาคารผู้โดยสาร:

chmod +x script_name.py

คำอธิบาย:

เมื่อกด F7 ในโหมดปกติ Vim จะพยายามเรียกใช้ไฟล์ปัจจุบันเป็น bash script จากนั้น bash interpreter จะเห็นบรรทัด shebang และเข้าใจว่าไฟล์นี้ควรถูกส่งไปยัง Python (หรือโปรแกรมอื่น ๆ หากจำเป็น)

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

./script_name.py

แทนวิธีนี้ (ซึ่งจะได้ผลเช่นกัน):

python3 script_name.py

1

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


คุณสามารถค้นหาแบบเพิ่มหน่วยได้โดยพิมพ์อักขระเริ่มต้นของคำสั่งก่อนกดลูกศรขึ้น หากหลายคำสั่งที่ผ่านมาฉันทำ! หลาม% ฉันทำได้:! จากนั้นกดลูกศรขึ้นเพื่อวนเฉพาะคำสั่งที่ขึ้นต้นด้วย!
shmup

1

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


1

ฉันมีสิ่งนี้ใน. vimrc ของฉัน:

"map <F9> :w<CR>:!python %<CR>"

ซึ่งบันทึกบัฟเฟอร์ปัจจุบันและรันโค้ดโดยกำหนดเฉพาะ Esc + F9



1

คุณสามารถขยายสำหรับภาษาใดก็ได้โดยใช้ 1 keybinding พร้อมคำสั่ง augroup ตัวอย่างเช่น

augroup rungroup
    autocmd!
    autocmd BufRead,BufNewFile *.go nnoremap <F5> :exec '!go run' shellescape(@%, 1)<cr>
    autocmd BufRead,BufNewFile *.py nnoremap <F5> :exec '!python' shellescape(@%, 1)<cr>
augroup END



0

การทำแผนที่. vimrc นี้ต้องการConque Shellแต่จะจำลองพฤติกรรมของ Geany (และตัวแก้ไข X อื่น ๆ ):

  • กดปุ่มเพื่อดำเนินการ
  • ดำเนินการใน gnome-terminal
  • รอการยืนยันเพื่อออก
  • หน้าต่างจะปิดโดยอัตโนมัติเมื่อออก

    :let dummy = conque_term#subprocess('gnome-terminal -e "bash -c \"python ' . expand("%") . '; answer=\\\"z\\\"; while [ $answer != \\\"q\\\" ]; do printf \\\"\nexited with code $?, press (q) to quit: \\\"; read -n 1 answer; done; \" "')


0

วางเคอร์เซอร์ไว้ในโค้ด. คลิกขวาและเลือกหนึ่งในตัวเลือก "เลือก" เพื่อเน้นรหัสของคุณ จากนั้นกด Ctrl: และคุณจะเห็นพรอมต์ใหม่ '<,>'

ตอนนี้พิมพ์! python และดูว่าได้ผลหรือไม่

ฉันใช้เวลาหลายวันในการพยายามหาปัญหาเดียวกัน !!! ฉันใช้การเข้ารหัส:

s='My name'
print (s) 

หลังจากดึงผมออกจนหมดแล้วในที่สุดก็ทำถูก!


5
ใช้เมาส์ไม่เป็นกลุ่ม
0xc0de

1
:% !pythonแต่มันก็เป็นไปได้ที่จะทำ %หมายถึงทุกบรรทัด
T.Chmelevskij

0

แทนที่จะใส่การแมปคำสั่งในของคุณ.vimrcให้ใส่การแมปลงใน~/.vim/ftplugin/python.vimไฟล์ของคุณ(Windows $HOME\vimfiles\ftplugin\python.vim) หากคุณไม่มีไฟล์หรือไดเรกทอรีนี้ให้สร้างขึ้นมา ด้วยวิธีนี้คีย์จะถูกแมปเฉพาะเมื่อคุณเปิด.pyไฟล์หรือไฟล์ใด ๆ ด้วยfiletype=pythonเนื่องจากคุณจะรันคำสั่งนี้กับสคริปต์ Python เท่านั้น

สำหรับการทำแผนที่จริงฉันต้องการที่จะแก้ไขใน Vim ขณะที่สคริปต์ทำงาน หากไม่ได้รับคำตอบของ @cazyas ฉันมีสิ่งต่อไปนี้ในftplugin\python.vim(Windows) ของฉัน:

noremap <F5> <Esc>:w<CR>:!START /B python %<CR>

สิ่งนี้จะเรียกใช้สคริปต์ Python ปัจจุบันในพื้นหลัง สำหรับ Linux เพียงแค่เปลี่ยนเป็นสิ่งนี้:

noremap <F5> <Esc>:w<CR>:!python % &<CR>

0
" run current python file to new buffer
function! RunPython()
    let s:current_file = expand("%")
    enew|silent execute ".!python " . shellescape(s:current_file, 1)
    setlocal buftype=nofile bufhidden=wipe noswapfile nowrap
    setlocal nobuflisted
endfunction
autocmd FileType python nnoremap <Leader>c :call RunPython()<CR>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.