Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
420 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,22 @@ | |||
DESCRIPTION | |||
=========== | |||
|
|||
Runs the Ruby [flog](http://ruby.sadi.st/Flog.html) tool against Ruby code as you write it. Displays the flog score at the beginning of each method in Emacs. | |||
|
|||
[Screenshot](http://peepcode.com/system/uploads/2009/flog-ruby-emacs.png) | |||
|
|||
AUTHOR | |||
------ | |||
|
|||
Geoffrey Grosenbach, [PeepCode](http://peepcode.com) | |||
|
|||
Heavily based on the [pycomplexity.el](http://bitbucket.org/garybernhardt/pycomplexity/) for Emacs by Ignas Mikalajunas. | |||
|
|||
References | |||
---------- | |||
|
|||
* [Source Code](http://github.com/topfunky/emacs-starter-kit/tree/master/vendor/ruby-complexity/) | |||
* [VIM Pycomplexity Video](http://www.vimeo.com/7259161) | |||
* [Gary Bernhardt](http://blog.extracheese.org/) | |||
* [Emacs pycomplexity.el](http://blog.pow.lt/2009/11/27/cyclomatic-complexity-in-emacs/) | |||
|
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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,192 @@ | |||
;;; linum.el --- Display line numbers to the left of buffers | |||
|
|||
;; Copyright (C) 2007, 2008 Markus Triska | |||
|
|||
;; Author: Markus Triska <markus.triska@gmx.at> | |||
;; Keywords: convenience | |||
|
|||
;; This file is free software; you can redistribute it and/or modify | |||
;; it under the terms of the GNU General Public License as published by | |||
;; the Free Software Foundation; either version 3, or (at your option) | |||
;; any later version. | |||
|
|||
;; This file is distributed in the hope that it will be useful, | |||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
;; GNU General Public License for more details. | |||
|
|||
;; You should have received a copy of the GNU General Public License | |||
;; along with GNU Emacs; see the file COPYING. If not, write to | |||
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |||
;; Boston, MA 02110-1301, USA. | |||
|
|||
;;; Commentary: | |||
|
|||
;; Display line numbers for the current buffer. Copy linum.el to your | |||
;; load-path and add to your .emacs: | |||
|
|||
;; (require 'linum) | |||
|
|||
;; Then toggle display of line numbers with M-x linum-mode. To enable | |||
;; line numbering in all buffers, use M-x global-linum-mode. | |||
|
|||
;;; Code: | |||
|
|||
(defconst linum-version "0.9wza") | |||
|
|||
(defvar linum-overlays nil "Overlays used in this buffer.") | |||
(defvar linum-available nil "Overlays available for reuse.") | |||
(defvar linum-before-numbering-hook nil | |||
"Functions run in each buffer before line numbering starts.") | |||
|
|||
(mapc #'make-variable-buffer-local '(linum-overlays linum-available)) | |||
|
|||
(defgroup linum nil | |||
"Show line numbers to the left of buffers" | |||
:group 'convenience) | |||
|
|||
;;;###autoload | |||
(defcustom linum-format 'dynamic | |||
"Format used to display line numbers. Either a format string | |||
like \"%7d\", 'dynamic to adapt the width as needed, or a | |||
function that is called with a line number as its argument and | |||
should evaluate to a string to be shown on that line. See also | |||
`linum-before-numbering-hook'." | |||
:group 'linum | |||
:type 'sexp) | |||
|
|||
(defface linum | |||
'((t :inherit (shadow default))) | |||
"Face for displaying line numbers in the display margin." | |||
:group 'linum) | |||
|
|||
(defcustom linum-eager t | |||
"Whether line numbers should be updated after each command. | |||
The conservative setting `nil' might miss some buffer changes, | |||
and you have to scroll or press C-l to update the numbers." | |||
:group 'linum | |||
:type 'boolean) | |||
|
|||
(defcustom linum-delay nil | |||
"Delay updates to give Emacs a chance for other changes." | |||
:group 'linum | |||
:type 'boolean) | |||
|
|||
;;;###autoload | |||
(define-minor-mode linum-mode | |||
"Toggle display of line numbers in the left marginal area." | |||
:lighter "" ; for desktop.el | |||
(if linum-mode | |||
(progn | |||
(if linum-eager | |||
(add-hook 'post-command-hook (if linum-delay | |||
'linum-schedule | |||
'linum-update-current) nil t) | |||
(add-hook 'after-change-functions 'linum-after-change nil t)) | |||
(add-hook 'window-scroll-functions 'linum-after-scroll nil t) | |||
;; mistake in Emacs: window-size-change-functions cannot be local | |||
(add-hook 'window-size-change-functions 'linum-after-size) | |||
(add-hook 'change-major-mode-hook 'linum-delete-overlays nil t) | |||
(add-hook 'window-configuration-change-hook | |||
'linum-after-config nil t) | |||
(linum-update-current)) | |||
(remove-hook 'post-command-hook 'linum-update-current t) | |||
(remove-hook 'post-command-hook 'linum-schedule t) | |||
(remove-hook 'window-size-change-functions 'linum-after-size) | |||
(remove-hook 'window-scroll-functions 'linum-after-scroll t) | |||
(remove-hook 'after-change-functions 'linum-after-change t) | |||
(remove-hook 'window-configuration-change-hook 'linum-after-config t) | |||
(remove-hook 'change-major-mode-hook 'linum-delete-overlays t) | |||
(linum-delete-overlays))) | |||
|
|||
;;;###autoload | |||
(define-globalized-minor-mode global-linum-mode linum-mode linum-on) | |||
|
|||
(defun linum-on () | |||
(unless (minibufferp) | |||
(linum-mode 1))) | |||
|
|||
(defun linum-delete-overlays () | |||
"Delete all overlays displaying line numbers for this buffer." | |||
(mapc #'delete-overlay linum-overlays) | |||
(setq linum-overlays nil) | |||
(dolist (w (get-buffer-window-list (current-buffer) nil t)) | |||
(set-window-margins w 0))) | |||
|
|||
(defun linum-update-current () | |||
"Update line numbers for the current buffer." | |||
(linum-update (current-buffer))) | |||
|
|||
(defun linum-update (buffer) | |||
"Update line numbers for all windows displaying BUFFER." | |||
(with-current-buffer buffer | |||
(when linum-mode | |||
(setq linum-available linum-overlays) | |||
(setq linum-overlays nil) | |||
(save-excursion | |||
(mapc #'linum-update-window | |||
(get-buffer-window-list buffer nil 'visible))) | |||
(mapc #'delete-overlay linum-available) | |||
(setq linum-available nil)))) | |||
|
|||
(defun linum-update-window (win) | |||
"Update line numbers for the portion visible in window WIN." | |||
(goto-char (window-start win)) | |||
(let ((line (line-number-at-pos)) | |||
(limit (window-end win t)) | |||
(fmt (cond ((stringp linum-format) linum-format) | |||
((eq linum-format 'dynamic) | |||
(let ((w (length (number-to-string | |||
(count-lines (point-min) (point-max)))))) | |||
(concat "%" (number-to-string w) "d"))))) | |||
(width 0)) | |||
(run-hooks 'linum-before-numbering-hook) | |||
;; Create an overlay (or reuse an existing one) for each | |||
;; line visible in this window, if necessary. | |||
(while (and (not (eobp)) (<= (point) limit)) | |||
(let* ((str (if fmt | |||
(propertize (format fmt line) 'face 'linum) | |||
(funcall linum-format line))) | |||
(visited (catch 'visited | |||
(dolist (o (overlays-in (point) (point))) | |||
(when (string= (overlay-get o 'linum-str) str) | |||
(unless (memq o linum-overlays) | |||
(push o linum-overlays)) | |||
(setq linum-available (delete o linum-available)) | |||
(throw 'visited t)))))) | |||
(setq width (max width (length str))) | |||
(unless visited | |||
(let ((ov (if (null linum-available) | |||
(make-overlay (point) (point)) | |||
(move-overlay (pop linum-available) (point) (point))))) | |||
(push ov linum-overlays) | |||
(overlay-put ov 'before-string | |||
(propertize " " 'display `((margin left-margin) ,str))) | |||
(overlay-put ov 'linum-str str)))) | |||
(forward-line) | |||
(setq line (1+ line))) | |||
(set-window-margins win width))) | |||
|
|||
(defun linum-after-change (beg end len) | |||
;; update overlays on deletions, and after newlines are inserted | |||
(when (or (= beg end) | |||
(= end (point-max)) | |||
;; TODO: use string-match-p with CVS or new release | |||
(string-match "\n" (buffer-substring-no-properties beg end))) | |||
(linum-update-current))) | |||
|
|||
(defun linum-after-scroll (win start) | |||
(linum-update (window-buffer win))) | |||
|
|||
(defun linum-after-size (frame) | |||
(linum-after-config)) | |||
|
|||
(defun linum-schedule () | |||
;; schedule an update; the delay gives Emacs a chance for display changes | |||
(run-with-idle-timer 0 nil #'linum-update-current)) | |||
|
|||
(defun linum-after-config () | |||
(walk-windows (lambda (w) (linum-update (window-buffer w))) nil 'visible)) | |||
|
|||
(provide 'linum) | |||
;;; linum.el ends here |
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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,165 @@ | |||
;;; ruby-complexity.el --- Display ruby code complexity to the left of buffers | |||
|
|||
;; Modified from pycomplexity.el by Geoffrey Grosenbach http://peepcode.com | |||
|
|||
;; Copyright (C) 2009 Ignas Mikalajunas | |||
|
|||
;; Author: Ignas Mikalajunas | |||
;; Keywords: convenience | |||
|
|||
;; This file is free software; you can redistribute it and/or modify | |||
;; it under the terms of the GNU General Public License as published by | |||
;; the Free Software Foundation; either version 3, or (at your option) | |||
;; any later version. | |||
|
|||
;; This file is distributed in the hope that it will be useful, | |||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
;; GNU General Public License for more details. | |||
|
|||
;; You should have received a copy of the GNU General Public License | |||
;; along with GNU Emacs; see the file GPL.txt . If not, write to | |||
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |||
;; Boston, MA 02110-1301, USA. | |||
|
|||
;;; Commentary: | |||
|
|||
;; Display complexity information for the current buffer. | |||
|
|||
;; Add to your .emacs: | |||
|
|||
;; (add-to-list 'load-path "~/.site-lisp/ruby-complexity/") | |||
|
|||
;; (require 'linum) | |||
;; (require 'ruby-complexity) | |||
;; (add-hook 'ruby-mode-hook | |||
;; (function (lambda () | |||
;; (flymake-mode) | |||
;; (linum-mode) | |||
;; (ruby-complexity-mode)))) | |||
;; | |||
;; NOTE: Also needs flymake-mode and the Ruby flog gem. | |||
|
|||
;;; Code: | |||
|
|||
(defconst ruby-complexity-version "0.1") | |||
|
|||
(defvar complexity-bad-score 30 | |||
"Complexities greater than this will be marked bad.") | |||
(make-variable-buffer-local 'complexity-bad-score) | |||
(defvar complexity-good-score 15 | |||
"Complexities lower than this will be marked good.") | |||
(make-variable-buffer-local 'complexity-bad-score) | |||
|
|||
|
|||
(defvar complexity-last-change 0 "Time last change to some ruby buffer happened.") | |||
(defvar complexity-data nil "Calcuated code complexity information for this buffer.") | |||
(make-variable-buffer-local 'complexity-data) | |||
|
|||
(defgroup ruby-complexity nil | |||
"Show complexity information to the left of buffers" | |||
:group 'convenience) | |||
|
|||
(defface ruby-complexity-complexity-low | |||
'((t (:foreground "#2A4A04"))) | |||
"Face that marks simple code " | |||
:group 'ruby-complexity) | |||
|
|||
(defface ruby-complexity-complexity-normal | |||
'((t (:foreground "#72CA09"))) | |||
"Face that marks normal code " | |||
:group 'ruby-complexity) | |||
|
|||
(defface ruby-complexity-complexity-high | |||
'((t (:foreground "#AD0C08"))) | |||
"Face that marks complex code " | |||
:group 'ruby-complexity) | |||
|
|||
(defcustom ruby-complexity-delay 20 | |||
"Update coverage information once in this many seconds." | |||
:group 'ruby-complexity | |||
:type 'int) | |||
|
|||
(defcustom ruby-complexity-ruby "ruby" | |||
"Ruby interpreter used to run the complexity calculation script." | |||
:group 'ruby-complexity | |||
:type 'string) | |||
|
|||
(defcustom ruby-complexity-script | |||
(expand-file-name "ruby-complexity.rb" | |||
(file-name-directory (or load-file-name buffer-file-name))) | |||
"Ruby-Complexity script." | |||
:group 'ruby-complexity | |||
:type 'string) | |||
|
|||
;;;###autoload | |||
(define-minor-mode ruby-complexity-mode | |||
"Toggle display complexity of the Ruby code you are editing." | |||
:lighter "" ; for desktop.el | |||
(if ruby-complexity-mode | |||
(progn | |||
(add-hook 'after-change-functions 'ruby-complexity-on-change nil t) | |||
(add-hook 'after-save-hook 'ruby-complexity-on-change-force nil t) | |||
(setf linum-format 'ruby-complexity-line-format) | |||
(ruby-complexity-on-change-force)) | |||
(setf linum-format 'dynamic) | |||
(remove-hook 'after-change-functions 'ruby-complexity-on-change t))) | |||
|
|||
(defun ruby-complexity-get-complexity (line data) | |||
(multiple-value-bind (face str complexity) | |||
(loop for info in data | |||
for from = (first info) | |||
for to = (second info) | |||
for complexity = (third info) | |||
when (and (>= line from) | |||
(<= line to)) | |||
return (cond ((> complexity complexity-bad-score) (values 'ruby-complexity-complexity-high (number-to-string complexity) complexity)) | |||
((> complexity complexity-good-score) (values 'ruby-complexity-complexity-normal (number-to-string complexity) complexity)) | |||
(t (values 'ruby-complexity-complexity-low (number-to-string complexity) complexity))) | |||
when (< line from) | |||
return (values 'default " " 0)) | |||
(if face (values face str complexity) | |||
(values 'default " " 0)))) | |||
|
|||
(defun ruby-complexity-line-format (line) | |||
(multiple-value-bind (face str complexity) | |||
(ruby-complexity-get-complexity line complexity-data) | |||
(propertize str 'face face | |||
'help-echo (format "Complexity of this function is %d" complexity)))) | |||
|
|||
|
|||
(defun ruby-complexity-make-buffer-copy () | |||
(let* ((source-file-name buffer-file-name) | |||
(file-name (flymake-create-temp-inplace source-file-name "complexity"))) | |||
(make-directory (file-name-directory file-name) 1) | |||
(write-region nil nil file-name nil 566) | |||
file-name)) | |||
|
|||
(defun ruby-complexity-get-raw-complexity-data (file-name) | |||
(shell-command-to-string (format "%s %s %s" | |||
ruby-complexity-ruby | |||
ruby-complexity-script | |||
file-name))) | |||
|
|||
(defun ruby-complexity-on-change-force (&optional beg end len) | |||
(ruby-complexity-on-change beg end len t)) | |||
|
|||
;; TODO: Should use built-in emacs timer as shown here: | |||
;; http://github.com/technomancy/dotfiles/blob/master/.emacs.old/idle-highlight.el | |||
(defun ruby-complexity-on-change (&optional beg end len force) | |||
(let ((since-last-change (- (float-time) complexity-last-change))) | |||
(when (or (> since-last-change ruby-complexity-delay) force) | |||
(setf complexity-last-change (float-time)) | |||
(let* ((temp-source-file-name (ruby-complexity-make-buffer-copy)) | |||
(result (ruby-complexity-get-raw-complexity-data temp-source-file-name)) | |||
(data (loop for line in (split-string result "[\n\r]+") | |||
for parsed-line = (loop for item in (split-string line) | |||
when item collect (read item)) | |||
when (and parsed-line | |||
(equal (car (last parsed-line)) 'function)) | |||
collect (subseq parsed-line 0 3)))) | |||
(when data (setf complexity-data data)) | |||
(delete-file temp-source-file-name))))) | |||
|
|||
(provide 'ruby-complexity) | |||
;;; ruby-complexity.el ends here |
Oops, something went wrong.