Emacs: How to cascade all new frames? - emacs

I have my Emacs default new frame set to
(setq default-frame-alist
'((top . 150) (left . 400)
(width . 120) (height . 50)))
Is there a way to write a funciton to offset each new frame by 5 units at top and left so that each new frame will not be perfectly superimposed on top of each other? In other words, I want to cascade all new frames.
My system is OS X with Emacs 24.3.1

I suggest that you modify default-frame-alist in before-make-frame-hook:
(add-hook 'before-make-frame-hook 'cascade-default-frame-alist)
(defun cascade-default-frame-alist ()
(setq default-frame-alist
(mapcar (lambda (kv)
(if (memq (car kv) '(top left))
(cons (car kv) (+ 5 (cdr kv)))
kv))
default-frame-alist)))
If you want to modify default-frame-alist in-place, you need to create it with list instead of quote:
(setq default-frame-alist (list (cons 'top 150) (cons 'left 400)
(cons 'width 120) (cons 'height 50)))
(defun cascade-default-frame-alist ()
(dolist (kv default-frame-alist)
(when (memq (car kv) '(top left))
(setcdr kv (+ 5 (cdr kv))))))

Related

How to limit the number of "suggestions" that flyspell gives?

In emacs flyspell mode, sometimes the list of suggestions is really long, so that the pop-up menu is taller than the screen and requires vertical scrolling of the menu because the "Save word" option is at the bottom of the menu.
Is there a way to to do one of the following:
Move "Save word" to the top of the menu?
Put a hard limit on the number of suggestions displayed?
Modify the threshold of a matching word?
This code will limit all ispell solutions to a maximum of limit-ispell-choices-to, which gets the desired limit in flyspell.
(defvar limit-ispell-choices-to 5
"Number indicating the maximum number of choices to present")
(defadvice ispell-parse-output (after limit-ispell-choices activate)
(when (and (listp ad-return-value)
ad-return-value)
(let* ((miss-list-end (nthcdr (- limit-ispell-choices-to 1)
(nth 2 ad-return-value)))
(guess-list-end (nthcdr (- limit-ispell-choices-to 1)
(nth 3 ad-return-value))))
(when miss-list-end (setcdr miss-list-end nil))
(when guess-list-end (setcdr guess-list-end nil)))))
This will put "Save word" at the top. I just swapped two words in the source.
It's a bit of a hack, but I can't see a better way.
(defun flyspell-emacs-popup (event poss word)
"The Emacs popup menu."
(unless window-system
(error "This command requires pop-up dialogs"))
(if (not event)
(let* ((mouse-pos (mouse-position))
(mouse-pos (if (nth 1 mouse-pos)
mouse-pos
(set-mouse-position (car mouse-pos)
(/ (frame-width) 2) 2)
(mouse-position))))
(setq event (list (list (car (cdr mouse-pos))
(1+ (cdr (cdr mouse-pos))))
(car mouse-pos)))))
(let* ((corrects (if flyspell-sort-corrections
(sort (car (cdr (cdr poss))) 'string<)
(car (cdr (cdr poss)))))
(cor-menu (if (consp corrects)
(mapcar (lambda (correct)
(list correct correct))
corrects)
'()))
(affix (car (cdr (cdr (cdr poss)))))
show-affix-info
(base-menu (let ((save (if (and (consp affix) show-affix-info)
(list
(list (concat "Save affix: " (car affix))
'save)
'("Accept (session)" session)
'("Accept (buffer)" buffer))
'(("Save word" save)
("Accept (session)" session)
("Accept (buffer)" buffer)))))
(if (consp cor-menu)
(append save (cons "" cor-menu))
save)))
(menu (cons "flyspell correction menu" base-menu)))
(car (x-popup-menu event
(list (format "%s [%s]" word (or ispell-local-dictionary
ispell-dictionary))
menu)))))

Switch between frames by number or letter

I'd like to create a function that offers me numbered or lettered choices (1, 2, 3, or a, b, c) of available frames to switch to, instead of manually typing the name. Aspell would be the closest example I can think of.
Could someone please share an example of how this might be done? Lines 6 to 14 of the following function creates a list of all available frame names on the fly. Additional functions related to frame switching can be found here
(defun switch-frame (frame-to)
(interactive (list (read-string (format "From: (%s) => To: %s. Select: "
;; From:
(frame-parameter nil 'name)
;; To:
(mapcar
(lambda (frame) "print frame"
(reduce 'concat
(mapcar (lambda (s) (format "%s" s))
(list "|" (frame-parameter frame 'name) "|" )
)
)
)
(frame-list) )
)))) ;; end of interactive statement
(setq frame-from (frame-parameter nil 'name))
(let ((frames (frame-list)))
(catch 'break
(while frames
(let ((frame (car frames)))
(if (equal (frame-parameter frame 'name) frame-to)
(throw 'break (select-frame-set-input-focus frame))
(setq frames (cdr frames)))))) )
(message "Switched -- From: \"%s\" To: \"%s\"." frame-from frame-to) )
EDIT (November 13, 2014):  Here is a revised function using ido-completing-read:
(defun ido-switch-frame ()
(interactive)
(when (not (minibufferp))
(let* (
(frames (frame-list))
(frame-to (ido-completing-read "Select Frame: "
(mapcar (lambda (frame) (frame-parameter frame 'name)) frames))))
(catch 'break
(while frames
(let ((frame (car frames)))
(if (equal (frame-parameter frame 'name) frame-to)
(throw 'break (select-frame-set-input-focus frame))
(setq frames (cdr frames)))))))))
I see what you're trying to do. Here's how I've solved this problem:
Part 1
The files that you use every day should be bookmarked.
The reason is that you loose focus when you're reading any sort of menu,
even as short as you describe. After some time with bookmarks,
it becomes like touch-typing: you select the buffer without thinking about it.
You can check out this question
to see my system.
I've got about 20 important files and buffers bookmarked and reachable
in two keystrokes, e.g. μ k for keys.el and μ h for hooks.el.
A nice bonus is that bookmark-bmenu-list shows all this stuff, so I can
add/remove bookmarks easily
rename bookmarks (renaming changes binding)
it's clickable with mouse (sometimes useful)
bookmark+ allows function bookmarks, so I've got org-agenda on μ a
and magit on μ m.
And of course the dired bookmarks: source is on μ s and
org-files are on μ g.
Part 2
For the files that can't be bookmarked, I'm using:
(ido-mode)
(setq ido-enable-flex-matching t)
(global-set-key "η" 'ido-switch-buffer)
This is fast as well: you need one keystroke to call ido-switch-buffer
and around 2-3 letters to find the buffer you need, and RET to select.
I've also recently added this hack:
(add-hook 'ido-setup-hook
(lambda()
(define-key ido-buffer-completion-map "η" 'ido-next-match)))
With this you can use the same key to call ido-switch-buffer and cycle the selection.
Part 3
The actual function with lettered choices has been on my todo list for a while
now. I'll post back here when I get around to implementing it,
or maybe just copy the solution from a different answer:)
This answer describes Icicles command icicle-select-frame, which lets you choose frames by name using completion.
There is also Icicles command icicle-other-window-or-frame (C-x o), which combines commands icicle-select-frame, other-frame, and other-window. It lets you select a window or a frame, by its name or by order.
With no prefix arg or a non-zero numeric prefix arg:
If the selected frame has multiple windows then this is
other-window. Otherwise, it is other-frame.
With a zero prefix arg (e.g. C-0):
If the selected frame has multiple windows then this is
icicle-select-window with windows in the frame as candidates.
Otherwise (single-window frame), this is icicle-select-frame.
With plain C-u:
If the selected frame has multiple windows then this is
icicle-select-window with windows from all visible frames as
candidates. Otherwise, this is icicle-select-frame.
Depending upon the operating system, it may be necessary to use (select-frame-set-input-focus chosen-frame) instead of select-frame / raise-frame towards the end of the function.
(defface frame-number-face
'((t (:background "black" :foreground "red" )))
"Face for `frame-number-face`."
:group 'frame-fn)
(defface frame-name-face
'((t ( :background "black" :foreground "ForestGreen")))
"Face for `frame-name-face`."
:group 'frame-fn)
(defun select-frame-number ()
"Select a frame by number -- a maximum of 9 frames are supported."
(interactive)
(let* (
choice
chosen-frame
(n 0)
(frame-list (frame-list))
(total-frames (safe-length frame-list))
(frame-name-list
(mapcar
(lambda (frame) (cons frame (frame-parameter frame 'name)))
frame-list))
(frame-name-list-sorted
(sort
frame-name-list
#'(lambda (x y) (string< (cdr x) (cdr y)))))
(frame-number-list
(mapcar
(lambda (frame)
(setq n (1+ n))
(cons n (cdr frame)))
frame-name-list-sorted))
(pretty-list
(mapconcat 'identity
(mapcar
(lambda (x) (concat
"["
(propertize (format "%s" (car x)) 'face 'frame-number-face)
"] "
(propertize (format "%s" (cdr x)) 'face 'frame-name-face)))
frame-number-list)
" | ")) )
(message "%s" pretty-list)
(setq choice (read-char-exclusive))
(cond
((eq choice ?1)
(setq choice 1))
((eq choice ?2)
(setq choice 2))
((eq choice ?3)
(setq choice 3))
((eq choice ?4)
(setq choice 4))
((eq choice ?5)
(setq choice 5))
((eq choice ?6)
(setq choice 6))
((eq choice ?7)
(setq choice 7))
((eq choice ?8)
(setq choice 8))
((eq choice ?9)
(setq choice 9))
(t
(setq choice 10)))
(setq chosen-frame (car (nth (1- choice) frame-name-list-sorted)))
(when (> choice total-frames)
(let* (
(debug-on-quit nil)
(quit-message
(format "You must select a number between 1 and %s." total-frames)))
(signal 'quit `(,quit-message ))))
(select-frame chosen-frame)
(raise-frame chosen-frame)
chosen-frame))

Emacs: default-frame-alist setting is ignored

I would like all frames to overlap at (1,1). Yet with a .emacs containing
(setq initial-frame-alist
'((top . 1) (left . 1) (width . 80) (height . 55)))
(setq default-frame-alist
'((top . 1) (left . 1) (width . 80) (height . 55)))
calling C-x 5 2 results in frames in a cascade, as you see in the figure.
How can I force all frames to be anchored at the same place?
I am running Emacs 23.3.1 on OS X (Mountain Lion).
The settings are not being ignored. The reason you see the above behaviour is due to a before-make-frame-hook in ns-win.el that adds 25 to top and left.
To avoid the above effect you can add the following to your .emacs file:
(setq default-frame-alist '((left . 0) (top . 0) (width . 80) (height . 55)))
(defvar parameters)
(add-hook 'before-make-frame-hook
(lambda ()
(let ((left (cdr (assq 'left (frame-parameters))))
(top (cdr (assq 'top (frame-parameters)))))
(setq parameters (cons (cons 'left (+ left 0))
(cons (cons 'top (+ top 0))
parameters))))))
If the above doesn't work you can try the following which is taken from ns-win.el before-make-frame-hook.
(setq default-frame-alist '((left . 0) (top . 0) (width . 80) (height . 55)))
(defvar parameters)
(add-hook 'before-make-frame-hook
(lambda ()
(let ((left (cdr (assq 'left (frame-parameters))))
(top (cdr (assq 'top (frame-parameters)))))
(if (consp left) (setq left (cadr left)))
(if (consp top) (setq top (cadr top)))
(cond
((or (assq 'top parameters) (assq 'left parameters)))
((or (not left) (not top)))
(t
(setq parameters (cons (cons 'left (+ left 0))
(cons (cons 'top (+ top 0))
parameters))))))))

Keyboard scrolling with acceleration

One can easily map some key to scroll up.
(defun up1()
(interactive)
(scroll-up 1))
(defun up2()
(interactive)
(scroll-up 2))
(global-set-key "\M-]" 'up2)
I am looking instead for the following behavior. The first handful of
scrolls would call up1() and the subsequent ones would call up2().
How about this:
(setq my-scroll-counter 0)
(setq my-scroll-limit 5)
(defun up1()
(interactive)
(if (eq last-command this-command)
(incf my-scroll-counter)
(setq my-scroll-counter 0))
(if (> my-scroll-counter my-scroll-limit)
(scroll-up 2)
(scroll-up 1)))
(global-set-key "\M-]" 'up1)
If you want something a little fancier, you calculate your scroll step dynamically based on how many times you repeat the command:
(setq my-scroll-counter 0)
(setq my-maximum-scroll 20)
(setq my-scroll-acceleration 4)
(defun up1()
(interactive)
(if (eq last-command this-command)
(incf my-scroll-counter)
(setq my-scroll-counter 0))
(scroll-up (min
(+ 1 (/ my-scroll-counter my-scroll-acceleration))
my-maximum-scroll)))
(global-set-key "\M-]" 'up1)

Emacs23 cannot be transparent in Ubuntu(Gnome 3)

I search how to transparent my emacs window. But it doesn't work.
Something like this failed:
(global-set-key [(f8)] 'loop-alpha)
(setq alpha-list '((100 100) (95 65) (85 55) (75 45) (65 35)))
(defun loop-alpha ()
(interactive)
(let ((h (car alpha-list)))
((lambda (a ab)
(set-frame-parameter (selected-frame) 'alpha (list a ab))
(add-to-list 'default-frame-alist (cons 'alpha (list a ab)))
) (car h) (car (cdr h)))
(setq alpha-list (cdr (append alpha-list (list h))))
)
)
Here's a working implementation of what I think you were trying to do:
(global-set-key [(f8)] 'loop-alpha)
(defvar alpha-list '((100 100) (95 65) (85 55) (75 45) (65 35)))
(defun next-alpha ()
(let ((current-alpha
(or (frame-parameter (selected-frame) 'alpha)
(first alpha-list)))
(lst alpha-list))
(or (second
(catch 'alpha
(while lst
(when (equal (first lst) current-alpha)
(throw 'alpha lst))
(setf lst (cdr lst)))))
(first alpha-list))))
(defun loop-alpha ()
(interactive)
(let ((new-alpha (next-alpha))
(current-default (assoc 'alpha default-frame-alist)))
(set-frame-parameter (selected-frame) 'alpha new-alpha)
(if current-default
(setcdr current-default new-alpha)
(add-to-list 'default-frame-alist (cons 'alpha new-alpha)))))
Notice that any version you write that redefines alpha-list is going to behave very strangely with multiple frames. I would explain what was wrong with your code, but I honestly couldn't work out what it was supposed to do. Note that this would be somewhat easier to write if I allowed myself to (require 'cl) first, but I think this code should work - it does here at any rate!