user4035
user4035

Reputation: 23749

Emacs: how to find that at least one windows was vertically split

I don't know, how to write a function like this in elisp:

if(any window was split vertically)
    return t;
else
    return nil;

true:

|----------|     |----------|----------|
|          |     |          |          |
|          |     |          |          |
|----------|     |----------|----------|

false:

|--------|     |--------|-------|
|        |     |        |       |
|        |     |        |       |
|--------|     |        |-------|
|        |     |        |       |
|        |     |        |       |
|--------|     |--------|-------|

I found, that there is window-list function, that returns a list of all the windows. So, the algorithm should be like this:

(setq windows (window-list))
dolist(windows)
{
    if($_->is_vertically_split())
    {
        return nil;
    }
}

return t;

How can I determine, that this window is vertically split? It's height shouldn't be 100%.

Update

Using @lawlist answer I wrote the following, but it doesn't work (always returns nil):

(defun no-window-is-vertically-split ()
  (let (windows (window-list)
                (result nil))
    (dolist (w windows)
      (when (or
             (window-in-direction 'above w)
             (window-in-direction 'below w))
             (setq result t)))
   result))


(no-window-is-vertically-split)

Is it possible to break the dolist loop and just return the value, when 1-st split window is found?

Upvotes: 0

Views: 309

Answers (2)

lawlist
lawlist

Reputation: 13467

You can use any of these to test whether there is a window above, below, left or right:

(window-in-direction 'above)

or

(window-in-direction 'below)

or

(window-in-direction 'left)

or

(window-in-direction 'right)

And here is an example using conditions -- just replace [... do something] with your preferred action:

(cond
  ((window-in-direction 'above)
    [... do something])
  ((window-in-direction 'below)
    [... do something])
  ((window-in-direction 'left)
    [... do something])
  ((window-in-direction 'right)
    [... do something]))

To test whether there is only one window, the following is useful:

(one-window-p t)

Here is a test similar to the call of the question, which is based upon the the test being performed from the selected window:

(if
    (or
      (window-in-direction 'above)
      (window-in-direction 'below))
  (message "There is either a window above or below the selected window.")
  (message "There is are no windows above or below the selected window."))

EDIT (August 1, 2014):  Based on the updated question of the original poster, the following is an example of how to break the dolist loop and throw the result:

(defun no-window-is-vertically-split ()
  (catch 'done
    (let* (
        result
        (windows (window-list)))
      (dolist (w windows)
        (when (or
               (window-in-direction 'above w)
               (window-in-direction 'below w))
          (setq result t)
          (throw 'done result))))))

Upvotes: 2

Dan
Dan

Reputation: 5369

These two functions will detect horizontal and vertical splits:

(defun any-vertical-splits-p ()
  "Return t if any windows have been split vertically."
  (when (member nil (mapcar #'window-full-height-p (window-list))) t))

(defun any-horizontal-splits-p ()
  "Return t if any windows have been split horizontally."
  (when (member nil (mapcar #'window-full-width-p (window-list))) t))

I wasn't quite sure I knew what you meant in your diagram. Vertical and horizontal are used here as Emacs uses them with split-window-vertically and split-window-horizontally.

Upvotes: 2

Related Questions