emacs macro to convert a vector to a matrix in .csv notation - emacs

I have a single line text file of csv values
I would like to able to 'pretty-print' the file to span multiple lines to make it more readable
The 1st no. represents the no. of csv values in the next section and so on
e.g.
3,1,2,3,3,4,5,6
would be converted to:
3,1,2,3
3,4,5,6
I know a little about making macros, e.g.
C-x (
C-s RET ,
C-x )
using this I can do:
C-u 3 C-x e to move 3 csv values along
My sticking point is how to use the value from file to paste into the arg to C-u
maybe I should be using an e-lisp function instead as its a function I would like to 'save' for continual use across emacs sessions. Is it possible to save macros as such?
any ideas gratefully received

I find elisp easier to think about than keyboard macros. How about this:
(defun csv-line-breaks ()
(interactive)
(while (search-forward "," nil t
(1+ (string-to-number (thing-at-point 'word))))
(delete-char -1)
(insert "\n")))
(global-set-key (kbd "C-c b") 'csv-line-breaks)
With this in your .emacs (or just evaluate the code in your scratch buffer), you put point at the beginning of the line, then hit C-c b to break the line up into the chunks you want.
What this does:
Looping over the buffer until it runs out of values, and for each loop:
Read the first value. (thing-at-point 'word) grabs anything it finds between whitespace of punctuation (more or less).
Convert the value, which is actually a string, into a number
Add one to that number, and move forward that many commas
Delete the previous comma
Insert a new line

You might want to take a look at csv-mode for Emacs: http://emacswiki.org/emacs/CsvMode
Although it might not do exactly what you're looking for, it has a feature for formatting for readability, as well as other features for munging csv files in a variety of ways.

Related

How to attach character to the next N lines using Emacs?

Using emacs24 I'd like to attach for example # at the beginning of the next five lines.
So having this:
Line1
line2
line3
get this:
#Line1
#line2
#line3
for the number of lines that I specify. How can I do that? Thanks!
While there may be something built in to Emacs that does this, and you can certainly write a little Lisp to get it done, I would usually use "rectangular editing" features to get this done. Imagine that the buffer contains the following, with . representing the point (where your cursor is)
.Line1
line2
line3
Set the mark
Press C-n twice. This is the state of the buffer now:
Line1
line2
.line3
Press C-x r t.
Type #.
Press enter.
I would find this much more natural than entering a value for the number of times to repeat a command, because you can visually select the lines you want to edit. YMMV
Edit
Here's how to do this using a bit of Emacs Lisp. Note that although I've been using Emacs for a few years now, I only recently began learning how to actually use Emacs Lisp, so this code might not be that great! It does get the job done.
(defun insert-n-times (s n)
(interactive "Mstring:\nNtimes:")
(while (> n 0)
(insert s)
(goto-char (- (point) 1))
(next-line)
(setq n (- n 1))))
Use it by doing the following: M-x insert-n-times RET <type a string> RET <type a number>
Another method is using macro to get such repetitive work done. Here is a page that describes how to use macros in Emacs. You can have a look at it if you are not familiar with it.
In your case, the following keys would work:
Move the cursor to the beginning of Line1
C-x (
Type a '#'
C-n, then C-a
C-x )
Move the cursor to the line to the beginning of which you want to add '#'
C-u 10 C-x e
Basically, step 2-5 will record a macro which will add a # at the beginning, and then move to the beginning of the next line. Step 6-7 will execute the macro 10 times (of course, you can change it to arbitrary number). I guess this will be quite a lot of keystrokes and newbies may not like it. Maybe others have better solutions.
Line1
line2
line3
I wrote the following code:
You first give a digit argument (the amount of times you want to do this), e.g. M-3 (hold alt, hit 3), to do the following 3 times
Either use a key for it, like a suggestion below (f8), or use M-x prompt-for-insert
It will ask you for a string to enter. e.g. "foo" and hit return button.
It will then do as you ask.
(defun prompt-for-insert (val)
(interactive "P")
(let ((astring (read-string "What do you want to insert?"))
(value val))
(while (> value 0)
(insert astring)
(move-beginning-of-line 2)
(decf value)))
)
(global-set-key [f8] 'prompt-for-insert)
The whole sequence will then be:
M-3 [f8] foo RET
Resulting in:
fooLine1
fooline2
fooline3
Why not just query-replace-regexp or replace-regexp? E.g. select the region and do C-M-%^RET#RET!
Try M-x string-insert-rectangle. This command inserts a string on every line of the rectangle.
While comment-region is good in this specific example, check out the multiple-cursors package for a very powerful way to do this kind of thing in general.
You can just hit C-> repeatedly until you have a cursor at the beginning of each line, then hit # and you're done (C-g to get rid of the extra cursors.)
It's a much more interactive form of C-x r t and works with non-rectangular regions too (after a C-s for example.)

Emacs: print with line numbers

Does anyone know how to print with the line numbers of the code in the margin? I can display the line number, cannot have that in the printout. Thanks!
You can add the line numbers with temporary overlays and convert the buffer to HTML using the htmlize package, after which you can save the HTML and print using lpr or a browser.
(defun htmlize-with-line-numbers ()
(interactive)
(goto-char (point-min))
(let ((n 1))
(while (not (eobp))
(htmlize-make-tmp-overlay (point) (point) `(before-string ,(format "%4d " n)))
(setq n (1+ n))
(forward-line 1)))
(switch-to-buffer (htmlize-buffer)))
This will require a recent version of htmlize.
Sorry for the solution on such an old post. I used ps-print-buffer rather than print-buffer, since the results are much nicer looking. Anyway, for some reason it is not documented in the manual, but if you look at the source for ps-print.el, you find the ps-line-number variable that you can set to non-nil in order include line numbers.
M-x set-variable RET ps-line-number RET t
That should set it temporarily so that you can print. You may want to set it permanently in your init.el.
You can also print using the M-x pr-interface command, which brings up a buffer of all sorts of printing options.
An easy yet hackish way would of course be to temporarily insert line numbers directly into the buffer
C-<
C-M-% ^ RET \,(1+ \#) SPC RET
then print it
M-x print-buffer
and then undo the line numbers again:
C-/
C-u C-SPC
The result is not very beautiful, but usable. There are three main problems:
you're making changes to the buffer. In particular, that means the buffer must not be read-only.
the line numbers are left justified which means you get different indentation depending on the number of digits in the line number.
your major mode will trip over the line numbers and you'll lose the syntax highlighting. If you're printing on a black-and-white printer that's not a problem though.
You could fix the second point by using a more complicated replacement string:
\,(format "%4d " (1+ \#))
but then you have to know what is the maximum line number so you can give the right number of digits between % and d. You could of course just jump to the end of the buffer quickly to check the maximum line number. But more importantly, it's becoming a pain to type all that every time you want to print line numbers.

emacs equivalent of ct

looking for an equivalent cut and paste strategy that would replicate vim's 'cut til'. I'm sure this is googleable if I actually knew what it was called in vim, but heres what i'm looking for:
if i have a block of text like so:
foo bar (baz)
and I was at the beginning of the line and i wanted to cut until the first paren, in visual mode, I'd do:
ct (
I think there is probably a way to look back and i think you can pass more specific regular expressions. But anyway, looking for some emacs equivalents to doing this kind of text replacement. Thanks.
Here are three ways:
Just type M-dM-d to delete two words. This will leave the final space, so you'll have to delete it yourself and then add it back if you paste the two words back elsewhere.
M-z is zap-to-char, which deletes text from the cursor up to and including a character you specify. In this case you'd have to do something like M-2M-zSPC to zap up to and including the second space character.
Type C-SPC to set the mark, then go into incremental search with C-s, type a space to jump to the first space, then C-s to search forward for the next space, RET to terminate the search, and finally C-w to kill the text you selected.
Personally I'd generally go with #1.
as ataylor said zap-to-char is the way to go, The following modification to the zap-to-char is what exactly you want
(defun zap-up-to-char (arg char)
"Like standard zap-to-char, but stops just before the given character."
(interactive "p\ncZap up to char: ")
(kill-region (point)
(progn
(search-forward (char-to-string char) nil nil arg)
(forward-char (if (>= arg 0) -1 1))
(point))))
(define-key global-map [(meta ?z)] 'zap-up-to-char) ; Rebind M-z to our version
BTW don't forget that it has the ability to go backward with a negative prefix
That sounds like zap-to-char in emacs, bound to M-z by default. Note that zap-to-char will cut all the characters up to and including the one you've selected.

Modify Alt+f in Emacs for tex-mode

Alt+f in emacs when writing in tex mode seems to not include the . as part of the word. So how do I modify the alt+f behavior to remain the same exact when going forward if there is punctiation to include that as part of the word.
I have a separate file that loads for when writing in tex so I will just throw it in there so it doesn't affect normal emacs behavior.
Thanks for any help.
Thought of an addition to this but same related problem is when using Alt+d and deleting. Getting it to delete not only the word but also the punctation following eg.. (,.! etc..).
The following code should work for you:
(defun unpunctuate-syntax (str)
"Make the characters of the given string word characters."
(let ((st (copy-syntax-table (syntax-table))))
(dotimes (n (length str))
(modify-syntax-entry (elt str n) "w" st))
(set-syntax-table st)))
(defun dots-are-not-punctuation ()
(unpunctuate-syntax "."))
(add-hook 'TeX-mode-hook 'dots-are-not-punctuation)
The way M-f (the forward-word function) works is that it skips all characters in the buffer that have type "w" (ie word) in the current syntax table.
This code makes a modified syntax table and gives it to the buffer and the add-hook bit at the bottom sets it to run when you open a file in TeX-mode. (This method avoids you having to do the separate file thing you described).
You might notice that I make a copy of the syntax table rather than editing the one belonging to the TeX major mode. This is because I always get things wrong when playing with syntax tables and you can mess things up royally... This method means you just have to close the buffer and start again!

How to get Emacs to unwrap a block of code?

Say I have a line in an emacs buffer that looks like this:
foo -option1 value1 -option2 value2 -option3 value3 \
-option4 value4 ...
I want it to look like this:
foo -option1 value1 \
-option2 value2 \
-option3 value3 \
-option4 value4 \
...
I want each option/value pair on a separate line. I also want those subsequent lines indented appropriately according to mode rather than to add a fixed amount of whitespace. I would prefer that the code work on the current block, stopping at the first non-blank line or line that does not contain an option/value pair though I could settle for it working on a selected region.
Anybody know of an elisp function to do this?
Nobody had what I was looking for so I decided to dust off my elisp manual and do it myself. This seems to work well enough, though the output isn't precisely what I asked for. In this version the first option goes on a line by itself instead of staying on the first line like in my original question.
(defun tcl-multiline-options ()
"spread option/value pairs across multiple lines with continuation characters"
(interactive)
(save-excursion
(tcl-join-continuations)
(beginning-of-line)
(while (re-search-forward " -[^ ]+ +" (line-end-position) t)
(goto-char (match-beginning 0))
(insert " \\\n")
(goto-char (+(match-end 0) 3))
(indent-according-to-mode)
(forward-sexp))))
(defun tcl-join-continuations ()
"join multiple continuation lines into a single physical line"
(interactive)
(while (progn (end-of-line) (char-equal (char-before) ?\\))
(forward-line 1))
(while (save-excursion (end-of-line 0) (char-equal (char-before) ?\\))
(end-of-line 0)
(delete-char -1)
(delete-char 1)
(fixup-whitespace)))
In this case I would use a macro. You can start recording a macro with C-x (, and stop recording it with C-x ). When you want to replay the macro type C-x e.
In this case, I would type, C-a C-x ( C-s v a l u e C-f C-f \ RET SPC SPC SPC SPC C-x )
That would record a macro that searches for "value", moves forward 2, inserts a slash and newline, and finally spaces the new line over to line up. Then you could repeat this macro a few times.
EDIT: I just realized, your literal text may not be as easy to search as "value1". You could also search for spaces and cycle through the hits. For example, hitting, C-s a few times after the first match to skip over some of the matches.
Note: Since your example is "ad-hoc" this solution will be too. Often you use macros when you need an ad-hoc solution. One way to make the macro apply more consistently is to put the original statement all on one line (can also be done by a macro or manually).
EDIT: Thanks for the comment about ( versus C-(, you were right my mistake!
Personally, I do stuff like this all the time.
But I don't write a function to do it unless I'll be doing it
every day for a year.
You can easily do it with query-replace, like this:
m-x (query-replace " -option" "^Q^J -option")
I say ^Q^J as that is what you'll type to quote a newline and put it in
the string.
Then just press 'y' for the strings to replace, and 'n' to skip the wierd
corner cases you'd find.
Another workhorse function is query-replace-regexp that can do
replacements of regular expressions.
and also grep-query-replace, which will perform query-replace by parsing
the output of a grep command. This is useful because you can search
for "foo" in 100 files, then do the query-replace on each occurrence
skipping from file to file.
Your mode may support this already. In C mode and Makefile mode, at least, M-q (fill-paragraph) will insert line continuations in the fill-column and wrap your lines.
What mode are you editing this in?