diff --git a/README.md b/README.md index 29b4c82..fe64af6 100644 --- a/README.md +++ b/README.md @@ -36,19 +36,11 @@ When this is done add `:silent exe "g:flog_enable"` to your .vimrc file. Configuration ------------- -You can set the colors for the complexity indication with the following commands in your .vimrc: +To change colors of sings, use the `higlight` command. The used groups are -* Set the color of for low complexity:
- `:let g:flog_low_color_hl = "term=standout ctermfg=118 ctermbg=235 guifg=#999999 guibg=#323232"` - -* Set the color of for medium complexity:
- `:let g:flog_medium_color_hl = "term=standout ctermfg=81 ctermbg=235 guifg=#66D9EF guibg=#323232"` - -* Set the color of for high complexity:
- `:let g:flog_high_color_hl = "term=standout cterm=bold ctermfg=199 ctermbg=16 gui=bold guifg=#F92672 guibg=#232526"` - -* Set the background color:
- `:let s:background_hl = "guifg=#999999 guibg=#323232 gui=NONE"` +* SignLowComplexity +* SignMediumComplexity +* SignHighComplexity You can set the limits for the complexity indication with the following commands in your .vimrc: @@ -69,16 +61,16 @@ You can hide some levels of complexity: You can also turn flog off and on: * Turn on flog - `:call EnableFlog()` + `:call FlogEnable()` * Turn off flog - `:call DisableFlog()` + `:call FlogDisable()` * Toggle flog - `:call ToggleFlog()` + `:call FlogToggle()` Additionally, you can map this in your .vimrc: - `:map ,f :call ToggleFlog()` + `:map ,f :call FlogToggle()` Credits ------- diff --git a/plugin/flog.vim b/plugin/flog.vim index 4aafcbc..9bf478b 100644 --- a/plugin/flog.vim +++ b/plugin/flog.vim @@ -9,14 +9,10 @@ if !has('signs') || !has('ruby') finish endif -let s:low_color_hl = "term=standout ctermfg=118 ctermbg=235 guifg=#a5c261 guibg=#323232" -let s:medium_color_hl = "term=standout ctermfg=81 ctermbg=235 guifg=#ffc66d guibg=#323232" -let s:high_color_hl = "term=standout cterm=bold ctermfg=199 ctermbg=16 gui=bold guifg=#cc7833 guibg=#232526" -let s:background_hl = "guifg=#999999 guibg=#323232 gui=NONE" let s:medium_limit = 10 let s:high_limit = 20 -let s:hide_low = 0 -let s:hide_medium = 0 +let s:hide_low = 0 +let s:hide_medium = 0 if exists("g:flog_hide_low") let s:hide_low = g:flog_hide_low @@ -26,22 +22,6 @@ if exists("g:flog_hide_medium") let s:hide_medium = g:flog_hide_medium endif -if exists("g:flog_low_color_hl") - let s:low_color_hl = g:flog_low_color_hl -endif - -if exists("g:flog_medium_color_hl") - let s:medium_color_hl = g:flog_medium_color_hl -endif - -if exists("g:flog_high_color_hl") - let s:high_color_hl = g:flog_high_color_hl -endif - -if exists("g:flog_background_hl") - let s:high_background_hl = g:flog_high_background_hl -endif - if exists("g:flog_medium_limit") let s:medium_limit = g:flog_medium_limit endif @@ -51,79 +31,22 @@ if exists("g:flog_high_limit") endif ruby << EOF - -require 'rubygems' -require 'flog' +begin + require 'rubygems' + require 'flog' + FLOG_LOADED = true +rescue LoadError + FLOG_LOADED = false +end class Flog - def in_method(name, file, line, endline=nil) - endline = line if endline.nil? - method_name = Regexp === name ? name.inspect : name.to_s - @method_stack.unshift method_name - @method_locations[signature] = "#{file}:#{line}:#{endline}" - yield - @method_stack.shift - end - - def process_defn(exp) - in_method exp.shift, exp.file, exp.line, exp.last.line do - process_until_empty exp - end - s() - end - - def process_defs(exp) - recv = process exp.shift - in_method "::#{exp.shift}", exp.file, exp.line, exp.last.line do - process_until_empty exp - end - s() - end - - def process_iter(exp) - context = (self.context - [:class, :module, :scope]) - context = context.uniq.sort_by { |s| s.to_s } - - if context == [:block, :iter] or context == [:iter] then - recv = exp.first - - # DSL w/ names. eg task :name do ... end - if (recv[0] == :call and recv[1] == nil and recv.arglist[1] and - [:lit, :str].include? recv.arglist[1][0]) then - msg = recv[2] - submsg = recv.arglist[1][1] - in_klass msg do - lastline = exp.last.respond_to?(:line) ? exp.last.line : nil # zomg teh hax! - # This is really weird. If a block has nothing in it, then for some - # strange reason exp.last becomes nil. I really don't care why this - # happens, just an annoying fact. - in_method submsg, exp.file, exp.line, lastline do - process_until_empty exp - end - end - return s() - end - end - add_to_score :branch - exp.delete 0 - process exp.shift - penalize_by 0.1 do - process_until_empty exp - end - s() - end - def return_report complexity_results = {} - max = option[:all] ? nil : total * THRESHOLD - each_by_score max do |class_method, score, call_list| + each_by_score(threshold) do |class_method, score, call_list| location = @method_locations[class_method] if location then - line, endline = location.match(/.+:(\d+):(\d+)/).to_a[1..2].map{|l| l.to_i } - # This is a strange case of flog failing on blocks. - # http://blog.zenspider.com/2009/04/parsetree-eol.html - line, endline = endline-1, line if line >= endline - complexity_results[line] = [score, class_method, endline] + line = location.match(/.+:(\d+)/).to_a[1] + complexity_results[line] = [score, class_method] end end complexity_results @@ -133,95 +56,89 @@ class Flog end def show_complexity(results = {}) - VIM.command ":silent sign unplace file=#{VIM::Buffer.current.name}" - results.each do |line_number, rest| - medium_limit = VIM::evaluate('s:medium_limit') - high_limit = VIM::evaluate('s:high_limit') - complexity = case rest[0] - when 0..medium_limit then "low_complexity" - when medium_limit..high_limit then "medium_complexity" - else "high_complexity" + medium_limit = VIM::evaluate('s:medium_limit') + high_limit = VIM::evaluate('s:high_limit') + hide_medium = VIM::evaluate('s:hide_medium') + hide_low = VIM::evaluate('s:hide_low') + + VIM.command ":silent sign unplace * file=#{VIM::Buffer.current.name}" + VIM.command ":sign define FlogDummySign" + VIM.command ":sign place 9999 line=1 name=FlogDummySign file=#{VIM::Buffer.current.name}" + + results.each do |line_number, (score, method)| + complexity = case score + when 0..medium_limit then "LowComplexity" + when medium_limit..high_limit then "MediumComplexity" + else "HighComplexity" + end + value = score >= 100 ? 99 : score.round + value = nil if (hide_low == 1 && value < medium_limit) || (hide_medium == 1 && value < high_limit) + if value + VIM.command ":sign define #{value} text=#{value} texthl=Sign#{complexity}" + VIM.command ":sign place #{line_number} line=#{line_number} name=#{value} file=#{VIM::Buffer.current.name}" end - value = rest[0].to_i - value = "9+" if value >= 100 - VIM.command ":sign define #{value.to_s} text=#{value.to_s} texthl=#{complexity}" - render_score line_number, value, medium_limit, high_limit - end -end - -def render_score(line_number, value, medium_limit, high_limit) - hide_medium = VIM::evaluate 's:hide_medium' - hide_low = VIM::evaluate 's:hide_low' - if (hide_low == 1 && value < medium_limit) || (hide_medium == 1 && value < high_limit) - VIM.command ":sign unplace #{line_number}" - else - VIM.command ":sign place #{line_number} line=#{line_number} name=#{value.to_s} file=#{VIM::Buffer.current.name}" end end - EOF -function! s:UpdateHighlighting() - exe 'hi low_complexity '.s:low_color_hl - exe 'hi medium_complexity '.s:medium_color_hl - exe 'hi high_complexity '.s:high_color_hl - exe 'hi SignColumn '.s:background_hl -endfunction - function! ShowComplexity() - ruby << EOF - -options = { - :quiet => true, - :continue => true, - :all => true - } - -flogger = Flog.new options -flogger.flog ::VIM::Buffer.current.name -show_complexity flogger.return_report - + ignore_files = /_spec/ + + options = { + :quiet => true, + :all => true + } + + if !Vim::Buffer.current.name.match(ignore_files) && FLOG_LOADED + buffer = ::VIM::Buffer.current + # nasty hack, but there is no read all... + code = (1..buffer.count).map{|i| buffer[i]}.join("\n") + + flogger = Flog.new options + flogger.flog_ruby `cat #{::VIM::Buffer.current.name}` + flogger.calculate_total_scores + show_complexity flogger.return_report + end EOF - -call s:UpdateHighlighting() - endfunction function! HideComplexity() - sign unplace * -call s:UpdateHighlighting() - +ruby << EOF + if FLOG_LOADED + VIM.command ":redir @a" + VIM.command ":silent sign place file=#{VIM::Buffer.current.name}" + VIM.command ":redir END" + placed_signs = VIM.evaluate "@a" + placed_signs.lines.map(&:chomp).select{|s| s.include? 'id='}.each do |sign| + id = Hash[*sign.split(' ').map{|s| s.split('=')}.flatten]['id'] + VIM.command ":sign unplace #{id} file=#{VIM::Buffer.current.name}" + end + end +EOF endfunction -function! EnableFlog() - let g:flog_enable=1 - if &filetype == 'ruby' - call ShowComplexity() - endif - autocmd! BufReadPost,BufWritePost,FileReadPost,FileWritePost *.rb call ShowComplexity() +function! FlogDisable() + let g:flog_enable = 0 + call HideComplexity() endfunction +command! FlogDisable call FlogDisable() -function! DisableFlog() - let g:flog_enable=0 - call HideComplexity() - autocmd! BufReadPost,BufWritePost,FileReadPost,FileWritePost *.rb +function! FlogEnable() + let g:flog_enable = 1 + call ShowComplexity() endfunction +command! FlogEnable call FlogEnable() -function! ToggleFlog() - if !exists("g:flog_enable") || g:flog_enable - call DisableFlog() +function! FlogToggle() + if exists("g:flog_enable") && g:flog_enable + call FlogDisable() else - call EnableFlog() - end + call FlogEnable() + endif endfunction - -call s:UpdateHighlighting() - -sign define low_color text=XX texthl=low_complexity -sign define medium_color text=XX texthl=medium_complexity -sign define high_color text=XX texthl=high_complexity +command! FlogToggle call FlogToggle() if !exists("g:flog_enable") || g:flog_enable - call EnableFlog() + au BufReadPost,BufWritePost,FileReadPost,FileWritePost *.rb call ShowComplexity() endif