Reversing siblings html elements with Emacs - emacs

I've a long list of divs that I need to reorder (reverse).
I need to transform this (numbered titles were added only for the sake of clarity):
<div class="some-classes">
<h2>Title 3</h2>
<!-- other html contents but not divs -->
</div>
<div class="some-classes">
<h2>Title 2</h2>
<!-- other html contents but not divs -->
</div>
<div class="some-classes">
<h2>Title 1</h2>
<!-- other html contents but not divs -->
</div>
Into this:
<div class="some-classes">
<h2>Title 1</h2>
<!-- other html contents but not divs -->
</div>
<div class="some-classes">
<h2>Title 2</h2>
<!-- other html contents but not divs -->
</div>
<div class="some-classes">
<h2>Title 3</h2>
<!-- other html contents but not divs -->
</div>
Is it possible to do this with Emacs?

There is certainly more than one way to achieve this in Emacs. For instance, you could do the following. CAVEAT: you've got make sure that you make no mistakes, i.e, no typos when following the instructions below, or else you might not get the results you're after.
Mark the region of your document that contains the div's and then type M-x narrow-to-region
This will make the following edits somewhat easier and also makes sure that you do not accidentally change parts of the documents you do not want to change.
Move to the beginning of the line of the last of the <div class=...>-entries. Make sure that no region is marked.
Type C-x (
As a result, you should see the message Defining kbd macro... in your minibuffer.
Hit C-space to start marking a region
Type C-r to start a backward search.
You should now see I-search backward: in your minibuffer
Type the string <div, and then hit Enter.
While you type in that string, point should already move to the beginning of the line of the previous div, the one just above the last one. The the whole body of that second-to-last div should become highlighted as you are marking the region that contains it. (This automatic marking of the region is why we did step 4. above.)
C-w will kill that region, i.e., will delete the complete second-to-last div-section from your buffer.
Type M-> to jump to the end of the buffer
Type C-y to insert the div you just deleted at the end of your buffer
Type C-u C-space and then again: C-u C-space
The point should now be back at the beginning of the div that was the last div in the buffer when we started.
Type C-x )
The last step should give you a message Keyboard marco defined in the minibuffer. Now comes the magic:
Type C-x e
Emacs will automatically repeat steps 4-10 for you with the effect of moving another div section to the end of the buffer.
Keep typing the character e until the whole list is reversed.
Finally, get the rest of the contents of your file back for editing:
M-x widen

A. Manually (slow if you have many such elements to sort):
M-x nxml-mode RET
M-x set-variable nxml-sexp-element-flag t RET
M-< C-M-t C-M-t C-M-t C-M-b C-M-b C-M-b C-M-t C-M-t
or
M-< C-M-f C-M-t C-M-t C-M-b C-M-b C-M-t
or
M-< C-M-f C-2 C-M-t C-2 C-M-b C-M-t
or
M-< C-M-k C-M-f C-M-t RET C-y
or
M-> C-M-<backspace> C-M-b C-M-b C-M-t C-M-b C-M-b C-y
or
M-< C-M-f C-M-k C-M-t C-M-b C-y RET
or
M-< C-M-f C-M-t C-M-k C-M-b C-M-b C-y RET
etc.
Step 2 lets the sexp commands treat a full element as a sexp (otherwise, it treats only a tag, such as <div class="some-classes"> or </div>, as a sexp).
C-M-f and C-M-b move over sexps (elements, in this case).
C-M-t transposes the elements before and after point.
C-M-k kills the next element. C-M-<backspace> kills the previous element.
B. A command to do it all: M-x foo:
(defun foo ()
"Reverse the order of the top-level elements in buffer."
(interactive)
(let ((nxml-sexp-element-flag t)
(o-mode major-mode))
(unwind-protect
(progn
(goto-char (point-min))
(nxml-mode)
(sort-subr
nil
(lambda ()
(forward-sexp)
(unless (eobp) (backward-sexp)))
(lambda () (backward-sexp) (forward-sexp))
nil
'forward-sexp
nil))
(funcall o-mode))))
See the Elisp manual, node Sorting.

Related

Save and execute an Emacs keyboard macro

I have a problem for execute a personal macro in another session in Emacs. I succeeded to create macro and execute then but, after I want to save it for execute them in another time.
For this I write this code in ~/.emacs
(fset 'psTest
(lambda (&optional arg) "Keyboard macro."
(interactive "p")
(kmacro-exec-ring-item (quote ("^X2^X2^X2^X2" 0 "%d")) arg)))
but when I call my macro in another file [ M- x psTest ], Emacs doesn't execute my macro but writes key in my file
^X2^X2^X2^X2
all my commands:
In terminal:
user#PC $ emacs ~/.emacs
In emacs:
C-x (
C-x 2
C-x )
C-x C-k n psTest
M-x insert-kbd-macro [ENTER] psTest [ENTER]
C-x C-c
In terminal:
user#PC $ cat ~/.emacs :
(fset 'psTest
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("^X2" 0 "%d")) arg)))
user#PC $ emacs ~/test
In emacs:
M- psTest
Now my macro [M- psTest] write ^X2 in my file instead of execute [^X2] which split the screen.
Where is my error?
Thanks
The problem lies in the sequence "^X2" in your macro definition. It contains two characters ^ and X rather than the single character 0x18 in the charset ascii (ASCII (ISO646 IRV)) which is used by emacs to refer to C-x but is displayed the same, though probably in a different color. If you replace the former two-letter-sequence with the latter character and evaluate the definition again, it should work.
You can insert the character with
C-x8RET #x18 RET.
PS: To display information about a specific character at point you can use
M-x desribe-char or what-cursor-position, which is bound to C-x = by default.
I agree with Simon Fromme.
To insert the C-x character, you may omit the #x prefix from his answer and type:
C-x8RET18RET
But you may also simply type C-qC-x in case you don't know the hexadecimal value of the ascii code of this or any other character!
Nevertheless, in your case, I would rather search for the function associated to the C-x 2 sequence. You'll easily find it is split-window-below using either:
C-h k C-x 2 RET
or M-x edit-last-kbd-macro RET
Then you can write some code easier to copy/paste/save like:
(fset 'psTest #'split-window-below)
or
(defun psTest ()
(interactive)
(split-window-below))
This might be a good way to start learning emacs-lisp!

C-a to go to the first character in emacs using ipython-mode

C-a brings me back to the beginning of the line. But I would like C-a to bring me back to the beginning of the text when writing python code.
if(test) :
print 'this is a test' # here i want to C-a
Now, at the end of the line starting with print i would like to press C-a to go to the p of print, not to the beginning of the line. Which function does this in emacs?
infact there is a direct global key binding for this M-m
There is 'misc-cmds.el' by Drew Adams which has the command beginning-or-indentation. It's probably what you are looking for. From the docstring:
Move cursor to beginning of this line or to its indentation.
If at indentation position of this line, move to beginning of line.
If at beginning of line, move to beginning of previous line.
Else, move to indentation position of this line.
Find it at http://www.emacswiki.org/cgi-bin/wiki/misc-cmds.el.
I use
back-to-indentation
I bound it to C-x C-a in my .emacs:
(global-set-key "\C-x\C-a" 'back-to-indentation)
I made a small custom function to do this in my setup. When I press C-a and it's not at the indentation, it goes back to the indentation. If it is, it goes to the beginning of the line.
;; Remap C-a to more useful behaviour (a press anywhere other than at the indentation preforms the effect of back-to-indetation, otherwise, the normal C-a behaviour is used.
(global-set-key (kbd "C-a") (lambda () (interactive)
(let ((previous-point (point)))
(back-to-indentation)
(if (equal (point) previous-point) (move-beginning-of-line 1)))))

Basic HTML operations in Emacs

I am working with HTML in Emacs and I am looking for ways to make basics operations as:
convert list of string to HTML-list
one
two
three
to
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
add class to list of elements
<a></a>
<a></a>
<a></a>
to
<a class="one"></a>
<a class="one"></a>
<a class="one"></a>
Is there any extensions which can helps me?
I would do this with a macro:
Move to the first line, and type C-x (
Type the <li>, move to the end </li>, and move to the next line
End and repeat the macro on the remaining lines with C-x e e e e e...
This can easily be generalized to add classes to your <a> tags, and many other things.
You should take a look at zencoding , it's pretty useful. Here's a youtube video showing it with yasnippet, showing some functionality like what you want.
You can add class to list of elements using command M-x replace-string.
Here is an Emacs Lisp function which performs the first task (operates on selected text):
(defun my-make-list (start end)
(interactive "r")
(insert "<ul>\n")
(mapcar '(lambda (line) (insert (concat " <li>" line "</li>\n")))
(split-string (buffer-substring start end) "\n"))
(insert "</ul>")
(delete-region start end))
In the second case I would just use search/replace.

Convert Emacs macro into Elisp

Is there a way to convert an emacs macro into elisp, not like what M-x insert-kbd-macro does, the actual activity becoming elisp statements.
Thanks for your help.
Nope, sorry. There is no trivial way to convert an emacs macro into elisp.
Update: There's been some work on Emacs to start down this path. See this thread as a starting point. It's still not possible (June 2010), but there's activity.
The first reason I can think of is dealing with interactive commands and translating keystrokes into proper arguments for functions.
Think of the following sequence:
C-x b .em TAB RET
This begins the command to switch to a buffer, types three characters, uses TAB completion to complete it and RET to accept. The equivalent lisp for the end result (in an emacs session where the TAB completion is unique) is:
(switch-to-buffer ".emacs")
Thinking of completion, there are also interactions with expansion of all types (dabbrev, hippie-expand, etc.).
A starting point can be M-x edit-last-kbd-macro which (in my case) shows this:
;; Keyboard Macro Editor. Press C-c C-c to finish; press C-x k RET to cancel.
;; Original keys: C-x b .em <tab> RET
Command: last-kbd-macro
Key: none
Macro:
C-x b ;; switch-to-buffer
.em ;; self-insert-command * 3
<tab> ;; pabbrev-expand-maybe
RET ;; newline-and-indent
Which at least gives you some of the function names. But you'll see that RET is labeled as 'newline-and-indent which is incorrect because at the time of the macro execution, the minibuffer is active and the binding is in fact 'minibuffer-complete-and-exit. Similarly, the proper binding for TAB is 'minibuffer-complete.
I made a package that allows pretty much exactly this at https://github.com/Silex/elmacro
It has some quirks but it works pretty well... for example, the following macro:
F3 C-e M-b M-u C-a C-n F4
Generates the following elisp:
(defun upcase-last-word ()
"Change me!"
(interactive)
(move-end-of-line 1)
(backward-word 1)
(upcase-word 1)
(move-beginning-of-line 1)
(next-line 1 1))

Emacs equivalent of Vim's yy10p?

How can I copy a line 10 times easily in Emacs? I can't find a copy-line shortcut or function. I can use C-aC-spcC-eM-w to laboriously copy the line but how can I then paste it more than once?
Any ideas before I go and write my own functions.
you can use a keyboard macro for that:-
C-a C-k C-x ( C-y C-j C-x ) C-u 9 C-x e
Explanation:-
C-a : Go to start of line
C-k : Kill line
C-x ( : Start recording keyboard macro
C-y : Yank killed line
C-j : Move to next line
C-x ) : Stop recording keyboard macro
C-u 9 : Repeat 9 times
C-x e : Execute keyboard macro
Copying:
If you frequently work with lines, you might want to make copy (kill-ring-save) and cut (kill-region) work on lines when no region is selected:
(defadvice kill-ring-save (before slickcopy activate compile)
"When called interactively with no active region, copy a single line instead."
(interactive
(if mark-active (list (region-beginning) (region-end))
(list (line-beginning-position)
(line-beginning-position 2)))))
(defadvice kill-region (before slickcut activate compile)
"When called interactively with no active region, kill a single line instead."
(interactive
(if mark-active (list (region-beginning) (region-end))
(list (line-beginning-position)
(line-beginning-position 2)))))
Then you can copy the line with just M-w.
Pasting:
Often a prefix argument just performs an action multiple times, so you'd expect C-u 10 C-y to work, but in this case C-y uses its argument to mean which element of the kill-ring to "yank" (paste). The only solution I can think of is what kronoz says: record a macro with C-x ( C-y C-x ) and then let the argument of C-u go to kmacro-end-and-call-macro instead (that's C-u 9 C-x e or even just C-9 C-x e or M-9 C-x e).
Another way:
You can also just stay in M-x viper-mode and use yy10p :)
You may know this, but for many commands a "C-u 10" prefix will do the trick. Unfortunately for the C-y yank command, "C-u" is redefined to mean "go back that many items in the kill ring, and yank that item".
I thought you might be able to use the copy-to-register and insert-register commands with the C-u prefix command, but apparently that doesn't work either.
Also C-x z, "repeat last command" seems to be immune to C-u.
Another thought would be to use M-: to get an Eval prompt and type in a bit of elisp. I thought something like (dotimes '10 'yank) might do it, but it doesn't seem to.
So it looks like using C-u on a macro may indeed be the best you can do short of writing your own little function.
Had I a vote, I'd vote for kronoz answer.
You don't need both C-x ) and C-x e in this example.
You can just give the repeat argument straight to C-x ). This stops recording and repeats the macro, in one step. Or you can skip C-x ) and go straight to C-x e, since C-x e will end the recording before doing the repeats.
Which way to choose depends on how you like your repeat count to work. For C-x ) you say how many repeats you wanted in total (so 10 in this case). For C-x e you need to say how many more repeats are left (i.e. 9).
C-a C-k C-k will also kill the trailing newline, so you don't have to put it back yourself later. It's quicker than using the mark, and doesn't need you to change any variables.
Even better (unless you're in a terminal), you can use C-S-Backspace* to kill the entire line, regardless of where you are in it.
[* If you're using X windows, make sure to type shift (not alt) or you may terminate your session!]
Speaking of terminals, M-9 is a nice alternative if you find you can't type C-9.
In Emacs 22 and higher, by default F3 starts a macro and F4 end/repeats a macro. You just hit F3 to start recording, hit F4 when you're done, and hit F4 again to repeat the macro. (F4 also takes an argument.)
Putting this all together, to get 10 copies of the current line:
C-S-Backspace : kill this line
F3 : start macro
C-y : yank the line
C-1 C-0 F4 : make that 10 yanks
Not quite as short as y y 10 p, but pretty close. :)
Here's a function I took from an OS/2 port of Emacs. (Yes, I've been using Emacs for a while.)
;; Author: Eberhard Mattes <mattes#azu.informatik.uni-stuttgart.de>
(defun emx-dup-line (arg)
"Duplicate current line.
Set mark to the beginning of the new line.
With argument, do this that many times."
(interactive "*p")
(setq last-command 'identity) ; Don't append to kill ring
(let ((s (point)))
(beginning-of-line)
(let ((b (point)))
(forward-line)
(if (not (eq (preceding-char) ?\n)) (insert ?\n))
(copy-region-as-kill b (point))
(while (> arg 0)
(yank)
(setq arg (1- arg)))
(goto-char s))))
I have that bound to F9 d:
(global-set-key [f9 ?d] 'emx-dup-line)
Then I'd use C-u 10 F9 d to duplicate a line 10 times.
The only way I know to repeat arbitrary commands is to use the "repeat by argument" feature of keyboard macros.
C-a C-space down M-w C-x ( C-y C-x ) C-9 C-x e
C-a : Go to start of line
C-space : Set mark
down : Go to start of following line
M-w : Copy region
C-x ( : Start keyboard macro
C-y : Yank copied line
C-x ) : End keyboard macro
C-9 C-x e : Execute keyboard macro nine times.
That's kind of weak compared to vim. But only because vim is amazingly efficient at this sort of thing.
If you are really pining for modal vi-like interaction, you could use one of the vi emulation modes, such as viper-mode. Check in the section "Emulation" of online emacs manual.
You will want to kill the line: C-a C-k, and then C-y or ?
I don't know of a direct equivalent (C-y 10 times is the best I know), but you may be interested in Viper, which is a vi emulation package for emacs. It's part of the standard emacs distribution.
Based on Baxissimo's answer I defuned this:
(defun yank-n-times (arg)
"yank prefix-arg number of times. Not safe in any way."
(interactive "*p")
(dotimes 'arg (yank)))
Set that to some key, call it with a prefix argument, and off you go.
edit (also modified the interactive call above to be less lousy)
Or, here's a version that can sort of replace yank-pop:
(defun yank-n-times (&optional arg)
"yank prefix-arg number of times. Call yank-pop if last command was yank."
(interactive "*p")
(if (or (string= last-command "yank")
(string= last-command "yank-pop"))
(yank-pop arg)
(if (> arg 1)
(dotimes 'arg (yank))
(message "Previous arg was not a yank, and called without a prefix."))))
the message is kind of a lie, but you shouldn't call it without a prefix of greater than 1 anyway, so.
Not sure if it's a good idea, but I replaced M-y with this, I'll see how that goes.
First you need this key binding in your .emacs:
;; yank n times
(global-set-key "\C-y" (lambda (n) (interactive "*p") (dotimes (i n) (clipboard-yank))))
Then you can do:
C-a C-SPC C-n M-w C-u 10 C-y
C-a C-SPC C-n M-w - select whole line
C-u 10 C-y - repeat "clipboard-yank" 10 times
You get the line with C-k, you make the next command happen ten times with C-u 10, then you paste the line with C-y. Pretty simple.
If you always want C-k to do the whole line, you can set kill-whole-line to t. No more fiddling with C-a or C-e.
There's a lot you can do with fancy kill rings, registers, and macros, and I encourage you to learn them, but yanking a line ten times doesn't have to be tough or strange.