Full Code of vim/killersheep for AI

master e91801129d2d cached
12 files
18.4 KB
6.7k tokens
1 requests
Download .txt
Repository: vim/killersheep
Branch: master
Commit: e91801129d2d
Files: 12
Total size: 18.4 KB

Directory structure:
gitextract_9tqvlwg2/

├── .gitignore
├── LICENSE
├── README.md
├── autoload/
│   └── killersheep.vim
└── plugin/
    ├── beh.ogg
    ├── fail.ogg
    ├── fire.ogg
    ├── killersheep.vim
    ├── music.ogg
    ├── poop.ogg
    ├── quack.ogg
    └── win.ogg

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# All platforms
*.rej
*.orig
*.mo
*.swp
*~

# Mac OSX
.DS_Store


================================================
FILE: LICENSE
================================================
The Killersheep game goes under the same license as Vim.
You can find the text here: 
https://github.com/vim/vim/blob/master/runtime/doc/uganda.txt

It basically means you can copy the files as you like and also re-distribute
them, so long as you keep the license.


================================================
FILE: README.md
================================================
# killersheep

Silly game to show off the new features of Vim 8.2:
-   Popup windows with colors and mask
-   Text properties to highlight text
-   Sound

Installation
------------

Use your favorite plugin manager.

For example, using [vim-plug](https://github.com/junegunn/vim-plug):

```vim
Plug 'vim/killersheep'
```

Or download the files using the zip archive, and unpack them in your
pack directory `~/.vim/pack/mine/opt/killersheep/`.
Then load the pack manually with:

```vim
packadd killersheep
```

Or put this in your vimrc:

```vim
packadd! killersheep
```

How to play
-----------

First of all: make sure you can hear the sound (or put on your headphones if
you don't want your friends/colleagues to find out what you are doing).

```vim
:KillKillKill
```

Or, if you don't have conflicting commands, just:

```vim
:Kill
```

In the game:

| Key     | Description       |
| ------- | ----------------- |
| l       | move cannon right |
| h       | move cannon left  |
| Space   | fire cannon       |
| Esc     | exit game         |


Requirements
------------

-   Vim 8.2
-   feature +textprop
-   feature +sound or command "afplay", "paplay" or "cvlc".
-   terminal with at least 45 lines


================================================
FILE: autoload/killersheep.vim
================================================
" Implementation of the silly game
" Use :KillKillKill to start
"
" Last Update: 2019 Dec 7

let s:did_init = 0
let s:sound_cmd = ''

func killersheep#Start(sounddir)
  let s:dir = a:sounddir

  if !has('sound')
    if executable('afplay')
      " Probably on Mac
      let s:sound_cmd = 'afplay'
      let g:killersheep_sound_ext = '.mp3'
    elseif executable('paplay')
      " Probably on Unix
      let s:sound_cmd = 'paplay'
      let g:killersheep_sound_ext = '.ogg'
    elseif executable('cvlc')
      " Probably on Unix
      let s:sound_cmd = 'cvlc --play-and-exit'
      let g:killersheep_sound_ext = '.ogg'
    else
      echomsg 'This build of Vim is lacking sound support, you are missing out!'
      sleep 2
    endif
  endif

  if !s:did_init
    let s:did_init = 1
    call s:Init()
  endif

  call s:Clear()
  call s:Intro()
endfunc

func s:NoProp(text)
  return #{text: a:text, props: []}
endfunc

func s:Intro()
  hi SheepTitle cterm=bold gui=bold
  hi introHL ctermbg=cyan guibg=cyan
  call prop_type_delete('sheepTitle')
  call prop_type_add('sheepTitle', #{highlight: 'SheepTitle'})
  call prop_type_delete('introHL')
  call prop_type_add('introHL', #{highlight: 'introHL'})
  let s:intro = popup_create([
	\   #{text: '   The sheep are out to get you!',
	\     props: [#{col: 4, length: 29, type: 'sheepTitle'}]},
	\   s:NoProp(''),
	\   s:NoProp('In the game:'),
	\   #{text: '     h       move cannon left',
	\     props: [#{col: 6, length: 1, type: 'sheepTitle'}]},
	\   #{text: '     l       move cannon right',
	\     props: [#{col: 6, length: 1, type: 'sheepTitle'}]},
	\   #{text: '  <Space>    fire',
	\     props: [#{col: 3, length: 7, type: 'sheepTitle'}]},
	\   #{text: '   <Esc>     quit (colon also works)',
	\     props: [#{col: 4, length: 5, type: 'sheepTitle'}]},
	\   s:NoProp(''),
	\   #{text: 'Now press  s  to start or  x  to exit',
	\     props: [#{col: 12, length: 1, type: 'sheepTitle'},
	\             #{col: 28, length: 1, type: 'sheepTitle'}]},
	\ ], #{
	\   filter: function('s:IntroFilter'),
	\   callback: function('s:IntroClose'),
	\   border: [],
	\   padding: [],
	\   mapping: 0,
	\   drag: 1,
	\   close: 'button',
	\ })
  if has('sound') || len(s:sound_cmd)
    let s:keep_playing = 1
    call s:PlayMusic()
  endif
  call s:IntroHighlight(0)
endfunc

const s:introHL = [[4, 3], [8, 5], [14, 3], [18, 3], [22, 2], [25, 3], [29, 4]]
let s:intro_timer = 0
func s:IntroHighlight(idx)
  let idx = a:idx
  if idx >= len(s:introHL)
    let idx = 0
  endif
  let buf = winbufnr(s:intro)
  call prop_remove(#{type: 'introHL', bufnr: buf}, 1)
  call prop_add(1, s:introHL[idx][0],
	\ #{length: s:introHL[idx][1], bufnr: buf, type: 'introHL'})
  let s:intro_timer = timer_start(300, { -> s:IntroHighlight(idx + 1)})
endfunc

func s:IntroFilter(id, key)
  if a:key == 's' || a:key == 'S'
    call s:Clear()
    let s:round = 0
    let s:ready = popup_create('Get Ready!', #{border: [], padding: [2, 4, 2, 4]})
    call s:BlinkLevel(s:ready, 1)
    call timer_start(s:blink_time * 8, { -> s:NextRound()})
    let s:ready_timer = timer_start(300, {... -> s:ReadySound()})
  elseif a:key == 'x' || a:key == 'X' || a:key == "\<Esc>"
    call s:Clear()
  endif
  return 1
endfunc

func s:ReadySound()
  call s:PlaySound('quack')
  let s:ready_timer = timer_start(s:blink_time * 2, {... -> s:ReadySound()})
endfunc

func s:IntroClose(id, res)
  call s:Clear()
endfunc

" Play the music in a loop
func s:PlayMusic()
  if s:keep_playing
    let fname = s:dir .. '/music' .. g:killersheep_sound_ext
    if has('sound')
      let s:music_id = sound_playfile(fname, {x -> s:PlayMusic()})
    elseif len(s:sound_cmd)
      let s:music_job = job_start(s:sound_cmd .. ' ' .. fname)
      " Detecting job exit is a bit slow, use a timer to loop.
      let s:music_timer = timer_start(14100, {x -> s:PlayMusic()})
    endif
  endif
endfunc

func s:StopMusic()
  let s:keep_playing = 0
  if has('sound')
    call sound_clear()
  elseif len(s:sound_cmd) && exists('s:music_job')
    call job_stop(s:music_job)
    call timer_stop(s:music_timer)
    unlet s:music_job s:music_timer
  endif
endfunc

func s:Init()
  hi def KillerCannon ctermbg=blue guibg=blue
  hi def KillerBullet ctermbg=red guibg=red
  hi def KillerSheep ctermfg=black ctermbg=green guifg=black guibg=green
  hi def KillerSheep2 ctermfg=black ctermbg=cyan guifg=black guibg=cyan
  if &bg == 'light'
    hi def KillerPoop ctermbg=black guibg=black
  else
    hi def KillerPoop ctermbg=white guibg=white
  endif
  hi def KillerPoop ctermbg=black guibg=black
  hi def KillerLevel ctermbg=magenta guibg=magenta
  hi def KillerLevelX ctermbg=yellow guibg=yellow

  if !exists('g:killersheep_sound_ext')
    if has('win32') || has('osx') || len(s:sound_cmd)
      " most systems can play MP3 files
      let g:killersheep_sound_ext = ".mp3"
    else
      " libcanberra defaults to supporting ogg only
      let g:killersheep_sound_ext = ".ogg"
    endif
  endif
endfunc

func s:NextRound()
  call s:Clear()

  let s:round += 1
  let s:sheepcount = 0
  let s:frozen = 0
  call s:ShowBulletSoon()

  " Every once in a while let the next sheep that moves poop.
  let s:wantpoop = 0
  let s:poop_timer = timer_start(s:poop_interval[s:round - 1], {x -> s:WantPoop()}, #{repeat: -1})

  " Create a few sheep to kill.
  let topline = &lines > 50 ? &lines - 50 : 0
  call s:PlaceSheep(topline +  0,  5, 'KillerSheep')
  call s:PlaceSheep(topline +  5, 75, 'KillerSheep2')
  call s:PlaceSheep(topline +  7, 35, 'KillerSheep')
  call s:PlaceSheep(topline + 10, 15, 'KillerSheep')
  call s:PlaceSheep(topline + 12, 70, 'KillerSheep')
  call s:PlaceSheep(topline + 15, 55, 'KillerSheep2')
  call s:PlaceSheep(topline + 20, 15, 'KillerSheep2')
  call s:PlaceSheep(topline + 21, 30, 'KillerSheep')
  call s:PlaceSheep(topline + 22, 60, 'KillerSheep2')
  call s:PlaceSheep(topline + 28, 0, 'KillerSheep')
  call s:ShowLevel(topline)

  let s:canon_id = popup_create(['  /#\  ', ' /###\ ', '/#####\'], #{
	\ line: &lines - 2,
	\ highlight: 'KillerCannon',
	\ filter: function('s:MoveCanon'),
	\ zindex: s:cannon_zindex,
	\ mask: [[1,2,1,1], [6,7,1,1], [1,1,2,2], [7,7,2,2]],
	\ mapping: 0,
	\ })
endfunc

func s:ShowLevel(line)
  let s:levelid = popup_create('Level ' .. s:round, #{
	\ line: a:line ? a:line : 1,
	\ border: [],
	\ padding: [0,1,0,1],
	\ highlight: 'KillerLevel'})
endfunc

func s:MoveCanon(id, key)
  if s:frozen
    return
  endif
  let pos = popup_getpos(a:id)

  let move = 0
  if a:key == 'h' && pos.col > 1
    let move = pos.col - 2
  endif
  if a:key == 'l' && pos.col < &columns - 6
    let move = pos.col + 2
  endif
  if move != 0
    call popup_move(a:id, #{col: move})
    if s:bullet_available
      call popup_move(s:bullet_available, #{col: move + 3})
    endif
  endif

  if a:key == ' '
    call s:Fire(pos.col + 3)
  endif
  if a:key == "\e" || a:key == 'x' || a:key == ':'
    call s:Clear()
  endif
  return a:key != ':'
endfunc

const s:bullet_holdoff = 800
const s:bullet_delay = 30
const s:poop_delay = 60
const s:sheep_anim = 40
const s:sheep_explode = 150
const s:cannon_zindex = 100
const s:bullet_zindex = 80
const s:sheep_zindex = 90
const s:poop_interval = [700, 500, 300, 200, 100]
const s:poop_countdown = 300 / s:sheep_anim 
const s:blink_time = 300

const s:sheepSprite = [[
      \ ' o^^) /^^^^^^\ ',
      \ '==___         |',
      \ '     \  ___  _/',
      \ '      ||   ||  '],[
      \ ' o^^) /^^^^^^\ ',
      \ '==___         |',
      \ '     \_ ____ _/',
      \ '       |    |  '],[
      \ ' o^^) /^^^^^^\ ',
      \ '==___         |',
      \ '     \  ___  _/',
      \ '      ||   ||  '],[
      \ ' o^^) /^^^^^^\ ',
      \ '==___         |',
      \ '     \ _ __ _ /',
      \ '      / |  / | '],[
      \ '        /^^^^^^\ ',
      \ '       |        |',
      \ ' O^^)            ',
      \ 'xx___ _         |',
      \ '      \ _____  _/',
      \ '       ||    ||  '],[
      \ '         /^^^^^^\ ',
      \ '        |        |',
      \ '                  ',
      \ ' O^^)             ',
      \ 'XX___             ',
      \ '       \ __  _  _/',
      \ '        ||    ||  ']]
const s:sheepSpriteMask = [[
      \ ' xxxx xxxxxxxx ',
      \ 'xxxxxxxxxxxxxxx',
      \ '     xxxxxxxxxx',
      \ '      xx   xx  '],[
      \ ' xxxx xxxxxxxx ',
      \ 'xxxxxxxxxxxxxxx',
      \ '     xxxxxxxxxx',
      \ '       x    x  '],[
      \ ' xxxx xxxxxxxx ',
      \ 'xxxxxxxxxxxxxxx',
      \ '     xxxxxxxxxx',
      \ '      xx   xx  '],[
      \ ' xxxx xxxxxxxx ',
      \ 'xxxxxxxxxxxxxxx',
      \ '     xxxxxxxxxx',
      \ '      x x  x x '],[
      \ '        xxxxxxxx ',
      \ '       xxxxxxxxxx',
      \ ' xxxx            ',
      \ 'xxxxx xxxxxxxxxxx',
      \ '      xxxxxxxxxxx',
      \ '       xx    xx  '],[
      \ '         xxxxxxxx ',
      \ '        xxxxxxxxxx',
      \ '                  ',
      \ ' xxxx             ',
      \ 'xxxxx             ',
      \ '       xxxxxxxxxxx',
      \ '        xx    xx  ']]

func GetMask(l)
  let mask = []
  for r in range(len(a:l))
    let s = 0
    let e = -1
    let l = a:l[r]
    for c in range(len(l))
      if l[c] == ' '
	let e = c
      elseif e >= s
	call add(mask, [s+1,e+1,r+1,r+1])
	let s = c + 1
	let e = c
      else
	let s = c + 1
      endif
    endfor
    if e >= s
      call add(mask, [s+1,e+1,r+1,r+1])
    endif
  endfor
  return mask
endfunc

let s:sheepMasks = []
for l in s:sheepSpriteMask
  call add(s:sheepMasks, GetMask(l))
endfor

func s:PlaceSheep(line, col, hl)
  let id = popup_create(s:sheepSprite[0], #{
	\ line: a:line,
	\ col: a:col,
	\ highlight: a:hl,
	\ mask: s:sheepMasks[0],
	\ fixed: 1,
	\ zindex: s:sheep_zindex,
        \ wrap: 0,
	\})
  call setwinvar(id, 'left', 0)
  call setwinvar(id, 'dead', 0)
  call timer_start(s:sheep_anim, {x -> s:AnimSheep(id, 1)})
  let s:sheepcount += 1
  sleep 10m
  return id
endfunc

func s:AnimSheep(id, state)
  if s:frozen
    return
  endif
  let pos = popup_getpos(a:id)
  if pos == {}
    return
  endif
  if getwinvar(a:id, 'dead')
    return
  endif
  let left = getwinvar(a:id, 'left')
  if left == 1
    if pos.line > &lines - 11
      call s:PlaySoundForEnd()
    endif
    call popup_setoptions(a:id, #{pos: 'topleft', col: &columns + 1, line: pos.line + 5})
    let left = 0
  elseif pos.col > 1
    call popup_move(a:id, #{col: pos.col - 1})
  else
    if left == 0
      let left = 15
    endif
    call popup_setoptions(a:id, #{pos: 'topright', col: left - 1})
    let left -= 1
  endif
  let poopid = getwinvar(a:id, 'poopid')
  if poopid
    let poopcount = getwinvar(a:id, 'poopcount')
    if poopcount == 1
      " drop the poop
      call popup_close(poopid)
      call setwinvar(a:id, 'poopid', 0)
      call s:Poop(pos.line + 1, left ? left : pos.col + 12)
    else
      call popup_move(poopid, #{col: left ? left + 1 : pos.col + 14,
	    \ line: pos.line + 1})
    endif
    call setwinvar(a:id, 'poopcount', poopcount - 1)
  endif

  call setwinvar(a:id, 'left', left)
  call popup_settext(a:id, s:sheepSprite[a:state])
  call popup_setoptions(a:id, #{mask: s:sheepMasks[a:state]})
  call timer_start(s:sheep_anim, {x -> s:AnimSheep(a:id, a:state == 3 ? 0 : a:state + 1)})

  if left || pos.col < &columns - 14
    if s:wantpoop && !getwinvar(a:id, 'poopid')
      let s:wantpoop = 0
      call setwinvar(a:id, 'poopcount', s:poop_countdown)
      let poopid = popup_create('x', #{
	\ col: left ? left + 1 : pos.col + 14,
	\ line: pos.line + 1,
	\ highlight: 'KillerPoop',
	\ zindex: s:bullet_zindex,
	\ })
      call setwinvar(a:id, 'poopid', poopid)
    endif
  endif
endfunc

func s:KillSheep(id, state)
  let pos = popup_getpos(a:id)
  if pos == {}
    return
  endif
  let poopid = getwinvar(a:id, 'poopid')
  if poopid
    call popup_close(poopid)
  endif
  let left = getwinvar(a:id, 'left')
  if a:state == 6
    let s:sheepcount -= 1
    if s:sheepcount == 0
      call s:PlaySoundForEnd()
    endif
    call popup_close(a:id)
    return
  endif
  call popup_settext(a:id, s:sheepSprite[a:state])
  call popup_setoptions(a:id, #{mask: s:sheepMasks[a:state], line: pos.line - 1, col: pos.col - 1})
  call timer_start(s:sheep_explode, {x -> s:KillSheep(a:id, a:state + 1)})
  call setwinvar(a:id, 'dead', 1)
endfunc

func s:WantPoop()
  let s:wantpoop = 1
endfunc

func s:Poop(line, col)
  if s:frozen
    return
  endif
  let id = popup_create(['|', '|'], #{
	\ col: a:col,
	\ line: a:line,
	\ highlight: 'KillerPoop',
	\ zindex: s:bullet_zindex,
	\ })
  call s:PlaySound('poop')
  call timer_start(s:poop_delay, {x -> s:MovePoop(x, id)}, #{repeat: -1})
endfunc

func s:MovePoop(x, id)
  if s:frozen
    return
  endif
  let pos = popup_getpos(a:id)
  if pos == {}
    call timer_stop(a:x)
    return
  endif
  if pos.line >= &lines - 1
    call popup_close(a:id)
    call timer_stop(a:x)
  else
    call popup_move(a:id, #{line: pos.line + 2})
    let winid = popup_locate(pos.line + 2, pos.col)
    " TODO: no hit if no overlap
    if winid != 0 && winid == s:canon_id
      call s:PlaySoundForEnd()
    endif
  endif
endfunc

func s:ShowBulletSoon()
  let s:bullet_available = 0
  let s:bullet_timer = timer_start(s:bullet_holdoff, {x -> ShowBullet()})
endfunc

func ShowBullet()
  if s:frozen
    return
  endif
  let s:bullet_timer = 0
  let pos = popup_getpos(s:canon_id)
  let s:bullet_available = popup_create(['|', '|'], #{
	\ col: pos.col + 3,
	\ line: &lines - 3,
	\ highlight: 'KillerBullet',
	\ zindex: s:bullet_zindex,
	\ })
endfunc

func s:Fire(col)
  if s:frozen
    return
  endif
  if !s:bullet_available
    return
  endif
  let id = s:bullet_available
  call s:ShowBulletSoon()

  call s:PlaySound('fire')
  call timer_start(s:bullet_delay, {x -> s:MoveBullet(x, id)}, #{repeat: -1})
endfunc

func s:MoveBullet(x, id)
  if s:frozen
    return
  endif
  let pos = popup_getpos(a:id)
  if pos == {}
    call timer_stop(a:x)
    return
  endif
  if pos.line <= 2
    call popup_close(a:id)
    call timer_stop(a:x)
  else
    call popup_move(a:id, #{line: pos.line - 2})
    let winid = popup_locate(pos.line - 2, pos.col)
    if winid != 0 && winid != a:id
      call s:KillSheep(winid, 4)
      if s:sheepcount == 1
	let s:frozen = 1
      endif
      call s:PlaySound('beh')
      call popup_close(a:id)
    endif
  endif
endfunc

func s:PlaySound(name)
  let fname = s:dir .. '/' .. a:name .. g:killersheep_sound_ext
  if has('sound')
    call sound_playfile(fname)
  elseif len(s:sound_cmd)
    call system(s:sound_cmd .. ' ' .. fname .. '&')
  endif
endfunc

func s:BlinkLevel(winid, on)
  call popup_setoptions(a:winid, #{highlight: a:on ? 'KillerLevelX': 'KillerLevel'})
  let s:blink_timer = timer_start(s:blink_time, {x -> s:BlinkLevel(a:winid, !a:on)})
endfunc

func s:PlaySoundForEnd()
  let s:frozen = 1
  if s:sheepcount == 0
    call s:PlaySound('win')
    if s:round == 5
      echomsg 'Amazing, you made it through ALL levels! (did you cheat???)'
      let s:end_timer = timer_start(2000, {x -> s:Clear()})
    else
      call popup_settext(s:levelid, 'Level ' .. (s:round + 1))
      call s:BlinkLevel(s:levelid, 1)
      call timer_start(2000, {x -> s:NextRound()})
    endif
  else
    call s:StopMusic()
    call s:PlaySound('fail')
    let s:end_timer = timer_start(4000, {x -> s:Clear()})
  endif
endfunc

func s:Clear()
  call s:StopMusic()
  if s:intro_timer
    call timer_stop(s:intro_timer)
    let s:intro_timer = 0
  endif
  call popup_clear()
  if get(s:, 'end_timer', 0)
    call timer_stop(s:end_timer)
    let s:end_timer = 0
  endif
  if get(s:, 'ready_timer', 0)
    call timer_stop(s:ready_timer)
    let s:ready_timer = 0
  endif
  if get(s:, 'poop_timer', 0)
    call timer_stop(s:poop_timer)
    let s:poop_timer = 0
  endif
  if get(s:, 'bullet_timer', 0)
    call timer_stop(s:bullet_timer)
    let s:bullet_timer = 0
  endif
  if get(s:, 'blink_timer', 0)
    call timer_stop(s:blink_timer)
    let s:blink_timer = 0
  endif
endfunc


================================================
FILE: plugin/killersheep.vim
================================================
" Silly game to show off new features in Vim 8.2.
" Last Update: 2019 Dec 7
"
" Requirements:
" - feature +textprop
" - feature +sound or command "afplay", "paplay" or "cvlc".
" - Vim patch level 8.1.1705
" - terminal with at least 45 lines
"
" :KillKillKill  start game
"	      l  move cannon right
"	      h  move cannot left
"	<Space>  fire
"	  <Esc>  exit game
"
" By default plays .ogg files on Unix, .mp3 files on MS-Windows.
" Set g:killersheep_sound_ext to overrule, e.g.:
"   let g:killersheep_sound_ext = '.mp3'
"
" Thanks to my colleagues Greg, Martijn and Shannon for the sounds!
"

if get(g:, 'loaded_killersheep', 0)
  finish
endif
let g:loaded_killersheep = 1

let s:dir = expand('<sfile>:h')

command KillKillKill call s:StartKillerSheep()

func s:StartKillerSheep()
  " Check features before loading the autoload file to avoid error messages.
  if !has('patch-8.1.1705')
    call s:Sorry('Sorry, This build of Vim is too old, you need at least 8.1.1705')
    return
  endif
  if !has('textprop')
    call s:Sorry('Sorry, This build of Vim is lacking the +textprop feature')
    return
  endif
  if &lines < 45
    call s:Sorry('Need at least a terminal height of 45 lines')
    return
  endif

  " The implementation is in an autoload file, so that this plugin doesn't
  " take much time when not being used.
  call killersheep#Start(s:dir)
endfunc

func s:Sorry(msg)
  echohl WarningMsg
  echo a:msg
  echohl None
endfunc
Download .txt
gitextract_9tqvlwg2/

├── .gitignore
├── LICENSE
├── README.md
├── autoload/
│   └── killersheep.vim
└── plugin/
    ├── beh.ogg
    ├── fail.ogg
    ├── fire.ogg
    ├── killersheep.vim
    ├── music.ogg
    ├── poop.ogg
    ├── quack.ogg
    └── win.ogg
Condensed preview — 12 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (20K chars).
[
  {
    "path": ".gitignore",
    "chars": 64,
    "preview": "# All platforms\n*.rej\n*.orig\n*.mo\n*.swp\n*~\n\n# Mac OSX\n.DS_Store\n"
  },
  {
    "path": "LICENSE",
    "chars": 265,
    "preview": "The Killersheep game goes under the same license as Vim.\nYou can find the text here: \nhttps://github.com/vim/vim/blob/ma"
  },
  {
    "path": "README.md",
    "chars": 1206,
    "preview": "# killersheep\n\nSilly game to show off the new features of Vim 8.2:\n-   Popup windows with colors and mask\n-   Text prope"
  },
  {
    "path": "autoload/killersheep.vim",
    "chars": 15915,
    "preview": "\" Implementation of the silly game\n\" Use :KillKillKill to start\n\"\n\" Last Update: 2019 Dec 7\n\nlet s:did_init = 0\nlet s:so"
  },
  {
    "path": "plugin/killersheep.vim",
    "chars": 1440,
    "preview": "\" Silly game to show off new features in Vim 8.2.\n\" Last Update: 2019 Dec 7\n\"\n\" Requirements:\n\" - feature +textprop\n\" - "
  }
]

// ... and 7 more files (download for full content)

About this extraction

This page contains the full source code of the vim/killersheep GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 12 files (18.4 KB), approximately 6.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!