Friday, April 11, 2014

Mac and Windows friendly setup

 Since all people in our laboratory refuse to use Emacs, I decided to make Emacs behave like other applications on Windows or Mac.

(global-set-key (kbd "s-x") 'kill-region)
(global-set-key (kbd "s-c") 'kill-ring-save)
(global-set-key (kbd "s-v") 'yank)
(global-set-key (kbd "s-z") 'undo)
(global-set-key (kbd "s-a") 'mark-whole-buffer)
(global-set-key (kbd "s-w") 'close-frame-or-kill-buffer)
(global-set-key (kbd "s-n") 'new-frame-with-new-buffer)
 
(defun new-frame-with-new-buffer ()
  "Create a new frame with a new buffer `untitled-n'."
  (interactive)
  (let* ((n-th 1)
         (dir (format-time-string "~/deleteme.d/%Y-%m" (current-time)))
         (file)
         (region-p (region-active-p)))
    (if region-p (kill-ring-save (region-beginning) (region-end)))
    (switch-to-buffer-other-frame "*scratch*")
    (make-directory dir t)
    (while (file-exists-p (setq file (format "%s/untitled-%d" dir n-th)))
      (setq n-th (+ n-th 1)))
    (find-file file)
    (emacs-lisp-mode) ;; to use (lispxmp)
    (turn-on-orgtbl)
    (when region-p
      (end-of-buffer)
      (yank))
    (write-file file))
  (when (fboundp 'w32-send-sys-command)
    (w32-send-sys-command #xf030)
    (w32-send-sys-command #xf120)))
(defvar no-warning-close-frame-or-kill-buffer nil)
(defun close-frame-or-kill-buffer ()
  "Close a frame if there are more than two frames.  If there is
only one frame, kill selected-buffer.  To avoid closing
frame/buffer by mistype of M-w, prompt for an action for the
first time."
  (interactive)
  (let* ((close-buffer-p (= 1 (length (visible-frame-list))))
        (name-obj (if close-buffer-p "buffer" "frame")))
    (if (or no-warning-close-frame-or-kill-buffer
            (setq no-warning-close-frame-or-kill-buffer
                  (yes-or-no-p (format "Are you sure you want to close a %s?" name-obj))))
        (if close-buffer-p (kill-this-buffer) (delete-frame)))))

Saturday, April 05, 2014

Specify a dedicated window for other-window in Emacs

There is a way to specify a window to be used by (other-window).  Also, after a buffer poped up on a unexpected window, you can slide it to the right place.

(winner-mode 1)
(defvar window-locked-p nil)

(defun lockon-window ()
  "Set a window for other-window.  To set the target window,
    move point to the window, then call this.  Technically this sets
    all window dedicated but the target window.  Call again to free
    windows."
  (interactive)
  (walk-windows
   (lambda (win)
     (set-window-dedicated-p win (not window-locked-p))))
  (if window-locked-p
      (message "Windows are free")
    (set-window-dedicated-p (selected-window) nil)
    (message "Window is locked on"))
  (setq window-locked-p (not window-locked-p)))

(defun freeze-window ()
  "This freezes or locks a window where point is.  Call again to unfreeze.
    Technically this toggles window-dedicate-p property of a window."
  (interactive)
  (set-window-dedicated-p
   (selected-window)
   (not (window-dedicated-p (selected-window))))
  (if (window-dedicated-p (selected-window))
      (message (format "%s is freezed" (selected-window)))
    (message (format "%s is free" (selected-window)))))

(defun slide-window ()
  "This slides a buffer in a window where point is to
    next-window.  Technically this recalls previous windows-set by
    winnder-undo then shows the buffer to next-window"
  (interactive)
  (let ((buf (buffer-name)))
    (winner-undo)
    (set-window-buffer (next-window) buf)
    ;; (switch-to-buffer buf)
    (message "Window is slided")
    (other-window 1)))