Closed cfsalguero closed 9 years ago
just removed syntastic and all its configuration. There is a link to my config in a previous msg
@cfsalguero so with only syntastic but no YCM you have no problem, with YCM and no syntastic you have no problem, but with syntastic and YCM you have a slow experience??
Really don't know what to say. I can give you the steps I did: 1) removed all plugins 2) removed go 3) reinstalled go 4) started from the very basic config 5) started to install 1 by 1 6) disabled syntastic because it started to work slow again Those were my steps. For me is very annoying too.
Just as a comment, depending on the file I'm still have slowness so I decided to use just a plain vim
@cfsalguero if the project is Open Source could you share it?
Sadly, no
Hi again. First I want to thank you for taking care of this. I know you work for free and I really appreciate it and I'm really thankful. Second, I want to apologize for not being able to provide you with better information. I did this in my vim to try to have more information:
:profile start profile.log :profile func :profile file " At this point did slow actions " for example, I have a line that says something like this "Db.TruncateTables([]string{"table1", "table2", "table3", "table4"}) " and when I try to add a new table between quotes or I try to delete the quotes AND the text, the editor becomes unusable. :profile pause
and this is the result in the log file. I hope it helps. FUNCTION gitgutter#process_buffer() Called 1 time Total time: 0.000166 Self time: 0.000066
count total (s) self (s) 1 0.000032 0.000011 call gitgutter#utility#set_buffer(a:bufnr) 1 0.000081 0.000008 if gitgutter#utility#is_active() 1 0.000002 if g:gitgutter_sign_column_always call gitgutter#sign#add_dummy_sign() endif 1 0.000002 try 1 0.000013 0.000007 if !a:realtime || gitgutter#utility#has_fresh_changes() let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(), 1) call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(diff)) let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())
if len(modified_lines) > g:gitgutter_max_signs
call gitgutter#utility#warn('exceeded maximum number of signs (configured by g:gitgutter_max_signs).')
call gitgutter#sign#clear_signs()
return
endif
if g:gitgutter_signs || g:gitgutter_highlight_lines
call gitgutter#sign#update_signs(modified_lines)
endif
call gitgutter#utility#save_last_seen_change()
endif
1 0.000001 catch /diff failed/
call gitgutter#hunk#reset()
endtry
1 0.000001 else
call gitgutter#hunk#reset()
endif
FUNCTION
count total (s) self (s) 57 0.001823 0.000238 if !s:AllowedToCompleteInCurrentFile() return endif
57 0.040154 0.000238 call s:OnFileReadyToParse() 57 0.006591 py ycm_state.OnCursorMoved()
FUNCTION
count total (s) self (s) 59 0.000640 0.000395 let should_display_diagnostics = g:ycm_show_diagnostics_ui && s:DiagnosticUiSupportedForCurrentFiletype() && pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
59 0.000065 if !should_display_diagnostics 59 0.000040 return endif
py ycm_state.UpdateDiagnosticInterface()
FUNCTION gitgutter#utility#not_git_dir() Called 1 time Total time: 0.000041 Self time: 0.000024
count total (s) self (s) 1 0.000040 0.000023 return gitgutter#utility#full_path_to_directory_of_file() !~ '[/].git($|[/])'
FUNCTION
count total (s) self (s) " Some plugins (I'm looking at you, vim-notes) change completeopt by for " instance adding 'longest'. This breaks YCM. So we force our settings. " There's no two ways about this: if you want to use YCM then you have to " have these completeopt settings, otherwise YCM won't work at all.
" We need menuone in completeopt, otherwise when there's only one candidate
" for completion, the menu doesn't show up.
1 0.000006 set completeopt-=menu
1 0.000002 set completeopt+=menuone
" This is unnecessary with our features. People use this option to insert
" the common prefix of all the matches and then add more differentiating chars
" so that they can select a more specific match. With our features, they
" don't need to insert the prefix; they just type the differentiating chars.
" Also, having this option set breaks the plugin.
1 0.000002 set completeopt-=longest
1 0.000002 if g:ycm_add_preview_to_completeopt
set completeopt+=preview
endif
FUNCTION
count total (s) self (s) 2 0.000017 let current_position = getpos('.') 2 0.000005 let s:cursor_moved = current_position != s:old_cursor_position
2 0.000009 let s:moved_vertically_in_insert_mode = s:old_cursor_position != [] && current_position[ 1 ] != s:old_cursor_position[ 1 ]
2 0.000004 let s:old_cursor_position = current_position
FUNCTION gitgutter#utility#set_buffer() Called 1 time Total time: 0.000021 Self time: 0.000021
count total (s) self (s) 1 0.000004 let s:bufnr = a:bufnr 1 0.000016 let s:file = resolve(bufname(a:bufnr))
FUNCTION
count total (s) self (s) 1 0.000037 0.000008 if !s:AllowedToCompleteInCurrentFile() return endif
1 0.000026 0.000008 call s:SetUpCompleteopt()
1 0.000059 0.000007 call s:OnFileReadyToParse()
FUNCTION
count total (s) self (s) 1 0.000050 0.000009 if !s:AllowedToCompleteInCurrentFile() return endif
1 0.000003 let s:omnifunc_mode = 0
1 0.000050 0.000005 call s:OnFileReadyToParse()
1 0.002529 py ycm_state.OnInsertLeave()
1 0.000005 if g:ycm_autoclose_preview_window_after_completion || g:ycm_autoclose_preview_window_after_insertion
call s:ClosePreviewWindowIfNeeded()
endif
FUNCTION
count total (s) self (s) " Remove any previous match. 76 0.000591 if exists('w:paren_hl_on') && w:paren_hl_on 5 0.000018 3match none 5 0.000018 let w:paren_hl_on = 0 5 0.000008 endif
" Avoid that we remove the popup menu.
" Return when there are no colors (looks like the cursor jumps).
76 0.000398 if pumvisible() || (&t_Co < 8 && !has("gui_running")) return endif
" Get the character under the cursor and check if it's in 'matchpairs'.
76 0.000240 let c_lnum = line('.') 76 0.000212 let c_col = col('.') 76 0.000076 let before = 0
76 0.000401 let c = getline(c_lnum)[c_col - 1] 76 0.001166 let plist = split(&matchpairs, '.\zs[:,]') 76 0.000265 let i = index(plist, c) 76 0.000087 if i < 0 " not found, in Insert mode try character before the cursor 72 0.000247 if c_col > 1 && (mode() == 'i' || mode() == 'R') 2 0.000003 let before = 1 2 0.000006 let c = getline(c_lnum)[c_col - 2] 2 0.000006 let i = index(plist, c) 2 0.000001 endif 72 0.000065 if i < 0 " not found, nothing to do 71 0.000068 return endif 1 0.000001 endif
" Figure out the arguments for searchpairpos().
5 0.000006 if i % 2 == 0
3 0.000004 let s_flags = 'nW'
3 0.000010 let c2 = plist[i + 1]
3 0.000003 else
2 0.000004 let s_flags = 'nbW'
2 0.000004 let c2 = c
2 0.000004 let c = plist[i - 1]
2 0.000001 endif
5 0.000009 if c == '['
2 0.000002 let c = '\['
2 0.000003 let c2 = '\]'
2 0.000001 endif
" Find the match. When it was just before the cursor move it there for a
" moment.
5 0.000005 if before > 0
1 0.000004 let save_cursor = winsaveview()
1 0.000004 call cursor(c_lnum, c_col - before)
1 0.000000 endif
" When not in a string or comment ignore matches inside them.
" We match "escape" for special items, such as lispEscapeSpecial.
5 0.000019 let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' . '=~? "string\\|character\\|singlequote\\|escape\\|comment"'
5 0.005092 execute 'if' s_skip '| let s_skip = 0 | endif'
" Limit the search to lines visible in the window.
5 0.000017 let stoplinebottom = line('w$')
5 0.000012 let stoplinetop = line('w0')
5 0.000005 if i % 2 == 0
3 0.000005 let stopline = stoplinebottom
3 0.000002 else
2 0.000003 let stopline = stoplinetop
2 0.000002 endif
" Limit the search time to 300 msec to avoid a hang on very long lines.
" This fails when a timeout is not supported.
5 0.000011 if mode() == 'i' || mode() == 'R'
1 0.000003 let timeout = exists("b:matchparen_insert_timeout") ? b:matchparen_insert_timeout : g:matchparen_insert_timeout
1 0.000001 else
4 0.000019 let timeout = exists("b:matchparen_timeout") ? b:matchparen_timeout : g:matchparen_timeout
4 0.000001 endif
5 0.000012 try
5 0.002572 let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, timeout)
5 0.000010 catch /E118/
" Can't use the timeout, restrict the stopline a bit more to avoid taking
" a long time on closed folds and long lines.
" The "viewable" variables give a range in which we can scroll while
" keeping the cursor at the same position.
" adjustedScrolloff accounts for very large numbers of scrolloff.
let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
" one of these stoplines will be adjusted below, but the current values are
" minimal boundaries within the current window
if i % 2 == 0
if has("byte_offset") && has("syntax_items") && &smc > 0
let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
let stopline = min([bottom_viewable, byte2line(stopbyte)])
else
let stopline = min([bottom_viewable, c_lnum + 100])
endif
let stoplinebottom = stopline
else
if has("byte_offset") && has("syntax_items") && &smc > 0
let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
let stopline = max([top_viewable, byte2line(stopbyte)])
else
let stopline = max([top_viewable, c_lnum - 100])
endif
let stoplinetop = stopline
endif
let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)
endtry
5 0.000007 if before > 0
1 0.000017 call winrestview(save_cursor)
1 0.000001 endif
" If a match is found setup match highlighting.
5 0.000014 if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom
5 0.000122 exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) . 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
5 0.000009 let w:paren_hl_on = 1
5 0.000005 endif
FUNCTION gitgutter#utility#has_fresh_changes() Called 1 time Total time: 0.000006 Self time: 0.000006
count total (s) self (s) 1 0.000005 return getbufvar(s:bufnr, 'changedtick') != getbufvar(s:bufnr, 'gitgutter_last_tick')
FUNCTION
count total (s) self (s) 62 0.000616 if empty( &filetype ) || getbufvar( winbufnr( winnr() ), "&buftype" ) ==# 'nofile' || &filetype ==# 'qf' return 0 endif
62 0.000140 if exists( 'b:ycm_largefile' ) return 0 endif
62 0.000339 let whitelist_allows = has_key( g:ycm_filetype_whitelist, '*' ) || has_key( g:ycm_filetype_whitelist, &filetype ) 62 0.000199 let blacklist_allows = !has_key( g:ycm_filetype_blacklist, &filetype )
62 0.000116 return whitelist_allows && blacklist_allows
FUNCTION
count total (s) self (s) 1 0.000047 0.000007 if !s:AllowedToCompleteInCurrentFile() return endif
1 0.000003 let s:old_cursor_position = []
FUNCTION
count total (s) self (s) 59 0.000349 let b:ycm_changedtick = get( b:, 'ycm_changedtick', { 'file_ready_to_parse' : -1, } )
FUNCTION gitgutter#utility#full_path_to_directory_of_file() Called 1 time Total time: 0.000017 Self time: 0.000017
count total (s) self (s) 1 0.000016 return fnamemodify(s:file, ':p:h')
FUNCTION
count total (s) self (s) " We need to call this just in case there is no b:ycm_changetick; this can " happen for special buffers. 59 0.000589 0.000217 call s:SetUpYcmChangedTick()
" Order is important here; we need to extract any done diagnostics before
" reparsing the file again. If we sent the new parse request first, then
" the response would always be pending when we called
" UpdateDiagnosticNotifications.
59 0.001046 0.000221 call s:UpdateDiagnosticNotifications()
59 0.000171 let buffer_changed = b:changedtick != b:ycm_changedtick.file_ready_to_parse 59 0.000056 if buffer_changed 17 0.037587 py ycm_state.OnFileReadyToParse() 17 0.000033 endif 59 0.000169 let b:ycm_changedtick.file_ready_to_parse = b:changedtick
FUNCTION gitgutter#utility#exists_file() Called 1 time Total time: 0.000018 Self time: 0.000018
count total (s) self (s) 1 0.000018 return filereadable(s:file)
FUNCTION
count total (s) self (s) 2 0.000002 if s:moved_vertically_in_insert_mode 1 0.000002 let s:previous_num_chars_on_current_line = -1 1 0.000001 return 0 endif
1 0.000003 let num_chars_in_current_cursor_line = strlen( getline('.') )
1 0.000002 if s:previous_num_chars_on_current_line == -1
let s:previous_num_chars_on_current_line = num_chars_in_current_cursor_line
return 0
endif
1 0.000003 let changed_text_on_current_line = num_chars_in_current_cursor_line != s:previous_num_chars_on_current_line
1 0.000002 let s:previous_num_chars_on_current_line = num_chars_in_current_cursor_line
1 0.000001 return changed_text_on_current_line
FUNCTION gitgutter#utility#is_active() Called 1 time Total time: 0.000073 Self time: 0.000014
count total (s) self (s) 1 0.000072 0.000013 return g:gitgutter_enabled && gitgutter#utility#exists_file() && gitgutter#utility#not_git_dir()
FUNCTION
count total (s) self (s) 59 0.000205 return get( s:diagnostic_ui_filetypes, &filetype, 0 )
FUNCTION
count total (s) self (s) 2 0.000074 0.000009 if !s:AllowedToCompleteInCurrentFile() return endif
2 0.000220 py ycm_state.OnCursorMoved()
2 0.000051 0.000012 call s:UpdateCursorMoved()
" Basically, we need to only trigger the completion menu when the user has
" inserted or deleted a character, NOT just when the user moves in insert mode
" (with, say, the arrow keys). If we trigger the menu even on pure moves, then
" it's impossible to move in insert mode since the up/down arrows start moving
" the selected completion in the completion menu. Yeah, people shouldn't be
" moving in insert mode at all (that's what normal mode is for) but explain
" that to the users who complain...
2 0.000034 0.000010 if !s:BufferTextChangedSinceLastMoveInInsertMode()
2 0.000001 return
endif
call s:IdentifierFinishedOperations()
if g:ycm_autoclose_preview_window_after_completion
call s:ClosePreviewWindowIfNeeded()
endif
if g:ycm_auto_trigger || s:omnifunc_mode
call s:InvokeCompletion()
endif
" We have to make sure we correctly leave omnifunc mode even when the user
" inserts something like a "operator[]" candidate string which fails
" CurrentIdentifierFinished check.
if s:omnifunc_mode && !pyeval( 'base.LastEnteredCharIsIdentifierChar()')
let s:omnifunc_mode = 0
endif
FUNCTIONS SORTED ON TOTAL TIME
count total (s) self (s) function
57 0.048729 0.007228
FUNCTIONS SORTED ON SELF TIME
count total (s) self (s) function
59 0.040013 0.038816
@ekfriis so, I've tried it on OS X and even though it's overriding vim-go, I'm not seeing any issues. I think I'll stick with this setup, YCM overrides completion but I still take the rest from vim-go without issues I hope. Thanks!
@ekfriis I've one concern though. Compared to other completion options even on YCM, the one built into YCM for golang is putting function prototype information at the type, instead of directly at the completion text. It looks like non conventional.
Hi @oblitum, glad to hear it is working for you. I'm not totally sure I understand your suggestion, can you give an example of what you think the completion should look like?
@cfsalguero sorry, just realized this fell off my stack. Looking at your profile, it seems the slowest functions are:
57 0.048729 0.007228 70_OnCursorMovedNormalMode() 59 0.040013 0.038816 70_OnFileReadyToParse() 76 0.013880 58_Highlight_Matching_Pair()
@Valloric, it looks like it is spending a lot of time in OnFileReadyToParse - is this normal? As far as I can tell, that is for the omnifunc(?), which should not be called at all in Go w/ the latest YCM.
@ekfriis OnFileReadyToParse the client send the buffer to the server, so ycmd is able to pick up new candidates for the identifier-based engine, and the server would also call the same function on the current semantic completer if it defines said function but the gocode completer does not.
Hi @ekfriis, for example, you may check the C and C++ completion that's displayed by the GIF in the official README, BUT, I think it's not a big issue, since it's not a standard followed by all languages.
Since a couple of days, YCM started to use 99% CPU when using it with Go. I've disabled Syntastic but there is no change. There is any way to make it compile only when saving?