;; advice to prevent ido from using flex matches on huge lists of files
;; with enough characters typed and blocking for an absurd amount of time
;; after a stupid typo
;; The value af-ido-flex-fuzzy-limit is the maximum value of the product
;; of the number of characters the user has entered and the number of
;; options in the ido list.
;; The default value was determined experimentally and seemed to be
;; the boundary of sane wait times when this was written.
(defvar af-ido-flex-fuzzy-limit (* 2000 5))
(defadvice ido-set-matches-1 (around my-ido-set-matches-1 activate)
"Conditionally disable flex matching if the list is huge.
This is useful because when the ido list is huge, ido flex matching
spends an eternity in a regex if you make a typo."
(let ((ido-enable-flex-matching (< (* (length (ad-get-arg 0)) (length ido-text))
;; Generic repository differ. Requires textmate.el and mercurial.el.
;; Will use monky or magit if either one is present.
(defun af-generic-diff-repo ()
(let ((root (textmate-project-root)))
(cond ((and (string= (textmate-project-root-type root) "hg") (fboundp 'monky-status)) (monky-status))
((and (string= (textmate-project-root-type root) "git") (fboundp 'magit-status)) (magit-status root))
((format "project diff for %s" root))
(call-process (textmate-project-root-type root) nil t nil "diff")
(setq diff (not (= (point-min) (point-max))))
(global-set-key [(control c)(t)(=)] 'af-generic-diff-repo)
(global-set-key [(control c)(d)] 'af-generic-diff-repo)
(defun af-rotate-list (l)
"Move the head of l to the end of the list."
(append (cdr l) (list (car l))))
(defun af-spacejoin (l)
"Given list of strings l, join them with spaces and return.
Returns the empty string if l is nil."
(reduce '(lambda (x &optional y) (concat x " " (if y y))) l)
(defun pyflakes-this-buffer ()
(compilation-start (concat "cd "
"; pyflakes " (file-name-nondirectory
(lambda (mode) "*pyflakes*")))
(defun hg-check-code ()
(textmate-start-compile-in-root "python contrib/check-code.py `hg man`"
'(lambda (x) "*check-code*") ))
(defun fullscreen ()
(set-frame-parameter nil 'fullscreen
(if (frame-parameter nil 'fullscreen) nil 'fullboth)))
(defun hg-rm-this-file ()
(shell-command-to-string (concat "hg rm " (shell-quote-argument buffer-file-name))))
;; Lifted from http://code.google.com/p/ergoemacs/
(defun select-text-in-quote ()
"Select text between the nearest left and right delimiters.
Delimiters are paired characters: ()<>«»“”‘’「」, including \"\"."
(let (b1 b2)
(setq b1 (point))
(setq b2 (point))
;; Most of this was extracted from show-paren-function in paren.el from an emacs 23 nightly
;; Also, it seems like this really ought to be builtin, but I can't find it.
(defun bounce-to-other-paren ()
(let ((oldpos (point))
(dir (cond ((eq (syntax-class (syntax-after (1- (point)))) 5) -1)
((eq (syntax-class (syntax-after (point))) 4) 1)))
pos mismatch face)
;; Find the other end of the sexp.
;; Determine the range within which to look for a match.
(max (point-min) (- (point) blink-matching-paren-distance))
(min (point-max) (+ (point) blink-matching-paren-distance))))
;; Scan across one sexp within that range.
;; Errors or nil mean there is a mismatch.
(setq pos (scan-sexps (point) dir))
(error (setq pos t mismatch t)))
;; Move back the other way and verify we get back to the
;; starting point. If not, these two parens don't really match.
;; Maybe the one at point is escaped and doesn't really count.
(when (integerp pos)
(unless (condition-case ()
(eq (point) (scan-sexps pos (- dir)))
(setq pos nil)))
;; Highlight the other end of the sexp, or unhighlight if none.
(if (and pos (integerp pos))
(message "No matching other paren found.")
(defun af-set-window-width (&optional columns)
"Make selected window COLUMNS wide.
Interactively, if no argument is given, make selected window 80
(let* ((cols (if (or (not columns) (>= 0 columns)) 80 columns)))
(shrink-window-horizontally (- (window-width) cols))))