# Wrappers for real screen primitives that can be passed a fake screen. # The tests here have been painstakingly validated against a real terminal # emulator. I believe functionality here is broadly portable across terminal # emulators. # # Remember: fake screen co-ordinates are 1-based, just like in real terminal # emulators. type screen { num-rows: int num-cols: int data: (handle array screen-cell) top-index: int # 0-indexed cursor-row: int # 1-indexed cursor-col: int # 1-indexed cursor-hide?: boolean curr-attributes: screen-cell } type screen-cell { data: grapheme color: int background-color: int bold?: boolean underline?: boolean reverse?: boolean blink?: boolean } fn initialize-screen screen: (addr screen), nrows: int, ncols: int { var screen-addr/esi: (addr screen) <- copy screen var tmp/eax: int <- copy 0 var dest/edi: (addr int) <- copy 0 # screen->num-rows = nrows dest <- get screen-addr, num-rows tmp <- copy nrows copy-to *dest, tmp # screen->num-cols = ncols dest <- get screen-addr, num-cols tmp <- copy ncols copy-to *dest, tmp # screen->data = new screen-cell[nrows*ncols] { var data-addr/edi: (addr handle array screen-cell) <- get screen-addr, data tmp <- multiply nrows populate data-addr, tmp } # screen->cursor-row = 1 dest <- get screen-addr, cursor-row copy-to *dest, 1 # screen->cursor-col = 1 dest <- get screen-addr, cursor-col copy-to *dest, 1 # screen->curr-attributes->background-color = 7 (simulate light background) var tmp2/eax: (addr screen-cell) <- get screen-addr, curr-attributes dest <- get tmp2, background-color copy-to *dest, 7 } fn screen-size screen: (addr screen) -> _/eax: int, _/ecx: int { var nrows/eax: int <- copy 0 var ncols/ecx: int <- copy 0 compare screen, 0 { break-if-!= nrows, ncols <- real-screen-size return nrows, ncols } # fake screen var screen-addr/esi: (addr screen) <- copy screen var tmp/edx: (addr int) <- get screen-addr, num-rows nrows <- copy *tmp tmp <- get screen-addr, num-cols ncols <- copy *tmp return nrows, ncols } fn clear-screen screen: (addr screen) { compare screen, 0 { break-if-!= clear-real-screen return } # fake screen var space/edi: grapheme <- copy 0x20 move-cursor screen, 1, 1 var screen-addr/esi: (addr screen) <- copy screen var i/eax: int <- copy 1 var nrows/ecx: (addr int) <- get screen-addr, num-rows { compare i, *nrows break-if-> var j/edx: int <- copy 1 var ncols/ebx: (addr int) <- get screen-addr, num-cols { compare j, *ncols break-if-> print-grapheme screen, space j <- increment loop } i <- increment loop } move-cursor screen, 1, 1 } fn move-cursor screen: (addr screen), row: int, column: int { compare screen, 0 { break-if-!= move-cursor-on-real-screen row, column return } # fake screen var screen-addr/esi: (addr screen) <- copy screen # row < 0 is ignored { compare row, 0 break-if->= return } # row = 0 is treated same as 1 { compare row, 0 break-if-!= copy-to row, 1 } # row > num-rows saturates to num-rows { var nrows-addr/eax: (addr int) <- get screen-addr, num-rows var nrows/eax: int <- copy *nrows-addr compare row, nrows break-if-<= copy-to row, nrows } # column < 0 is ignored { compare column, 0 break-if->= return } # column = 0 is treated same as 1 { compare column, 0 break-if-!= copy-to column, 1 } # column > num-cols saturates to num-cols+1 (so wrapping to next row) { var ncols-addr/eax: (addr int) <- get screen-addr, num-cols var ncols/eax: int <- copy *ncols-addr compare column, ncols break-if-<= copy-to column, ncols increment column } # screen->cursor-row = row var dest/edi: (addr int) <- get screen-addr, cursor-row var src/eax: int <- copy row copy-to *dest, src # screen->cursor-col = column dest <- get screen-addr, cursor-col src <- copy column copy-to *dest, src } fn print-string screen: (addr screen), s: (addr array byte) { compare screen, 0 { break-if-!= print-string-to-real-screen s return } #
" Compatible with ranger 1.4.2 through 1.7.*
"
" Add ranger as a file chooser in vim
"
" If you add this code to the .vimrc, ranger can be started using the command
" ":RangerChooser" or the keybinding "<leader>r". Once you select one or more
" files, press enter and ranger will quit again and vim will open the selected
" files.
function! RangeChooser()
let temp = tempname()
" The option "--choosefiles" was added in ranger 1.5.1. Use the next line
" with ranger 1.4.2 through 1.5.0 instead.
"exec 'silent !ranger --choosefile=' . shellescape(temp)
if has("gui_running")
exec 'silent !xterm -e ranger --choosefiles=' . shellescape(temp)
else
exec 'silent !ranger --choosefiles=' . shellescape(temp)
endif
if !filereadable(temp)
redraw!
" Nothing to read.
return
endif
let names = readfile(temp)
if empty(names)
redraw!
" Nothing to open.
return
endif
" Edit the first item.
exec 'edit ' . fnameescape(names[0])
" Add any remaning items to the arg list/buffer list.
for name in names[1:]
exec 'argadd ' . fnameescape(name)
endfor
redraw!
endfunction
command! -bar RangerChooser call RangeChooser()
nnoremap <leader>r :<C-U>RangerChooser<CR>