Nothing Special   »   [go: up one dir, main page]

Skip to content

Nodejs extension host for vim & neovim, load extensions like VSCode and host language servers.

License

Notifications You must be signed in to change notification settings

neoclide/coc.nvim

Repository files navigation

Logo

Make your Vim/Neovim as smart as VS Code

Software License Actions Codecov Coverage Status Doc Matrix


Custom coc popup menu with snippet support

Custom popup menu with snippet support

Why?

Quick Start

Make sure use Vim >= 9.0.0438 or Neovim >= 0.8.0.

Install nodejs >= 16.18.0:

curl -sL install-node.vercel.app/lts | bash

For vim-plug users:

" Use release branch (recommended)
Plug 'neoclide/coc.nvim', {'branch': 'release'}

" Or build from source code by using npm
Plug 'neoclide/coc.nvim', {'branch': 'master', 'do': 'npm ci'}

in your .vimrc or init.vim, then restart Vim and run :PlugInstall.

Checkout Install coc.nvim for more info.

You have to install coc extensions or configure language servers for LSP support.

Install extensions like this:

:CocInstall coc-json coc-tsserver

Or you can configure a language server in your coc-settings.json(open it using :CocConfig) like this:

{
  "languageserver": {
    "go": {
      "command": "gopls",
      "rootPatterns": ["go.mod"],
      "trace.server": "verbose",
      "filetypes": ["go"]
    }
  }
}

Checkout the wiki for more details:

Checkout :h coc-nvim for Vim interface.

Example Vim configuration

Configuration is required to make coc.nvim easier to work with, since it doesn't change your key-mappings or Vim options. This is done as much as possible to avoid conflict with your other plugins.

❗️Important: Some Vim plugins can change your key mappings. Please use command like:verbose imap <tab> to make sure that your keymap has taken effect.

" https://raw.githubusercontent.com/neoclide/coc.nvim/master/doc/coc-example-config.vim

" May need for Vim (not Neovim) since coc.nvim calculates byte offset by count
" utf-8 byte sequence
set encoding=utf-8
" Some servers have issues with backup files, see #649
set nobackup
set nowritebackup

" Having longer updatetime (default is 4000 ms = 4s) leads to noticeable
" delays and poor user experience
set updatetime=300

" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved
set signcolumn=yes

" Use tab for trigger completion with characters ahead and navigate
" NOTE: There's always complete item selected by default, you may want to enable
" no select by `"suggest.noselect": true` in your configuration file
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config
inoremap <silent><expr> <TAB>
      \ coc#pum#visible() ? coc#pum#next(1) :
      \ CheckBackspace() ? "\<Tab>" :
      \ coc#refresh()
inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"

" Make <CR> to accept selected completion item or notify coc.nvim to format
" <C-g>u breaks current undo, please make your own choice
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

function! CheckBackspace() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion
if has('nvim')
  inoremap <silent><expr> <c-space> coc#refresh()
else
  inoremap <silent><expr> <c-@> coc#refresh()
endif

" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" GoTo code navigation
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use K to show documentation in preview window
nnoremap <silent> K :call ShowDocumentation()<CR>

function! ShowDocumentation()
  if CocAction('hasProvider', 'hover')
    call CocActionAsync('doHover')
  else
    call feedkeys('K', 'in')
  endif
endfunction

" Highlight the symbol and its references when holding the cursor
autocmd CursorHold * silent call CocActionAsync('highlight')

" Symbol renaming
nmap <leader>rn <Plug>(coc-rename)

" Formatting selected code
xmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)

augroup mygroup
  autocmd!
  " Setup formatexpr specified filetype(s)
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  " Update signature help on jump placeholder
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Applying code actions to the selected code block
" Example: `<leader>aap` for current paragraph
xmap <leader>a  <Plug>(coc-codeaction-selected)
nmap <leader>a  <Plug>(coc-codeaction-selected)

" Remap keys for applying code actions at the cursor position
nmap <leader>ac  <Plug>(coc-codeaction-cursor)
" Remap keys for apply code actions affect whole buffer
nmap <leader>as  <Plug>(coc-codeaction-source)
" Apply the most preferred quickfix action to fix diagnostic on the current line
nmap <leader>qf  <Plug>(coc-fix-current)

" Remap keys for applying refactor code actions
nmap <silent> <leader>re <Plug>(coc-codeaction-refactor)
xmap <silent> <leader>r  <Plug>(coc-codeaction-refactor-selected)
nmap <silent> <leader>r  <Plug>(coc-codeaction-refactor-selected)

" Run the Code Lens action on the current line
nmap <leader>cl  <Plug>(coc-codelens-action)

" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server
xmap if <Plug>(coc-funcobj-i)
omap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap af <Plug>(coc-funcobj-a)
xmap ic <Plug>(coc-classobj-i)
omap ic <Plug>(coc-classobj-i)
xmap ac <Plug>(coc-classobj-a)
omap ac <Plug>(coc-classobj-a)

" Remap <C-f> and <C-b> to scroll float windows/popups
if has('nvim-0.4.0') || has('patch-8.2.0750')
  nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
  inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
  inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
  vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
  vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
endif

" Use CTRL-S for selections ranges
" Requires 'textDocument/selectionRange' support of language server
nmap <silent> <C-s> <Plug>(coc-range-select)
xmap <silent> <C-s> <Plug>(coc-range-select)

" Add `:Format` command to format current buffer
command! -nargs=0 Format :call CocActionAsync('format')

" Add `:Fold` command to fold current buffer
command! -nargs=? Fold :call     CocAction('fold', <f-args>)

" Add `:OR` command for organize imports of the current buffer
command! -nargs=0 OR   :call     CocActionAsync('runCommand', 'editor.action.organizeImport')

" Add (Neo)Vim's native statusline support
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

" Mappings for CoCList
" Show all diagnostics
nnoremap <silent><nowait> <space>a  :<C-u>CocList diagnostics<cr>
" Manage extensions
nnoremap <silent><nowait> <space>e  :<C-u>CocList extensions<cr>
" Show commands
nnoremap <silent><nowait> <space>c  :<C-u>CocList commands<cr>
" Find symbol of current document
nnoremap <silent><nowait> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols
nnoremap <silent><nowait> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item
nnoremap <silent><nowait> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item
nnoremap <silent><nowait> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list
nnoremap <silent><nowait> <space>p  :<C-u>CocListResume<CR>

Example Lua configuration

NOTE: This only works in Neovim 0.7.0dev+.

-- https://raw.githubusercontent.com/neoclide/coc.nvim/master/doc/coc-example-config.lua

-- Some servers have issues with backup files, see #649
vim.opt.backup = false
vim.opt.writebackup = false

-- Having longer updatetime (default is 4000 ms = 4s) leads to noticeable
-- delays and poor user experience
vim.opt.updatetime = 300

-- Always show the signcolumn, otherwise it would shift the text each time
-- diagnostics appeared/became resolved
vim.opt.signcolumn = "yes"

local keyset = vim.keymap.set
-- Autocomplete
function _G.check_back_space()
    local col = vim.fn.col('.') - 1
    return col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') ~= nil
end

-- Use Tab for trigger completion with characters ahead and navigate
-- NOTE: There's always a completion item selected by default, you may want to enable
-- no select by setting `"suggest.noselect": true` in your configuration file
-- NOTE: Use command ':verbose imap <tab>' to make sure Tab is not mapped by
-- other plugins before putting this into your config
local opts = {silent = true, noremap = true, expr = true, replace_keycodes = false}
keyset("i", "<TAB>", 'coc#pum#visible() ? coc#pum#next(1) : v:lua.check_back_space() ? "<TAB>" : coc#refresh()', opts)
keyset("i", "<S-TAB>", [[coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"]], opts)

-- Make <CR> to accept selected completion item or notify coc.nvim to format
-- <C-g>u breaks current undo, please make your own choice
keyset("i", "<cr>", [[coc#pum#visible() ? coc#pum#confirm() : "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"]], opts)

-- Use <c-j> to trigger snippets
keyset("i", "<c-j>", "<Plug>(coc-snippets-expand-jump)")
-- Use <c-space> to trigger completion
keyset("i", "<c-space>", "coc#refresh()", {silent = true, expr = true})

-- Use `[g` and `]g` to navigate diagnostics
-- Use `:CocDiagnostics` to get all diagnostics of current buffer in location list
keyset("n", "[g", "<Plug>(coc-diagnostic-prev)", {silent = true})
keyset("n", "]g", "<Plug>(coc-diagnostic-next)", {silent = true})

-- GoTo code navigation
keyset("n", "gd", "<Plug>(coc-definition)", {silent = true})
keyset("n", "gy", "<Plug>(coc-type-definition)", {silent = true})
keyset("n", "gi", "<Plug>(coc-implementation)", {silent = true})
keyset("n", "gr", "<Plug>(coc-references)", {silent = true})


-- Use K to show documentation in preview window
function _G.show_docs()
    local cw = vim.fn.expand('<cword>')
    if vim.fn.index({'vim', 'help'}, vim.bo.filetype) >= 0 then
        vim.api.nvim_command('h ' .. cw)
    elseif vim.api.nvim_eval('coc#rpc#ready()') then
        vim.fn.CocActionAsync('doHover')
    else
        vim.api.nvim_command('!' .. vim.o.keywordprg .. ' ' .. cw)
    end
end
keyset("n", "K", '<CMD>lua _G.show_docs()<CR>', {silent = true})


-- Highlight the symbol and its references on a CursorHold event(cursor is idle)
vim.api.nvim_create_augroup("CocGroup", {})
vim.api.nvim_create_autocmd("CursorHold", {
    group = "CocGroup",
    command = "silent call CocActionAsync('highlight')",
    desc = "Highlight symbol under cursor on CursorHold"
})


-- Symbol renaming
keyset("n", "<leader>rn", "<Plug>(coc-rename)", {silent = true})


-- Formatting selected code
keyset("x", "<leader>f", "<Plug>(coc-format-selected)", {silent = true})
keyset("n", "<leader>f", "<Plug>(coc-format-selected)", {silent = true})


-- Setup formatexpr specified filetype(s)
vim.api.nvim_create_autocmd("FileType", {
    group = "CocGroup",
    pattern = "typescript,json",
    command = "setl formatexpr=CocAction('formatSelected')",
    desc = "Setup formatexpr specified filetype(s)."
})

-- Update signature help on jump placeholder
vim.api.nvim_create_autocmd("User", {
    group = "CocGroup",
    pattern = "CocJumpPlaceholder",
    command = "call CocActionAsync('showSignatureHelp')",
    desc = "Update signature help on jump placeholder"
})

-- Apply codeAction to the selected region
-- Example: `<leader>aap` for current paragraph
local opts = {silent = true, nowait = true}
keyset("x", "<leader>a", "<Plug>(coc-codeaction-selected)", opts)
keyset("n", "<leader>a", "<Plug>(coc-codeaction-selected)", opts)

-- Remap keys for apply code actions at the cursor position.
keyset("n", "<leader>ac", "<Plug>(coc-codeaction-cursor)", opts)
-- Remap keys for apply source code actions for current file.
keyset("n", "<leader>as", "<Plug>(coc-codeaction-source)", opts)
-- Apply the most preferred quickfix action on the current line.
keyset("n", "<leader>qf", "<Plug>(coc-fix-current)", opts)

-- Remap keys for apply refactor code actions.
keyset("n", "<leader>re", "<Plug>(coc-codeaction-refactor)", { silent = true })
keyset("x", "<leader>r", "<Plug>(coc-codeaction-refactor-selected)", { silent = true })
keyset("n", "<leader>r", "<Plug>(coc-codeaction-refactor-selected)", { silent = true })

-- Run the Code Lens actions on the current line
keyset("n", "<leader>cl", "<Plug>(coc-codelens-action)", opts)


-- Map function and class text objects
-- NOTE: Requires 'textDocument.documentSymbol' support from the language server
keyset("x", "if", "<Plug>(coc-funcobj-i)", opts)
keyset("o", "if", "<Plug>(coc-funcobj-i)", opts)
keyset("x", "af", "<Plug>(coc-funcobj-a)", opts)
keyset("o", "af", "<Plug>(coc-funcobj-a)", opts)
keyset("x", "ic", "<Plug>(coc-classobj-i)", opts)
keyset("o", "ic", "<Plug>(coc-classobj-i)", opts)
keyset("x", "ac", "<Plug>(coc-classobj-a)", opts)
keyset("o", "ac", "<Plug>(coc-classobj-a)", opts)


-- Remap <C-f> and <C-b> to scroll float windows/popups
---@diagnostic disable-next-line: redefined-local
local opts = {silent = true, nowait = true, expr = true}
keyset("n", "<C-f>", 'coc#float#has_scroll() ? coc#float#scroll(1) : "<C-f>"', opts)
keyset("n", "<C-b>", 'coc#float#has_scroll() ? coc#float#scroll(0) : "<C-b>"', opts)
keyset("i", "<C-f>",
       'coc#float#has_scroll() ? "<c-r>=coc#float#scroll(1)<cr>" : "<Right>"', opts)
keyset("i", "<C-b>",
       'coc#float#has_scroll() ? "<c-r>=coc#float#scroll(0)<cr>" : "<Left>"', opts)
keyset("v", "<C-f>", 'coc#float#has_scroll() ? coc#float#scroll(1) : "<C-f>"', opts)
keyset("v", "<C-b>", 'coc#float#has_scroll() ? coc#float#scroll(0) : "<C-b>"', opts)


-- Use CTRL-S for selections ranges
-- Requires 'textDocument/selectionRange' support of language server
keyset("n", "<C-s>", "<Plug>(coc-range-select)", {silent = true})
keyset("x", "<C-s>", "<Plug>(coc-range-select)", {silent = true})


-- Add `:Format` command to format current buffer
vim.api.nvim_create_user_command("Format", "call CocAction('format')", {})

-- " Add `:Fold` command to fold current buffer
vim.api.nvim_create_user_command("Fold", "call CocAction('fold', <f-args>)", {nargs = '?'})

-- Add `:OR` command for organize imports of the current buffer
vim.api.nvim_create_user_command("OR", "call CocActionAsync('runCommand', 'editor.action.organizeImport')", {})

-- Add (Neo)Vim's native statusline support
-- NOTE: Please see `:h coc-status` for integrations with external plugins that
-- provide custom statusline: lightline.vim, vim-airline
vim.opt.statusline:prepend("%{coc#status()}%{get(b:,'coc_current_function','')}")

-- Mappings for CoCList
-- code actions and coc stuff
---@diagnostic disable-next-line: redefined-local
local opts = {silent = true, nowait = true}
-- Show all diagnostics
keyset("n", "<space>a", ":<C-u>CocList diagnostics<cr>", opts)
-- Manage extensions
keyset("n", "<space>e", ":<C-u>CocList extensions<cr>", opts)
-- Show commands
keyset("n", "<space>c", ":<C-u>CocList commands<cr>", opts)
-- Find symbol of current document
keyset("n", "<space>o", ":<C-u>CocList outline<cr>", opts)
-- Search workspace symbols
keyset("n", "<space>s", ":<C-u>CocList -I symbols<cr>", opts)
-- Do default action for next item
keyset("n", "<space>j", ":<C-u>CocNext<cr>", opts)
-- Do default action for previous item
keyset("n", "<space>k", ":<C-u>CocPrev<cr>", opts)
-- Resume latest coc list
keyset("n", "<space>p", ":<C-u>CocListResume<cr>", opts)

Articles

Troubleshooting

Try these steps if you experience problems with coc.nvim:

  • Ensure your Vim version >= 8.0 using :version
  • If a service failed to start, use :CocInfo or :checkhealth if you use Neovim
  • Checkout the log of coc.nvim with :CocOpenLog
  • If you have issues with the language server, it's recommended to checkout the language server output

Feedback

Backers

Become a backer and get your image on our README on GitHub with a link to your site.

Contributors

Qiming zhao
Qiming zhao

💻
Heyward Fann
Heyward Fann

💻
Raidou
Raidou

💻
kevinhwang91
kevinhwang91

💻
年糕小豆汤
年糕小豆汤

💻
Avi Dessauer
Avi Dessauer

💻
最上川
最上川

💻
Yatao Li
Yatao Li

💻
wongxy
wongxy

💻
Sam McCall
Sam McCall

💻
Samuel Roeca
Samuel Roeca

💻
Amirali Esmaeili
Amirali Esmaeili

💻
Jack Rowlingson
Jack Rowlingson

💻
Jaehwang Jung
Jaehwang Jung

💻
Antoine
Antoine

💻
Cosmin Popescu
Cosmin Popescu

💻
Duc Nghiem Xuan
Duc Nghiem Xuan

💻
Francisco Lopes
Francisco Lopes

💻
daquexian
daquexian

💻
dependabot[bot]
dependabot[bot]

💻
greenkeeper[bot]
greenkeeper[bot]

💻
Chris Kipp
Chris Kipp

💻
Dmytro Meleshko
Dmytro Meleshko

💻
Kirill Bobyrev
Kirill Bobyrev

💻
Gontran Baerts
Gontran Baerts

💻
Andy
Andy

💻
Cheng JIANG
Cheng JIANG

💻
Corin
Corin

💻
Daniel Zhang
Daniel Zhang

💻
Ferdinand Bachmann
Ferdinand Bachmann

💻
Guangqing Chen
Guangqing Chen

💻
Jade Meskill
Jade Meskill

💻
Jasper Poppe
Jasper Poppe

💻
Jean Jordaan
Jean Jordaan

💻
Kid
Kid

💻
Pieter van Loon
Pieter van Loon

💻
Robert Liebowitz
Robert Liebowitz

💻
Seth Messer
Seth Messer

💻
UncleBill
UncleBill

💻
ZERO
ZERO

💻
fsouza
fsouza

💻
XiaoZhang
XiaoZhang

💻
whyreal
whyreal

💻
yehuohan
yehuohan

💻
バクダンくん
バクダンくん

💻
Raphael
Raphael

💻
tbodt
tbodt

💻
Aaron McDaid
Aaron McDaid

💻
Aasif Versi
Aasif Versi

💻
Abner Silva
Abner Silva

💻
Adam Stankiewicz
Adam Stankiewicz

💻
Adamansky Anton
Adamansky Anton

💻
Ahmed El Gabri
Ahmed El Gabri

💻
Alexandr Kondratev
Alexandr Kondratev

💻
Andrew Shim
Andrew Shim

💻
Andy Lindeman
Andy Lindeman

💻
Augustin
Augustin

💻
Bastien Orivel
Bastien Orivel

💻
Ben Lu
Ben Lu

💻
Ben
Ben

💻
Brendan Roy
Brendan Roy

💻
brianembry
brianembry

💻
br
br

💻
Cason Adams
Cason Adams

💻
Chang Y
Chang Y

💻
Chayoung You
Chayoung You

💻
Chen Lijun
Chen Lijun

💻
Chen Mulong
Chen Mulong

💻
Chris Weyl
Chris Weyl

💻
dezza
dezza

💻
Cody Allen
Cody Allen

💻
Damien Rajon
Damien Rajon

💻
Daniel Eriksson
Daniel Eriksson

💻
Daniel Jenson
Daniel Jenson

💻
David Mejorado
David Mejorado

💻
Deric Pang
Deric Pang

💻
Ding Tao
Ding Tao

💻
Doron Behar
Doron Behar

💻
Egor Kovetskiy
Egor Kovetskiy

💻
ElKowar
ElKowar

💻
Emeliov Dmitrii
Emeliov Dmitrii

💻
Fabian Becker
Fabian Becker

💻
FallenWarrior2k
FallenWarrior2k

💻
Fausto Núñez Alberro
Fausto Núñez Alberro

💻
Felipe Ramos
Felipe Ramos

💻
Fredrik Borg
Fredrik Borg

💻
Gavin Sim
Gavin Sim

💻
Gibson Fahnestock
Gibson Fahnestock

💻
Giovanni Giordano
Giovanni Giordano

💻
Gopal Adhikari
Gopal Adhikari

💻
Hanh Le
Hanh Le

💻
hedy
hedy

💻
Hendrik Lammers
Hendrik Lammers

💻
Henry Barreto
Henry Barreto

💻
Hugo
Hugo

💻
Jackie Li
Jackie Li

💻
Jakub Nowak
Jakub Nowak

💻
James Pickard
James Pickard

💻
Jia Sui
Jia Sui

💻
Ellie Hermaszewska
Ellie Hermaszewska

💻
Joel Bradshaw
Joel Bradshaw

💻
John Carlo Roberto
John Carlo Roberto

💻
Jonas Holst Damtoft
Jonas Holst Damtoft

💻
Jonathan Lehman
Jonathan Lehman

💻
Joosep Alviste
Joosep Alviste

💻
Josa Gesell
Josa Gesell

💻
Joshua Rubin
Joshua Rubin

💻
Julian Grinblat
Julian Grinblat

💻
Julian Valentin
Julian Valentin

💻
KabbAmine
KabbAmine

💻
Kay Gosho
Kay Gosho

💻
Kenny Huynh
Kenny Huynh

💻
Kevin Rambaud
Kevin Rambaud

💻
Kian Cross
Kian Cross

💻
Kristijan Husak
Kristijan Husak

💻
NullVoxPopuli
NullVoxPopuli

💻
Lasse Peters
Lasse Peters

💻
Noel Errenil
Noel Errenil

💻
LinArcX
LinArcX

💻
Liu-Cheng Xu
Liu-Cheng Xu

💻
Marc
Marc

💻
Marius Gawrisch
Marius Gawrisch

💻
Mark Hintz
Mark Hintz

💻
Mathieu Le Tiec
Mathieu Le Tiec

💻
Matt White
Matt White

💻
Matthew Evans
Matthew Evans

💻
Me1onRind
Me1onRind

💻
Qyriad
Qyriad

💻
Narcis B.
Narcis B.

💻
Neur1n
Neur1n

💻
Nicolas Dermine
Nicolas Dermine

💻
Noah
Noah

💻
PENG Rui
PENG Rui

💻
Paco
Paco

💻
Peng Guanwen
Peng Guanwen

💻
Petter Wahlman
Petter Wahlman

💻
Pooya Moradi
Pooya Moradi

💻
Quade Morrison
Quade Morrison

💻
Ralf Vogler
Ralf Vogler

💻
Ran Chen
Ran Chen

💻
Ricardo García Vega
Ricardo García Vega

💻
Rick Jones
Rick Jones

💻
Ryan Christian
Ryan Christian

💻
Salo
Salo

💻
Sam Nolan
Sam Nolan

💻
Saurav
Saurav

💻
Sean Mackesey
Sean Mackesey

💻
Sheel Patel
Sheel Patel

💻
Solomon Ng
Solomon Ng

💻
Sri Kadimisetty
Sri Kadimisetty

💻
Stephen Prater
Stephen Prater

💻
Sune Kibsgaard
Sune Kibsgaard

💻
Aquaakuma
Aquaakuma

💻
Takumi Kawase
Takumi Kawase

💻
The Blob SCP
The Blob SCP

💻
Tomasz N
Tomasz N

💻
Tomoyuki Harada
Tomoyuki Harada

💻
Tony Fettes
Tony Fettes

💻
Tony Narlock
Tony Narlock

💻
Tony Wang
Tony Wang

💻
Victor Quach
Victor Quach

💻
Whisperity
Whisperity

💻
William Turner
William Turner

💻
Xiaochao Dong
Xiaochao Dong

💻
Hugh Hou
Hugh Hou

💻
Jackie Li
Jackie Li

💻
Zachary Freed
Zachary Freed

💻
akiyosi
akiyosi

💻
alexjg
alexjg

💻
aste4
aste4

💻
clyfish
clyfish

💻
dev7ba
dev7ba

💻
diartyz
diartyz

💻
doza-daniel
doza-daniel

💻
equal-l2
equal-l2

💻
fong
fong

💻
hexh
hexh

💻
hhiraba
hhiraba

💻
ic-768
ic-768

💻
javiertury
javiertury

💻
karasu
karasu

💻
kevineato
kevineato

💻
Eduardo Costa
Eduardo Costa

💻
micchy326
micchy326

💻
midchildan
midchildan

💻
minefuto
minefuto

💻
miyanokomiya
miyanokomiya

💻
miyaviee
miyaviee

💻
monkoose
monkoose

💻 🐛
mujx
mujx

💻
mvilim
mvilim

💻
naruaway
naruaway

💻
piersy
piersy

💻
ryantig
ryantig

💻
rydesun
rydesun

💻
sc00ter
sc00ter

💻
smhc
smhc

💻
Sam Kaplan
Sam Kaplan

💻
tasuten
tasuten

💻
todesking
todesking

💻
typicode
typicode

💻
李鸣飞
李鸣飞

💻
Ikko Ashimine
Ikko Ashimine

📖
Rammiah
Rammiah

🐛
Alisue
Alisue

🐛
bigshans
bigshans

📖
Robert Boyd III
Robert Boyd III

🐛
Yuki Iwanaga
Yuki Iwanaga

💻
SpringHack
SpringHack

🐛
Lucas Burns
Lucas Burns

📖
qiqiboy
qiqiboy

💻
timsu92
timsu92

📖
Shawn M Moore
Shawn M Moore

💻
Aaron U'Ren
Aaron U'Ren

🐛
SeniorMars
SeniorMars

📖
牧羊犬真Q
牧羊犬真Q

📖
geraldspreer
geraldspreer

📖
Fabio
Fabio

📖
Li Yunting
Li Yunting

🐛
Jeff L.
Jeff L.

💻
Elliot Winkler
Elliot Winkler

💻
Svetlozar Iliev
Svetlozar Iliev

💻
James Garbutt
James Garbutt

💻
Qingzhou Yue
Qingzhou Yue

💻
Maarten de Vries
Maarten de Vries

💻
A4-Tacks
A4-Tacks

💻
forceofsystem
forceofsystem

💻
lake
lake

💻
David O'Trakoun
David O'Trakoun

📖
aispeaking
aispeaking

💻
Christian Clauss
Christian Clauss

💻
Micah Halter
Micah Halter

💻
Cristiano De Michele
Cristiano De Michele

💻
Yong Jie
Yong Jie

💻
Kira Oakley
Kira Oakley

📖
Merouane Atig
Merouane Atig

📖
Gerald
Gerald

💻
Nicklas Sedlock
Nicklas Sedlock

💻
Adam Tao
Adam Tao

💻
itsf4llofstars
itsf4llofstars

📖
Brian Wo
Brian Wo

📖
Eric Wong
Eric Wong

💻
oxalica
oxalica

💻
Christian Zangl
Christian Zangl

💻
zoumi
zoumi

💻

This project follows the all-contributors specification. Contributions of any kind are welcome!

License

Anti 996