specify window layout in emacs on commandline - emacs

I would like to be able to specify the window layout of the Emacs when starting it from commandline.
More specifically, I invoke "emacs file1 file2 file3 file4" and would, for example, like see
+---------+ +--------+
| file1 | | buff |
| | | list |
+---------+ instead of the default +--------+ that I see currently
| | | |
| file3 | | file4 |
+---------+ +--------+
My emacs is GNU Emacs 24.0.91.1, and I do not use emacsclient.
Note, I do not want to make the change permanent. That is why I ask for command-line solution.

Put the following in layout.el
(setq inhibit-startup-screen t)
(defun ordered-window-list-aux (tree)
(if (windowp tree)
(list tree)
(append (ordered-window-list-aux (nth 2 tree))
(ordered-window-list-aux (nth 3 tree)))))
(defun ordered-window-list ()
"Lists windows from top to bottom, left to right."
(ordered-window-list-aux
(car (window-tree))))
(require 'cl)
(defun fill-windows ()
"Make window list display recent buffer."
(mapcar*
(lambda (win buf)
(set-window-buffer win buf))
(nreverse (ordered-window-list))
(buffer-list)))
(delete-other-windows)
;; your window configuration
(split-window-horizontally)
(split-window-vertically)
;; Make window list display recent buffer
(fill-windows)
Then
emacs blah foo bar --load layout.el
The only thing you have to do is customizing the layout the way you want using a combination of the following functions:
(split-window-horizontally)
(split-window-vertically)
(other-windows 1)

Related

orgmode region to table

I have a region:
Items Quantity Amount
"Item A" 423 63
"Item B and C" 27 169
"Item D " 6 199
I would like to create org-table of the above region:
|Items | Quantity| Amount|
----------------|------------------
|"Item A" | 423 | 63 |
|"Item A and C" | 27 | 169 |
|"Item D" | 6 | 199 |
The current suggestion is to select the region and use C-c | to create the table but this creates a table based on spaces between the elements. It is not able to group the items column. Is there a way I can group
You can write your own Emacs Lisp function which will convert all the white-chars (not only spaces) between the two sexp and replace them with , in the currently active region.
(defun my/convert-region ()
(interactive)
(save-window-excursion
(narrow-to-region (region-beginning) (region-end))
(goto-char (point-min))
(forward-sexp)
(while (< (point) (buffer-end 1))
(let ((beg (point)))
(if (= (point) (line-end-position))
(forward-char)
(progn
(forward-sexp)
(backward-word)
(delete-region beg (point)))
(insert ",")))
(forward-sexp))
(goto-char (point-min))
(widen)))
I checked this on such active region:
Items Quantity Amount
"Item A" 423 63
"Item B and C" 27 169
"Item D " 6 199
After running M-x my/convert-region it was changed to:
Items,Quantity,Amount
"Item A",423,63
"Item B and C",27,169
"Item D ",6,199
You can add this function to your config file and bind it to some keys.
If you want this function to convert this region to the org-table in the same function just add org-table-convert-region call.
(defun my/convert-region-to-org-table ()
(interactive)
(save-window-excursion
(narrow-to-region (region-beginning) (region-end))
(goto-char (point-min))
(forward-sexp)
(while (< (point) (buffer-end 1))
(let ((beg (point)))
(if (= (point) (line-end-position))
(forward-char)
(progn
(forward-sexp)
(backward-word)
(delete-region beg (point)))
(insert ",")))
(forward-sexp))
(org-table-convert-region (point-min) (point-max) '(4))
(goto-char (point-min))
(widen)))
For the same input:
Items Quantity Amount
"Item A" 423 63
"Item B and C" 27 169
"Item D " 6 199
I got the following result:
| Items | Quantity | Amount |
| Item A | 423 | 63 |
| Item B and C | 27 | 169 |
| Item D | 6 | 199 |
Unfortunately the quotation marks are being removed by org-mode during the conversion.
(defun my/convert-region-to-org-table-with-header ()
(interactive)
(save-window-excursion
(narrow-to-region (region-beginning) (region-end))
(goto-char (point-min))
(forward-sexp)
(while (< (point) (buffer-end 1))
(let ((beg (point)))
(if (= (point) (line-end-position))
(forward-char)
(progn
(forward-sexp)
(backward-word)
(delete-region beg (point)))
(insert ",")))
(forward-sexp))
(org-table-convert-region (point-min) (point-max) '(4))
(goto-char (point-min))
(org-ctrl-c-minus)
(widen)))
Then the output will look like this:
| Items | Quantity | Amount |
|--------------+----------+--------|
| Item A | 423 | 63 |
| Item B and C | 27 | 169 |
| Item D | 6 | 199 |
I can explain how the code works if anyone is interested. This answer is already pretty long so I am not going to do that now when not sure if it will be useful for anyone.
Hope that helps.
In these cases i normally create an emacs macro:
position the cursor on the second line (As your first line does not contain the quotes, it will not work there) of your table.
Press f3 and then:
C-a
Then press the pipe: "|"
press "delete" to remove the first double quote
search for the next double quote C-s "
remove the double quote and add another pipe sign
move one word further with C-right
add another pipe
C-e
add another pipe
move one line down with the cursor
press f4 to close the marco
When you now press f4 it should execute the same again.
If everything went fine, then you can execute the command easily hundreds of times through C- any number you want and "f4".
After that is done, you can simply also add pipes in the first line once.
Now pressing "tab" inside the org-table will align everything.
Hope that helps.

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?
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))))))
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.

Second eshell buffer is opened at the top instead of bottom

Desired function algorithm
|------------------|
| old buffer - 70% |
| |
| |
| |
|------------------|
| |
| eshell - 30% |
|------------------|
If there is only 1 window in the buffer
1.1 Split buffer into 2 parts: top - 70% of the height, bottom - 30% of the height.
1.2. Put cursor to the bottom buffer.
1.3. Open eshell.
Code
(defun new-eshell ()
(interactive)
(when (one-window-on-screen-p)
(let ((new-window (split-window-vertically 30)))
(select-window new-window)
(eshell "eshell"))))
(defun one-window-on-screen-p ()
(= (length (window-list)) 1))
(global-set-key "\M-e" 'new-eshell)
Problem
When I click Alt-e for the first time, the function works correctly. But if I hide eshell buffer, and click Alt-e for the second time, the window is split in proportions 50/50 and "*eshell<2>*" buffer is opened at the top instead of bottom.
I think that the problem is that the parameter of split-lines-vertically refers to a number of lines, not to a proportion. This code worked for me:
(defun new-eshell ()
(interactive)
(when (one-window-on-screen-p)
(let* ((lines (window-body-height))
(new-window (split-window-vertically (floor (* 0.7 lines)))))
(select-window new-window)
(eshell "eshell"))))
(btw, I obtained strange results if I passed a floating point number to split-lines-vertically, so I had to use floor)

macro for deleting selected rows from org table

I have some org table with 5 columns and 100 rows.
I would like to delete all those rows with field $3="away".
Below is the function that should do the following. Unfortunately I do not know how to convert org table that is created with (org-table-to-lisp), back to text table into my buffer.
(defun org-table-tests ()
"acts on balance table itself"
(interactive)
(save-excursion
(unless (org-table-p)
(error
"You are not in an org-table."))
(goto-char (org-table-begin))
(let (out-tbl
(tbl-list (org-table-to-lisp)))
(while
(let ((row-list (car tbl-list)))
(cond ((and
(listp row-list)
;; do not copy "away" (3rd column) lines containing folliwng:
(string-match "away" (nth 2 row-list)))
;; just skip copying to new table
)
(t (setq out-tbl (cons row-list out-tbl))))
(setq tbl-list (cdr tbl-list))))
;;(orgtbl-to-generic out-tbl) <---------- QUESTION: which function to use to convert back to table in text format.
)))
... or maybe there is a better way for doing such tasks with orgtbl mode?
Since your main question was answered, here's now a solution that doesn't rely on converting to lisp and back :
(defun org-table-tests ()
(interactive)
(save-excursion
(unless (org-table-p)
(error "You are not in an org-table."))
(goto-char (org-table-begin))
(while (org-table-p)
(if (string-match "away" (save-excursion (org-table-get-field 3)))
(delete-region (point) (progn (forward-line) (point)))
(forward-line)))))
Have a look at org-listtable-to-string. It's the reverse of org-table-to-lisp.
Also have a look at this screencast to see how
I've found the solution in under a minute (just grepped for "to table" in org's code base, basically).
If you just want to remove row where $3=="away", following commands are useful. But I don't know why it works.
ESC M-<
M-x flush-lines
RET
^[|][^|]*[|][^|
]*[|] away [|]
RET
Input:
| 1 | 2 | 3 | 4 | 5 |
|------+------+------+------+------|
| away | 12 | 13 | 14 | away |
| 21 | 22 | away | 24 | 25 |
| 31 | away | 33 | away | 35 |
Output:
| 1 | 2 | 3 | 4 | 5 |
|------+------+------+------+------|
| away | 12 | 13 | 14 | away |
| 31 | away | 33 | away | 35 |

Howto convert org-mode table to original tabbed format?

I am converting a region to a table by using C-c |.
Is there a way to reverse the process, say after converting do some editing and go back to original format (tab separated values will do)?
I know that I can do it via org-table-export but that is too cumbersome.
Try orgtbl-to-tsv for tab-separated values.
There is also orgtbl-to-csv for comma-separated values.
Combining the table with a short code block to do the conversion is convenient. For example:
* Some heading
#+name: foo
| a | b | c |
|---+---+---|
| 1 | 2 | 3 |
| 4 | 5 | 6 |
#+name: foo-csv
#+BEGIN_SRC elisp :var x=foo :wrap example
(orgtbl-to-csv x nil)
#+END_SRC
#+RESULTS: foo-csv
#+begin_example
1,2,3
4,5,6
#+end_example
C-c C-c on the code block will produce the results shown. Adding :colnames no as a header argument to the code block will also preserve the header line:
#+name: foo-csv
#+BEGIN_SRC elisp :var x=foo :wrap example :results raw :colnames no
(orgtbl-to-csv x nil)
#+END_SRC
#+RESULTS: foo-csv
#+begin_example
a,b,c
1,2,3
4,5,6
#+end_example
I needed this too and just wrote the following based on org-table-export:
(defun org-table-transform-in-place ()
"Just like `ORG-TABLE-EXPORT', but instead of exporting to a
file, replace table with data formatted according to user's
choice, where the format choices are the same as
org-table-export."
(interactive)
(unless (org-at-table-p) (user-error "No table at point"))
(org-table-align)
(let* ((format
(completing-read "Transform table function: "
'("orgtbl-to-tsv" "orgtbl-to-csv" "orgtbl-to-latex"
"orgtbl-to-html" "orgtbl-to-generic"
"orgtbl-to-texinfo" "orgtbl-to-orgtbl"
"orgtbl-to-unicode")))
(curr-point (point)))
(if (string-match "\\([^ \t\r\n]+\\)\\( +.*\\)?" format)
(let ((transform (intern (match-string 1 format)))
(params (and (match-end 2)
(read (concat "(" (match-string 2 format) ")"))))
(table (org-table-to-lisp
(buffer-substring-no-properties
(org-table-begin) (org-table-end)))))
(unless (fboundp transform)
(user-error "No such transformation function %s" transform))
(save-restriction
(with-output-to-string
(delete-region (org-table-begin) (org-table-end))
(insert (funcall transform table params) "\n")))
(goto-char curr-point)
(beginning-of-line)
(message "Tranformation done."))
(user-error "Table export format invalid"))))
(define-key org-mode-map (kbd "\C-x |") 'org-table-transform-in-place)
It'd be great if this got added to org-mode proper as I think many would use it.
Mark the region.
M-x replace-string
|
C-q TAB RET
If you want to tweak it, use replace-regex.
Here are the steps to use export the table as tab or comma separated values:
Use the command org-table-export. M-x org-table-export
Enter the filename to save to (or hit enter for the same file).
Select the format (this is where you can set the orgtbl-to-tsv or any other formats).
These are some of the formats that can be used:
orgtbl-to-csv
orgtbl-to-generic
orgtbl-to-html
orgtbl-to-latex
orgtbl-to-orgtbl
orgtbl-to-texinfo
orgtbl-to-tsv