Last active
October 17, 2019 10:27
-
-
Save nuc/9199a627623f2ee940c284745cffd45f to your computer and use it in GitHub Desktop.
vimrc & gvimrc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set macmeta | |
" MacVim GUI mode | |
if has("gui_macvim") | |
" Dark | |
" set macligatures | |
set guifont=Operator\ Mono\ Light:h14 | |
" set guifont=Droid\ Sans\ Mono:h12 | |
" Light | |
" set guifont=Source\ Code\ Pro:h12 | |
set guioptions=egmrt | |
set fuoptions=maxvert,maxhorz | |
set noballooneval | |
au GUIEnter * set fullscreen | |
" resize current buffer by +/- 5 | |
nnoremap <M-Right> :vertical resize -5<CR> | |
nnoremap <M-Left> :vertical resize +5<CR> | |
nnoremap <M-Up> :resize -5<CR> | |
nnoremap <M-Down> :resize +5<CR> | |
nnoremap <Leader>t :BTags<CR> | |
nnoremap <Leader>T :Tags<CR> | |
" Command+Option+Right for next | |
map <D-M-Right> :tabn<CR> | |
" Command+Option+Left for previous | |
map <D-M-Left> :tabp<CR> | |
" Automatically resize splits | |
" when resizing MacVim window | |
autocmd VimResized * wincmd = | |
map <Leader>b :Buffers<CR> | |
map <Leader>h :History<CR> | |
" " CtrlP | |
macmenu &File.New\ Tab key=<D-S-t> | |
" map <D-t> :CtrlPLastMode<CR> | |
map <D-t> :Files<CR> | |
" map <D-r> :CtrlPMRU<CR> | |
map <D-M-l> <C-w>l | |
map <D-M-h> <C-w>h | |
map <D-M-j> <C-w>j | |
map <D-M-k> <C-w>k | |
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set nocompatible | |
filetype on | |
filetype plugin on | |
filetype indent on " file type based indentation | |
" colorscheme hemisu | |
" set background=light | |
" set background=dark | |
" colorscheme hybrid | |
set background=dark | |
colorscheme onehalfdark | |
" colorscheme seti | |
" colorscheme nord | |
" colorscheme onedark | |
" colorscheme hybrid_material | |
let g:hybrid_custom_term_colors = 1 | |
let g:hybrid_reduced_contrast = 1 | |
let g:indent_guides_auto_colors = 0 | |
let g:enable_bold_font = 0 | |
autocmd VimEnter,Colorscheme * :hi IndentGuidesOdd guibg=red ctermbg=3 | |
autocmd VimEnter,Colorscheme * :hi IndentGuidesEven guibg=green ctermbg=4 | |
packadd minpac | |
call minpac#init({ 'verbose': 3 }) | |
" Let minpac handle minpac | |
call minpac#add('k-takata/minpac', {'type':'opt'}) | |
" Core | |
call minpac#add('tpope/vim-sensible') | |
call minpac#add('tpope/vim-surround') | |
call minpac#add('tpope/vim-repeat') | |
call minpac#add('tpope/vim-unimpaired') | |
call minpac#add('tpope/vim-fugitive') | |
call minpac#add('tpope/vim-rhubarb') | |
call minpac#add('tpope/vim-commentary') | |
call minpac#add('kana/vim-textobj-user') | |
call minpac#add('yegappan/greplace') | |
call minpac#add('junegunn/gv.vim') | |
" call minpac#add('justinmk/vim-dirvish') | |
" Tools | |
" call minpac#add('kien/ctrlp.vim') | |
call minpac#add('junegunn/fzf.vim') | |
call minpac#add('scrooloose/nerdtree') | |
call minpac#add('rking/ag.vim') | |
call minpac#add('w0rp/ale') | |
call minpac#add('roxma/nvim-yarp') | |
call minpac#add('roxma/vim-hug-neovim-rpc') | |
call minpac#add('sjl/gundo.vim') | |
call minpac#add('editorconfig/editorconfig-vim') | |
call minpac#add('vimwiki/vimwiki') | |
call minpac#add('airblade/vim-gitgutter') | |
call minpac#add('junegunn/goyo.vim') | |
call minpac#add('amix/vim-zenroom2') | |
call minpac#add('ludovicchabant/vim-gutentags') | |
call minpac#add('Xuyuanp/nerdtree-git-plugin') | |
" call minpac#add('segeljakt/vim-silicon') | |
" Load FZF from homebrew installation | |
set runtimepath^=/usr/local/opt/fzf | |
runtime plugin/fzf.vim | |
" Deoplete & Friends | |
" call minpac#add('Shougo/deoplete.nvim') | |
" call minpac#add('roxma/nvim-yarp') | |
" call minpac#add('roxma/vim-hug-neovim-rpc') | |
" Colors & Themes | |
call minpac#add('agreco/vim-citylights') | |
call minpac#add('nuc/vim-hybrid-material') | |
call minpac#add('noahfrederick/vim-hemisu') | |
call minpac#add('joshdick/onedark.vim') | |
" call minpac#add('trusktr/seti.vim') | |
call minpac#add('flazz/vim-colorschemes') | |
call minpac#add('arcticicestudio/nord-vim') | |
call minpac#add('sonph/onehalf') | |
call minpac#add('kien/rainbow_parentheses.vim') | |
" call minpac#add('ryanoasis/vim-devicons') | |
" Languages | |
call minpac#add('sheerun/vim-polyglot') | |
" call minpac#add('slim-template/vim-slim') | |
" call minpac#add('pangloss/vim-javascript') | |
" call minpac#add('chemzqm/vim-jsx-improve') | |
" call minpac#add('elzr/vim-json') | |
" call minpac#add('wavded/vim-stylus') | |
" " call minpac#add('othree/javascript-libraries-syntax.vim') | |
" call minpac#add('mitermayer/vim-prettier') | |
" call minpac#add('leafgarland/typescript-vim') | |
" call minpac#add('smerrill/vcl-vim-plugin') | |
" call minpac#add('godlygeek/tabular') | |
" call minpac#add('plasticboy/vim-markdown') | |
" call minpac#add('chr4/nginx.vim') | |
" " call minpac#add('carlitux/deoplete-ternjs', {'do': 'silent! !npm install -g ternjs'}) | |
" call minpac#add('chrisbra/Colorizer') | |
" call minpac#add('rust-lang/rust.vim') | |
" call minpac#add('cespare/vim-toml') | |
" call minpac#add('racer-rust/vim-racer') | |
" minpac commands: | |
" command! PackUpdate call minpac#update() | |
" command! PackClean call minpac#clean() | |
" | |
" Define user commands for updating/cleaning the plugins. | |
" Each of them loads minpac, reloads .vimrc to register the | |
" information of plugins, then performs the task. | |
command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update('', {'do': 'call minpac#status()'}) | |
command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean() | |
command! PackStatus packadd minpac | source $MYVIMRC | call minpac#status() | |
" Persistend undo | |
set undodir=~/.vim/undodir | |
set undofile | |
" " Make clipboard work with y and p | |
" set clipboard+=unnamed | |
" | |
let s:coc_extensions = [ | |
\ 'coc-css', | |
\ 'coc-html', | |
\ 'coc-json', | |
\ 'coc-yaml', | |
\ 'coc-tsserver' | |
\ ] | |
call minpac#add('https://github.com/neoclide/coc.nvim') | |
let g:gutentags_file_list_command = 'rg --files --hidden' | |
" Our commands | |
command! ConvertToPureComponent :!jscodeshift -t ~/Code/Github/react-codemod/transforms/pure-component.js %:p --useArrows=true --destructuring=true | |
let mapleader="\\" | |
let &t_Co=256 | |
"Use 24-bit (true-color) mode in Vim/Neovim when outside tmux. | |
"If you're using tmux version 2.2 or later, you can remove the outermost $TMUX check and use tmux's 24-bit color support | |
"(see < http://sunaku.github.io/tmux-24bit-color.html#usage > for more information.) | |
if (empty($TMUX)) | |
"For Neovim > 0.1.5 and Vim > patch 7.4.1799 < https://github.com/vim/vim/commit/61be73bb0f965a895bfb064ea3e55476ac175162 > | |
"Based on Vim patch 7.4.1770 (`guicolors` option) < https://github.com/vim/vim/commit/8a633e3427b47286869aa4b96f2bfc1fe65b25cd > | |
" < https://github.com/neovim/neovim/wiki/Following-HEAD#20160511 > | |
if (has("termguicolors")) | |
set termguicolors | |
endif | |
endif | |
set cursorline | |
set expandtab | |
set modelines=0 | |
set shiftwidth=2 | |
set ttyscroll=10 | |
set encoding=utf-8 | |
set tabstop=2 | |
set nowrap | |
set wrapscan " wrap around | |
set number | |
set expandtab | |
set nowritebackup | |
set noswapfile | |
set nobackup | |
set hlsearch | |
set ignorecase | |
set smartcase | |
let loaded_matchparen=1 " Don't load matchit.vim (paren/bracket matching) | |
set noshowmatch " Don't match parentheses/brackets | |
set nocursorline " Don't paint cursor line | |
set nocursorcolumn " Don't paint cursor column | |
set lazyredraw " Wait to redraw | |
set scrolljump=8 " Scroll 8 lines at a time at bottom/top | |
let html_no_rendering=1 " Don't render italic, bold, links in HTML | |
set hidden | |
set nohlsearch | |
set paste | |
set ttyfast " u got a fast terminal | |
set shell=zsh\ -l | |
set exrc | |
set secure | |
syntax enable | |
let g:enable_bold_font = 0 | |
au BufNewFile * set noeol | |
" NeoComplete | |
" let g:deoplete#enable_at_startup = 1 | |
" inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>" | |
" autocmd FileType css setlocal omnifunc=csscomplete#CompleteCSS | |
" autocmd FileType html,markdown setlocal omnifunc=htmlcomplete#CompleteTags | |
" autocmd FileType javascript setlocal omnifunc=javascriptcomplete#CompleteJS | |
" autocmd FileType python setlocal omnifunc=pythoncomplete#Complete | |
" autocmd FileType xml setlocal omnifunc=xmlcomplete#CompleteTags | |
" autocmd FileType make setlocal noexpandtab | |
" " Set bin if you have many instalations | |
" let g:deoplete#sources#ternjs#timeout = 1 | |
" " Whether to include the types of the completions in the result data. Default: 0 | |
" let g:deoplete#sources#ternjs#types = 1 | |
" " Whether to include the distance (in scopes for variables, in prototypes for | |
" " properties) between the completions and the origin position in the result | |
" " data. Default: 0 | |
" let g:deoplete#sources#ternjs#depths = 1 | |
" " Whether to include documentation strings (if found) in the result data. | |
" " Default: 0 | |
" let g:deoplete#sources#ternjs#docs = 1 | |
" " When on, only completions that match the current word at the given point will | |
" " be returned. Turn this off to get all results, so that you can filter on the | |
" " client side. Default: 1 | |
" let g:deoplete#sources#ternjs#filter = 0 | |
" " Whether to use a case-insensitive compare between the current word and | |
" " potential completions. Default 0 | |
" let g:deoplete#sources#ternjs#case_insensitive = 1 | |
" " When completing a property and no completions are found, Tern will use some | |
" " heuristics to try and return some properties anyway. Set this to 0 to | |
" " turn that off. Default: 1 | |
" let g:deoplete#sources#ternjs#guess = 0 | |
" " Determines whether the result set will be sorted. Default: 1 | |
" let g:deoplete#sources#ternjs#sort = 0 | |
" " When disabled, only the text before the given position is considered part of | |
" " the word. When enabled (the default), the whole variable name that the cursor | |
" " is on will be included. Default: 1 | |
" let g:deoplete#sources#ternjs#expand_word_forward = 0 | |
" " Whether to ignore the properties of Object.prototype unless they have been | |
" " spelled out by at least two characters. Default: 1 | |
" let g:deoplete#sources#ternjs#omit_object_prototype = 0 | |
" " Whether to include JavaScript keywords when completing something that is not | |
" " a property. Default: 0 | |
" let g:deoplete#sources#ternjs#include_keywords = 1 | |
" " If completions should be returned when inside a literal. Default: 1 | |
" let g:deoplete#sources#ternjs#in_literal = 0 | |
" NERDTree | |
nmap <leader>n :NERDTreeToggle<CR> | |
let NERDTreeHighlightCursorline=1 | |
let NERDTreeIgnore = ['.yardoc', 'pkg'] | |
let g:nerdtree_tabs_open_on_gui_startup=1 | |
let g:nerdtree_tabs_autoclose=0 | |
let g:nerdtree_tabs_open_on_gui_startup=0 | |
let g:nerdtree_tabs_smart_startup_focus=0 | |
let g:nerdtree_tabs_open_on_new_tab=1 | |
let NERDTreeQuitOnOpen=0 | |
let g:jsx_ext_required = 0 " Allow JSX in normal JS files | |
" Ale | |
let g:ale_linters = { | |
\ 'javascript': ['eslint'], | |
\ 'html': ['htmlhint'], | |
\} | |
let g:ale_fixers = { | |
\ 'javascript': ['eslint'], | |
\} | |
let g:ale_fix_on_save = 1 | |
let g:rustfmt_autosave = 1 | |
" CtrlP | |
" let g:ctrlp_working_path_mode = 2 | |
" let g:ctrlp_max_depth = 5 | |
" " let g:ctrlp_max_files=20000 | |
" let g:ctrlp_custom_ignore = '\vnode_modules\/(\@)@!|DS_Store|tmp|npm-packages-offline-cache' | |
" let g:ctrlp_follow_symlinks = 1 | |
" if executable('rg') | |
" set grepprg=rg\ --color=never | |
" let g:ctrlp_user_command = "rg %s --files --color=never --glob '!npm-packages-offline-cache'" | |
" let g:ctrlp_use_caching = 0 | |
" endif | |
set wildignore+=*/.git/*,*/tmp/*,*.swp | |
" CtrlP auto cache clearing. | |
" ---------------------------------------------------------------------------- | |
" function! SetupCtrlP() | |
" if exists("g:loaded_ctrlp") && g:loaded_ctrlp | |
" augroup CtrlPExtension | |
" autocmd! | |
" autocmd FocusGained * CtrlPClearCache | |
" autocmd BufWritePost * CtrlPClearCache | |
" augroup END | |
" endif | |
" endfunction | |
" if has("autocmd") | |
" autocmd VimEnter * :call SetupCtrlP() | |
" endif | |
" Fugitive | |
nmap <leader>gb :Gblame<CR> | |
nmap <leader>gs :Gstatus<CR> | |
nmap <leader>gd :Gdiff<CR> | |
nmap <leader>gl :Glog<CR> | |
nmap <leader>gc :Gcommit<CR> | |
nmap <leader>gp :Gpush<CR> | |
" autocmd User fugitive | |
" \ if fugitive#buffer().type() =~# '^\%(tree\|blob\)$' | | |
" \ nnoremap <buffer> .. :edit %:h<CR> | | |
" \ endif | |
" autocmd BufReadPost fugitive://* set bufhidden=delete | |
" For making fugitive work on new tab | |
augroup LaunchFugitiveForAllBuffers | |
autocmd! | |
autocmd BufNew :doautocmd fugitive BufRead . | |
augroup END | |
" GitGutter | |
nmap <Leader>ha <Plug>GitGutterStageHunk | |
nmap <Leader>hr <Plug>GitGutterUndoHunk | |
nmap <Leader>hv <Plug>GitGutterPreviewHunk | |
" Do not hide quotes in json | |
let g:vim_json_syntax_conceal = 0 | |
" JSX Support | |
let g:js_context_colors_jsx = 1 | |
" Leader triggers | |
nmap <Leader>f :NERDTreeFind<CR> | |
nmap <leader>m :Gdiff master<CR> | |
nmap <leader>v :tabedit ~/.vimrc<CR> | |
" Shortcuts | |
nnoremap <F12> :GundoToggle<CR> | |
" map <D-F> :Ggrep<space> | |
map <D-F> :Rg<space> | |
" map <D-F> :grep<space> | |
map <D-/> :Commentary<CR> | |
nnoremap <F12> :GundoToggle<CR> | |
if executable('rg') | |
set grepprg=rg\ --no-heading\ --vimgrep\ --hidden | |
set grepformat=%f:%l:%c:%m | |
endif | |
" No smartcase for * searching | |
nnoremap * /\<<C-R>=expand('<cword>')<CR>\><CR> | |
nnoremap # ?\<<C-R>=expand('<cword>')<CR>\><CR> | |
" No show command | |
autocmd VimEnter * set nosc | |
" format the entire file | |
nmap <leader>fef ggVG= | |
" Dot command active in visual mode | |
xnoremap . :norm.<CR> | |
" Force saving files that require root permission | |
cnoremap w!! w !sudo tee > /dev/null % | |
" Cmd-Return on insert mode | |
" inoremap <D-CR> <C-O>o | |
inoremap <D-CR> <CR><Esc>O | |
"disable sounds | |
set noeb vb t_vb= | |
" Toggle fullscreen | |
map <D-Enter> :set fu!<CR> | |
" auto remove whitespace | |
autocmd BufWritePre * :%s/\s\+$//e | |
" switch between last accessed buffers | |
map <D-`> :e#<CR> | |
map <D-d> <C-w><C-v> | |
map <D-S-d> <C-w><C-s> | |
autocmd QuickFixCmdPost *grep* cwindow | |
"http://stackoverflow.com/a/5686810/422977 | |
command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames() | |
function! QuickfixFilenames() | |
" Building a hash ensures we get each buffer only once | |
let buffer_numbers = {} | |
for quickfix_item in getqflist() | |
let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr']) | |
endfor | |
return join(values(buffer_numbers)) | |
endfunction | |
function! ExtractImdbIds() | |
command! %s/^.*\(tt\d\+\).*$/\1/ | |
endfunction | |
" NerdCommenter | |
let g:NERDSpaceDelims = 1 | |
" Unimpaired | |
" Bubble single lines | |
nmap <D-k> [e | |
nmap <D-j> ]e | |
" Bubble multiple lines | |
vmap <D-k> [egv | |
vmap <D-j> ]egv | |
" EditorConfig | |
let g:EditorConfig_exclude_patterns = ['fugitive://.*', 'scp://.*'] | |
" vim-markdown | |
let g:vim_markdown_folding_disabled = 1 | |
" " https://stackoverflow.com/a/5686810 | |
" command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames() | |
" function! QuickfixFilenames() | |
" " Building a hash ensures we get each buffer only once | |
" let buffer_numbers = {} | |
" for quickfix_item in getqflist() | |
" let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr']) | |
" endfor | |
" return join(values(buffer_numbers)) | |
" endfunction | |
" Better Rainbow Parentheses | |
au VimEnter * RainbowParenthesesToggle | |
au Syntax * RainbowParenthesesLoadRound | |
au Syntax * RainbowParenthesesLoadSquare | |
au Syntax * RainbowParenthesesLoadBraces | |
"Racer | |
let g:racer_cmd = "/Users/nuc/.cargo/bin/racer" | |
"COC | |
" Better display for messages | |
set cmdheight=2 | |
" Smaller updatetime for CursorHold & CursorHoldI | |
set updatetime=300 | |
" don't give |ins-completion-menu| messages. | |
set shortmess+=c | |
" always show signcolumns | |
set signcolumn=yes | |
" Use tab for trigger completion with characters ahead and navigate. | |
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin. | |
inoremap <silent><expr> <TAB> | |
\ pumvisible() ? "\<C-n>" : | |
\ <SID>check_back_space() ? "\<TAB>" : | |
\ coc#refresh() | |
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>" | |
function! s:check_back_space() abort | |
let col = col('.') - 1 | |
return !col || getline('.')[col - 1] =~# '\s' | |
endfunction | |
if has('nvim-0.3.2') || has("patch-8.1.0360") | |
set diffopt=filler,internal,algorithm:histogram,indent-heuristic | |
endif | |
" " Use <c-space> to trigger completion. | |
" inoremap <silent><expr> <c-space> coc#refresh() | |
" " Use <cr> to confirm completion, `<C-g>u` means break undo chain at current position. | |
" " Coc only does snippet and additional edit on confirm. | |
" inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>" | |
" " Use `[c` and `]c` to navigate diagnostics | |
" nmap <silent> [c <Plug>(coc-diagnostic-prev) | |
" nmap <silent> ]c <Plug>(coc-diagnostic-next) | |
" " Remap keys for gotos | |
" nmap <silent> gt <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 <SID>show_documentation()<CR> | |
" function! s:show_documentation() | |
" if (index(['vim','help'], &filetype) >= 0) | |
" execute 'h '.expand('<cword>') | |
" else | |
" call CocAction('doHover') | |
" endif | |
" endfunction | |
" " Highlight symbol under cursor on CursorHold | |
" autocmd CursorHold * silent call CocActionAsync('highlight') | |
" " Remap for rename current word | |
" nmap <leader>rn <Plug>(coc-rename) | |
" " Remap for format selected region | |
" 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 | |
" " Remap for do codeAction of selected region, ex: `<leader>aap` for current paragraph | |
" xmap <leader>a <Plug>(coc-codeaction-selected) | |
" nmap <leader>a <Plug>(coc-codeaction-selected) | |
" " Remap for do codeAction of current line | |
" nmap <leader>ac <Plug>(coc-codeaction) | |
" " Fix autofix problem of current line | |
" nmap <leader>qf <Plug>(coc-fix-current) | |
" " Use `:Format` to format current buffer | |
" command! -nargs=0 Format :call CocAction('format') | |
" " Use `:Fold` to fold current buffer | |
" command! -nargs=? Fold :call CocAction('fold', <f-args>) | |
" " Add diagnostic info for https://github.com/itchyny/lightline.vim | |
" let g:lightline = { | |
" \ 'colorscheme': 'wombat', | |
" \ 'active': { | |
" \ 'left': [ [ 'mode', 'paste' ], | |
" \ [ 'cocstatus', 'readonly', 'filename', 'modified' ] ] | |
" \ }, | |
" \ 'component_function': { | |
" \ 'cocstatus': 'coc#status' | |
" \ }, | |
" \ } | |
" " Using CocList | |
" " Show all diagnostics | |
" nnoremap <silent> <space>a :<C-u>CocList diagnostics<cr> | |
" " Manage extensions | |
" nnoremap <silent> <space>e :<C-u>CocList extensions<cr> | |
" " Show commands | |
" nnoremap <silent> <space>c :<C-u>CocList commands<cr> | |
" " Find symbol of current document | |
" nnoremap <silent> <space>o :<C-u>CocList outline<cr> | |
" " Search workspace symbols | |
" nnoremap <silent> <space>s :<C-u>CocList -I symbols<cr> | |
" " Do default action for next item. | |
" nnoremap <silent> <space>j :<C-u>CocNext<CR> | |
" " Do default action for previous item. | |
" nnoremap <silent> <space>k :<C-u>CocPrev<CR> | |
" " Resume latest coc list | |
" nnoremap <silent> <space>p :<C-u>CocListResume<CR> | |
" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment