Switching between buffers with the same major mode in Emacs

Below are functions that can be used to switch to next or previus buffer in the same major mode

(defun buffer-same-mode (change-buffer-fun)
  (let ((current-mode major-mode)
        (next-mode nil))
    (while (not (eq next-mode current-mode))
      (funcall change-buffer-fun)
      (setq next-mode major-mode))))

(defun previous-buffer-same-mode ()
  (buffer-same-mode #'previous-buffer))

(defun next-buffer-same-mode ()
  (buffer-same-mode #'next-buffer))

In my init file I have bind those functions to CTRL+TAB and CTRL+ALT+TAB which was not set by default.

(global-set-key [C-M-tab] 'previous-buffer-same-mode)
(global-set-key [C-tab] 'next-buffer-same-mode)


Leave a comment

Faster buffer bookmarking in Emacs

I wanted to speed up jumping in the same buffer so I have written this bookmarking utility (Similar to built-in registers) and put it in my .emacs file.

(defvar bookmark-markers '())

(defun bookmark (bookmark)
   "Store current position for this buffer in 
    bookmar-markers a-list"
   (interactive "nBookmark: ")
   (let* ((buffer (current-buffer))
           (let ((pair (assoc buffer bookmark-markers)))
             (if (eq pair nil)
                 (let ((new-pair (cons buffer '())))
                     (setq bookmark-markers
                           (append bookmark-markers
                                   (list new-pair)))
     (let ((pair (assoc bookmark bookmarks)))
       (if (eq pair nil)
           (setf (cdr bookmarks)
                 (append (cdr bookmarks)
                         (list (cons bookmark (point)))))
         (setf (cdr pair) (point))))))

(defun jump-to-bookmark (bookmark)
  "Jump to previously stored bookmark position"
  (interactive "nJump To: ")
  (let ((pair-bookmars (assoc (current-buffer) bookmark-markers)))
    (if (not (eq pair-bookmars nil))
        (let ((pair-point (assoc bookmark (cdr pair-bookmars))))
          (if (not (eq pair-point nil))
              (goto-char (cdr pair-point)))))))

(defun range (n &optional list)
  "function return list of numbers from 1 to n"
  (if (eq n 0)
    (let ((n (- n 1)))
      (range n (cons n list)))))

(dolist (i (range 9))
    (global-set-key (read-kbd-macro (concat "C-c "
                                            (number-to-string i)))
                    ;; emacs lisp have no closures
                    (lexical-let ((i i)) 
                      (lambda ()
                        (jump-to-bookmark i)))))

(global-set-key (kbd "C-c 0") 'bookmark)

Above code define 2 functions bookmark bind to C-c 0 and function jump-to-bookmark this function create a bookmark, for currect position in a buffer, and assing it to the number (passed as argument or from minubuffer, if run interactively). You have 9 keyboard binding for keys from C-c 1 to C-c 9.

You can use it go to specific location and type C-c 0 1 RET go to another location and type C-c 0 2 RET and now you can jump to locations with C-c 1 or C-c 2.

Every buffer will have they own bookmarks.


Leave a comment

Matrix manipulation in scheme

Here’s the code I wrote for matrix manipulation in scheme. It use lists.

Procedure that creates new square identity matrix:

(define (make-matrix n)
  (let outter ((i n) (result '()))
    (if (= i 0)
        (outter (- i 1) 
                 (let inner ((j n) (row '()))
                   (if (= j 0)
                       (inner (- j 1) (cons (if (= i j) 1 0) row))))

Procedure that return nth element of the list, which is the same as nth row of the matrix:

(define (nth list n)
  (let iter ((n n) (result list))
    (if (= n 0)
        (car result)
        (iter (- n 1)
              (cdr result)))))

(define matrix-row nth)

Procedure that return nth column of the matrix:

(define (matrix-col M n)
  (let iter ((i (length M)) (result '()))
    (if (= i 0)
        (iter (- i 1)
              (cons (nth (nth M (- i 1)) n) result)))))

Procedure for multiplication of two matrices:

(define (matrix-mul N M)
  (let rows ((i (length N)) (result '()))
    (if (= i 0)
        (rows (- i 1)
               (let cols ((j (length (car M))) (row '()))
                 (if (= j 0)
                      (- j 1)
                      (cons (reduce + (map *
                                           (matrix-row N (- i 1))
                                           (matrix-col M (- j 1))))

For above procedure you will need reduce procedure:

(define (reduce fun lst)
  (let iter ((result (car lst)) (lst (cdr lst)))
    (if (null? lst)
        (iter (fun result (car lst)) (cdr lst)))))

Procedure for multiplication of vector and matrix:

(define (matrix-vector-mul v M)
  (car (matrix-mul (list v) M)))

Procedure for transpose the matrix:

(define (matrix-transpose M)
  (if (null? (car M))
      (cons (map car M)
            (matrix-transpose (map cdr M)))))

Tail recursive procedure for transpose the matrix:

(define (matrix-transpose M)
  (let iter ((M M) (result '()))
    (if (null? (car M))
        (iter (map cdr M) (append result (list (map car M)))))))

Procedure that calculate the sum of two matrices:

(define (matrix-sum N M)
  (let iter ((N N) (M M) (result '()))
    (if (or (null? N) (null? M))
        (reverse result)
        (iter (cdr N) 
              (cdr M)
              (cons (map + (car N) (car M)) result)))))

Shorter version of the above:

(define (matrix-sum N M)
  (map (lambda (nrow mrow) (map + nrow mrow)) N M))


You can use those procedures like this:

(define M1 '((1 2 3) (2 3 4) (3 2 1)))
(define M2 (make-matrix 3))

(write (matrix-mul M1 M2))
(write (matrix-mul M1 '((2 3 1) (1 2 1) (1 3 1))))
(write (matrix-sum M1 M2))
(write (matrix-vector-mul '(2 3 1) M1)


Leave a comment

666 the number of the beast tweets on smashing magazine

I spot number of the beast tweets on smashing magazine article “Desktop Wallpaper Calendar: April 2011”

666 the number of the beast tweets

Leave a comment

Really wicked web application source code hiding

I saw this video on YouTube from DefCon Conference.

I go to samy website, and it’s web application which look like Microsoft Windows. So first think I do to see how it is build. I look at source code and it’s look like there is no code at all, but in the middle (line 281) there is this

No source for you!

Before and after script tags are only empty lines (\n), I check the end of the line 283 and there is following code (line breaks and indentations are mine):

    String.fromCharCode(parseInt(w.replace(/ /g,'0').
                                 replace(/	/g,'1'),2)))});

And thats it. So where is the real code? And the answer is this:

  1. He encode all characters in html as binary and replace zeros as space and ones as tabulations. there is no string, but in 283 line there is this: "*//" which is the end of multi-line comment and beginning of Regular Expression (which look like simple closing comment)
  2. He get value of the string representation of the RegEx using source field
  3. replace all whitespace with '0' and '1'
  4. convert it to decimal
  5. get the value of characters encoded and print all of that out

Pretty clever.

Of course you can get generated code from a menu “View Generated Source” from WebDeveloper toolbar in Firefox or see the the DOM in Firebug.

, , ,

Leave a comment

jQuery splitter – split container

This is my latest jquery plugin — “splitter” which splits content vertically or horizontally with movable element between them, that allow to change the proportion of two element. You can get it from github. The demo is here.

, ,


Concatenate files with progress bar on GNU/Linux

When I download files form rapidshare or other file hosting sites I occasionally download movies that are splited into parts, and to watch the movie they need to be concatenated.

I came up with this bash function which I put in my .bashrc file:

function concat() {
  cat $files | pv -s $(du -cb $files | tail -n1 | cut -d $'\t' -f1) > ${@: -1}

If you have files like Movie.avi.001…Movie.avi.020, to concatenate these files just type:

concat Movie.avi.* Movie.avi

And you’ll see progress bar when output file is created.

, ,

1 Comment

%d bloggers like this: