📜 ⬆️ ⬇️

Macros in Emacs: form teams for processing



Do not forget your roots, remember, there are things much higher ...
Caste here

Life story


')
Many began their computer life with games. Whoever did not start, he plays chess on a wooden board, like some other president. I do not play chess, I play Starcraft and other similar games. Once I played for many hours, but the time passed and the games turned into serious lessons, giving some result. At the same time, although the games were reborn, the habits remained old. Sometimes you want to play.

What is not in chess? In chess, there are no live patrols, troops, minefields in the most favorite places and a lot more, which is sometimes not enough, while you recompile some program by editing it. Nostalgia captures and we slowly begin to look for something similar in the software environment. And we find!

Today we will talk about funny macros.



In Emacs, there are two kinds of macros — boring and fun. Boring ones are macros in Lisp, and fun ones are keyboard macros that are well known to many. Here about the second and will be discussed.

Priming - master buttons



When you start the game for the first time, you see in front of you one builder who stands and does nothing. Chasing him around the neighborhood, you start building something, and at the same time you notice the highlighted letters in the names of buildings and actions. These letters are access keys through which you can quickly perform actions. In the future, the game is reduced to the sequential pressing of these letters at the right time.

What is a macro?



Everyone knows that there are such things in programs that are called “macros”, and Emacs itself contains this concept in the root of its name (Editor MACroS), so don’t know this concept when using Emacs and do not try them - shame-like. At the same time, not everyone knows further macros F3 and F4, by analogy with macros in other programs, in which they are in their infancy.

What are macros in emacs?



Macros in Emacs, generally speaking, of the common with other programs, only keyboard writing and have. Otherwise, it is a powerful apparatus that can be used to its fullest, to which, as a rule, no one comes. One guy on the Internet, in the midst of many decent settings for Emacs, even suggested to hang another action on a macro combination, because it is never said to be used. Apparently, he thought that Emacs macros are the same as everywhere else, and they boil down to two keys — recording and playback.

In Emacs, the situation is completely different:

First, when recording macros, they fall into the macro ring, for which a number of operations are defined. That is, macros there are not just recorded for memories of them, but you can choose them by walking around the ring back and forth. And you can not just walk around the ring, but also go into each macro, making changes to it.

Secondly, this ring itself is not simple. Such control keys are attached to it, which are designed for permanent operations with it, which is why the initial key combination for access to the ring is remembered by Emacs so that it does not need to be pressed each time.

If you press Ctrl + x + Ctrl + k, then you will enter the keyboard namespace. After that, holding Ctrl, you can press many keys that are responsible for actions with the ring and the current macro.

Consider an example:

1) We write two macros. The first macro will insert the number 1, and the second will insert the number 2.

F3 1 F4
F3 2 F4


From the bottom, after each click on F3, you will see that the recording has started, and after each click on F4, you will see that the macro is recorded. After these actions, 12 are displayed in the buffer and we have an invisible ring in which there are two macros. The second macro is selected (or active).

2) Run the selected macro. Many would like to press F4 now, because it is so simple, but we will not press it. We are now passing the ring, and not how a macro can be performed in a quick way.

Push long start

Ctrl + x + Ctrl + k + Ctrl + k


We saw that the number 2 was inserted, while we do not release Ctrl, but continue to press the buttons

Ctrl + p + Ctrl + k


And first, after p, we see that at the bottom (in the minibuffer) something is written (number 1), and then after k, we see how the number 1 is inserted. While holding Ctrl, we press further

Ctrl + n + Ctrl + k


And first, after n, we see that the information on the current macro is written in the same way (number 2), and then after k, we see how the number 2 is inserted.

3) Release all the buttons. 12212 remained on the screen. The first two digits participated in the macro recording, the other three digits - the result of the macro execution.

What happened? We recorded two simple macros, and then entered the keyboard namespace by pressing the prefix combination Ctrl + x + Ctrl + k. Acting in this namespace, we first executed the second macro, then switched from the second macro to the first one and executed the first one, and then switched from the first macro back to the second one and again executed the second one.

If you did everything correctly, then the left Ctrl was never released after entering the space and at the same time only the kpkn k keys were pressed with the right hand.

This is the difference in the launch of the macro: if we have a single macro, then it is more convenient for us to run it through F4; if we have several macros in the ring and we need to run them alternately, then we use a long start.

What else can you do with this ring?



The ring itself can be rotated by changing the current element, so the ring has no fixed beginning or end. At each moment of time, the last element in the ring is considered the current element, and the first element is the element following it. When a new macro is recorded, it will be added to the ring after the current element, becoming the last element in the ring. So you can create the desired order of macros in the ring.

Most of the operations with the ring (forward transitions n and back p , doing k , deleting d , editing the macro) work in the same way, requiring only one button press, which makes the use of the ring speed and convenient. But there are also operations that, in theory, should work the same way, but do not work. Perhaps they were added later by another author who did not notice this ecosystem.

To clean the ring by removing some or all of the elements, you need to click

Ctrl + x + Ctrl + k + Ctrl + d


And then just hold down Ctrl and press dd d.

And you can change the order of macros through

Ctrl + x + Ctrl + k + Ctrl + t


Sometimes this is required in conjunction with cleaning the ring from failed macros.

And this is exactly the case when the removal of elements works in an abbreviated version, and the exchange of elements only in full. So most often you just need to know what actions need to be typed in full. As a rule, such inconvenient actions are combined with each other because they are used less frequently than the main ones.

The length of the ring limit is 8 macros, but in the Emacs settings, of course, you can easily increase it (for example, set 32). It’s a lot or a little — for individual manually recorded macros, it may seem like 8 is enough. But in order to seriously use this, 8 is not enough.

We make the first fighters



Chasing the builder, when we built the first buildings open for construction, we find barracks in which you can make the simplest fighters. Usually there are two of them: one for close combat, the other for long-range. As they are created, we also notice the highlighted letters for quick access to these fighters and their actions.

How can I create a macro?



At first we, of course, write them down through F3 F4. Then we find the macro editor, in which we find the only way to edit already recorded macros, and everything goes back to F3 F4.

In fact, there are two states of the ring: there is nothing in the ring and there is something in the ring. And for these two states there are ways to create a new macro.

When there is nothing in the macro ring and we just want to create a macro, we can apply the following methods:

1) Start the macro editor, which will offer to create a macro.

Ctrl + x + Ctrl + k + Ctrl + ey


This method requires that something be necessarily written to the macro, it will not be possible to create an empty macro.

2) Apply a hack to F3 F4.

F3 + Ctrl + u + F4


Emacs writes an error in the minibuffer, but an absolutely empty macro is created.

Wrong type argument: integerp, (4)


3) Run the command to read the macro from the text.

Ctrl + SPC + Ctrl + SPC + Alt + x + read-kbd-macro


There is a side effect: since we set and remove the marker, the ring of markers is changing, which might be necessary somewhere. Through Ctrl + u + Ctrl + SPC you can usually walk on this ring, thus an extra position may appear.

When there is at least one macro in the macro ring and we just want to add a macro, we can apply the following methods:

1) Copy a macro through a single-line macro editor.

Ctrl + x + Ctrl + k + SPC + Ctrl + k


The editor for the current macro opens, but because of Ctrl + k, the macro will be copied to the new macro, discarding all the contents.

2) Apply a hack to F3 F4.

F3 + Ctrl + u + F4


Here the method is the same as with the empty ring.

When there are macros in the ring, the read-kbd-macro command will not create a new macro, but write to the selected one. Therefore, the method with this command does not work here. You can only overwrite the selected macro, which may contain something important.

Here, many may have the question "why do we need an empty macro?". The fact is that macros are large and small, complex and simple. Writing a macro can take much longer than writing it quickly through the editor. In addition, not always the seemingly correct recording of a macro turns out to be like this when it is executed. You need to be able to use the editor, especially since it is elementary.

How can I edit a macro?



For the next experiment, we will need to make two macros and prepare the third one completely empty.

F3 123 F4
F3 456 F4
F3 Ctrl+u F4


We have three macros in the ring: one inserts 123, another inserts 456, the third macro is empty and is selected. We need to write in the third macro the contents of the first two.

We move to the first macro.

Ctrl + x + Ctrl + k + Ctrl + n


Open it for editing

Ctrl + e


We see

 ;; Keyboard Macro Editor. Press Cc Cc to finish; press Cx k RET to cancel. ;; Original keys: 123 Command: last-kbd-macro Key: none Macro: 123 ;; self-insert-command * 3 


Go to the line at the top, where it is written

 ;; Original keys: 123 


And copy to buffer 123.

Then just close the buffer.

Ctrl + x + k + <RET>


Then go to the second macro

Ctrl + x + Ctrl + k + Ctrl + n


Open it for editing

Ctrl + e


We see

 ;; Keyboard Macro Editor. Press Cc Cc to finish; press Cx k RET to cancel. ;; Original keys: 456 Command: last-kbd-macro Key: none Macro: 456 ;; self-insert-command * 3 


Go to the line at the top, where it is written

 ;; Original keys: 456 


And copy to buffer 456.

Then just close the buffer.

Ctrl + x + k + <RET>


Then go to the third macro.

Ctrl + x + Ctrl + k + Ctrl + n


Open it for editing

Ctrl + e


We see

 ;; Keyboard Macro Editor. Press Cc Cc to finish; press Cx k RET to cancel. ;; Original keys: Command: last-kbd-macro Key: none Macro: 


And paste after the line "Macro:" via Ctrl + y, Alt + y, Ctrl + y our copied lines 456 and 123.

 ;; Keyboard Macro Editor. Press Cc Cc to finish; press Cx k RET to cancel. ;; Original keys: Command: last-kbd-macro Key: none Macro: 123 456 


Then save it via Ctrl + c + Ctrl + c.

Now we have three macros in the ring: the first is 123, the second is 456, the third is 123456.

Naturally, we could write all this manually (123456), without copying anything, but these macros are too simple. In more complex cases, writing the sequence to the beginning will not be so easy, and writing a large macro through F3 can drown in errors. Therefore, small macros are written one after another, and there is always a complete record in the editor that can be simply copied.

The second method, which is also often used, is through read-kbd-macro. We simply select the text and execute read-kbd-macro. Then whatever macro we are (full or empty), it will be overwritten with this text. Just need to remember that spaces and line breaks will disappear.

The spaces in the editor are written in the form of SPC SPC SPC, so copying through the editor does not often require additional actions.

What is in the macro?



What the macro consists of - of three things: a sequence of clicks, a counter and a format string of the counter. There are two more things that can often be noticed, the name of the macro and its keyboard combination. If the first three things are in each macro, then the remaining two are external and are attached to the macro at will through an additional code. Therefore, they can be either tied to a macro or untied from it.

The counter itself inside the macro can be confusing, since it is not immediately obvious how it changes when the macro is called. The answer is simple: it does not change at all. This counter is simply stored in a macro and works completely independently of it. A format string refers only to the counter, determining its output.

From what is often used from the macro-insides, you can select only the “request for continuation”. Its essence boils down to the following: during operation, the macro by a special feature in its sequence determines that it is necessary to stop and ask the user about further actions. Why do you need it? The command to execute a macro has an argument that specifies the number of its repetitions. And when we process some unknown data with a macro, using the argument to automatically repeat the macro, often they need to be processed selectively, because the macro during such execution can find fragments that need to be skipped.

Even if we recorded a macro without this “request for continuation”, then we can add it through the macro editor at any time. If we added it, but it was no longer needed, then through the editor it can be removed as quickly.

And it looks like this

Cx q


You can directly open macro 123 and insert such lines between the numbers, then run it and see the request for continuation

 ;; Keyboard Macro Editor. Press Cc Cc to finish; press Cx k RET to cancel. ;; Original keys: 1 Cx q 2 Cx q 3 Command: last-kbd-macro Key: none Macro: 1 ;; self-insert-command Cx q ;; kbd-macro-query 2 ;; self-insert-command Cx q ;; kbd-macro-query 3 ;; self-insert-command 


If we now run the macro with the argument

Alt + 5 + F4


When executed, it will ask each time at the appropriate places, write down a number and continue or not write down a number and continue.

If someone did not notice, now everything is ready to test this experiment. You can copy the macro directly from this text from the line with ";; Original keys:" to the clipboard, open the macro editor in your Emacs via Ctrl + x + Ctrl + k + Ctrl + e, insert this line after the line "Macro : ”, Press Ctrl + c + Ctrl + c, and then press Alt + 5 + F4.

What macros to do, large or small?



When you make macros in any programs, the question arises, how best to do one large or many small ones. Experience suggests that a large macro, even while recording, may turn on and have to be overwritten with the same risk. If we talk about storage, then at the slightest change in the data that it converts, you will need to deal with its change, and the change leads to debugging. It is easy to get bogged down in such a macro by simply starting editing some unimportant text through it.

There is another aspect - macros require repetitions. It often happens that you need to repeat only a small subset of the actions of the whole macro cyclically. To do this, one would have to single them out of a monolith and in the same way make a small macro out of them, as one could do from the very beginning.

Therefore, small macros are better. They can be repeated, they can be replaced, they can be corrected and their order can be easily changed without destroying the entire system.

We send soldiers in the first campaign



When the first soldiers are done, they go hiking to break something and fight with someone. So it turns out the strength, armor and speed of different types of fighters, so that later you can properly distribute them during planned campaigns.

What macros are there?



Very often, macros are applied only to the text, since the rest of their capabilities are not obvious. In Emacs, macros can be divided into three types: for changing text, for changing appearance, and for executing functions.

Most of the actions to create windows in the frame and resize them are performed many times, but few know that all this can be done by macros. Now we will write a simple macro and play with it.

1) Open the editor and write the first macro.

Cx 2 Cx 3 Cx o Cx o Cx 3 Cx o


2) Write the second macro.

123


3) Now in the clean window, select the first macro and run it three times.

Alt + 3 + Ctrl + x + Ctrl + k + Ctrl + k


Without releasing Ctrl, go to the second macro.

Ctrl + n


Without releasing Ctrl, run it.

Ctrl + k


If done correctly, you will see such a picture.

Show



It is easy to make such a picture.

Show



And such

Show



As you can see, we just recorded a simple macro of splitting the windows, and they can make such different patterns.

A more useful example is the opening of two independent consoles. If we program, it is often necessary to start one in one console, and another in another. At the same time, we need to edit the source.

Write the macro and execute

Cx 2 Cx o Cx 3 Cu <<shell>> shell-compil RET Cx o Cu <<shell>> shell-exec RET M-- 2 Cx o


See a text buffer with two different consoles below it.

Show



Now write this macro

Cx o Cx k RET yes RET Cx o Cx k RET yes RET Cx 0 Cx 0


This is the reverse action - closing windows with consoles. Now a set of consoles can be opened with one macro and closed with another. And switching between these macros can be a way we already know.

Here is another example of a macro, but no longer processing the text or creating a window, but performing some set of actions in the file manager mode.

Record a macro

+ dir <f3> 2*RET Cx Cf file . txt RET abcd Cx Cs Cx k RET g ^ g


Set him a counter

Ctrl + x + Ctrl + k + Ctrl + c
1
RET


Create a directory somewhere and go to it via Ctrl + x + d. Having executed a macro in it five times, you will see five directories created, where each directory will have its own file with its own text.

Show



So you can create and delete directory trees, change the contents of files or their external data like rights or names. Similarly, you can use macros in consoles to automatically compile and run programs. In addition, one macro can interact with different consoles, switching between them.

Here is another example.

echo SPC x RET Cx o echo SPC y RET Cx o


Show



Cooking soldiers on base



When we found out in the first battle the capabilities of different types of soldiers, we can already make specific types to solve already defined tasks and accumulate them in a safe place where no one will beat them. We begin to find out what the composition and in what quantity is more effective.

How to hide macros?



When during the Emacs session we have done a lot of all sorts of convenient macros, it becomes a pity to throw them away. Searches on the Internet do little, on the best pages dedicated to Emacs, it is written only about converting a macro to a Lisp view and then saving it as a normal function. It seems that this is what is needed, but here you encounter a known problem: this function needs to memorize a name that will be forgotten in a couple of days. There is an even more difficult option - when the macro itself is forgotten. Adding these two things results in <forgotten macro> + <forgotten name> = 0. But the most important thing, and this is the main problem, - such macros are not inserted into the macro ring, therefore they fall out of this wonderful machine. It turns out a bundle of macros on those that were saved, and those that were recorded during the current session.

To convert a macro to a Lisp view, we switch to it and run insert-kbd-macro.

Here are macros 123 and 456

 (setq last-kbd-macro "123") (setq last-kbd-macro "456") 


It seems simple and tasteful, but they are not suitable for loading, since both are loaded into the last macro, and for this you have to make an empty macro. To create macros suitable for loading, you need to give them both names through Ctrl + x + Ctrl + k + n (not to be confused with switching to the next macro).

When they have onetwothree and fourfivesix names, the insert-kbd macro command works differently.

 (fset 'onetwothree (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("123" 0 "%d")) arg))) (fset 'fourfivesix (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("456" 0 "%d")) arg))) 


This is now cast into the Lisp file, which connects to the Emacs init files. This is considered a classic way of saving macros, which will be available under these names the next time Emacs is booted. It does not take into account that the macro ring will be empty.

Your way was found quickly. I had to pick it all up and get to the ring, and then learn how to push macros into it without any names.

 (defun make-my-macros() "Make macros." (interactive) (add-to-list 'kmacro-ring '("123" 0 "%d")) (add-to-list 'kmacro-ring '("456" 0 "%d"))) (make-my-macros) 


Now, having executed this code through eval-buffer, you can at any time load macros into the ring, while the ring remains open to writing new macros. If you throw this code into the initialization file, then to reload the macros it will be enough to call the function.

Why is this better than normal functions?



Even if you know lisp well (not even lisp itself, but the names of Emacs internals), in any case, writing one function will take longer than recording a macro. At the same time, any changes to the function will be stopped due to the difficulties of debugging, saving and reloading the function. The homework of one function in symbiosis with others will not go well either, since many unimportant things will have to be memorized by heart. And macros - today they are here, and tomorrow - there. They are more free. They can be changed on the go and copied without any problems and the fear of loss or fear of subsequent heavy debugging. If there is an error in the macro, it is simply copied and all experiments are performed on the copy in the macro editor. When everything is ready, the old version is removed and the new one moves to its place.In this case, the effect of one small macro is often equal to the effect of a heap of functional structures.



, . , , , . , .

?



Emacs'. , , . , Emacs' — , .

, , . , . , .

I have several modes: one for Habra, another for Yutyube, and the rest for forums. And some of them have already developed their own system of functions and macros. In each mode, macros are grouped by task, and for each task its set of macros can be loaded into the ring. In addition, the task itself and the composition of the macros in it can be described in the comments in the function, which can then be easily viewed through the help of the mode available via Ctrl + h + m.

But what does the help to the regime for Habra look like?

 Habra minor mode (indicator Habr): Mode for `http://www.habrahabr.ru'. key binding --- ------- Cc Prefix Command Cc m Prefix Command Cc mh Prefix Command Cc mhc Prefix Command Cc mhm Prefix Command Cc mhq habra-wrap-quote Cc mhmg habra-make-macro-general Cc mhc 1 habra-wrap-code Cc mhc 2 habra-wrap-source 


And so it looks like help to the regime for Yutyuba

 Youtube minor mode (indicator YouTube): Mode for `https://www.youtube.com'. key binding --- ------- Cc Prefix Command Cc m Prefix Command Cc my Prefix Command Cc mym Prefix Command Cc mymg youtube-make-macro-general Cc mymp youtube-make-macro-playlist 


You can always remember the names of functions in this way, and then go into these functions and see their comment about the macros in them.

The mode itself for Habra looks like this

Source code
 ;; Habra mode (defun habra-wrap-quote() "Wrap selection to <blockquote></blockquote> tags." (interactive) (if (not (mark)) (set-mark (point))) (narrow-to-region (mark) (point)) (goto-char (point-min)) (insert "<blockquote>") (goto-char (point-max)) (insert "</blockquote>") (set-mark (point-min)) (widen)) (defun habra-wrap-code() "Wrap selection to <code></code> tags." (interactive) (if (not (mark)) (set-mark (point))) (narrow-to-region (mark) (point)) (goto-char (point-min)) (insert "<code>\n") (goto-char (point-max)) (insert "\n</code>") (set-mark (point-min)) (widen)) (defun habra-wrap-source() "Wrap selection to <source></source> tags." (interactive) (if (not (mark)) (set-mark (point))) (narrow-to-region (mark) (point)) (goto-char (point-min)) (insert "<source>\n") (goto-char (point-max)) (insert "\n</source>") (set-mark (point-min)) (widen)) (defun habra-make-macro-general() "Make general macros." (interactive) ;; Add a title to spoiler (add-to-list 'kmacro-ring '("\Cs<spoiler\Cm title=\"\"\Cb\Cu\C-xq" 0 "%d")) ;; Replace * to <h1> (add-to-list 'kmacro-ring '([?\Cu ?\Cs ?^ ?\\ ?* ? ?\Cm ?\Cx ?q ?\M-2 ?\C-? ?\M-\\ ?< ?h ?1 ?> ?\Ce ?\M-\\ ?< ?/ ?h ?1 ?>] 0 "%d")) ;; Replace ** to <h2> (add-to-list 'kmacro-ring '([?\Cu ?\Cs ?^ ?\\ ?* ?\\ ?* ? ?\Cm ?\Cx ?q ?\M-3 ?\C-? ?\M-\\ ?< ?h ?2 ?> ?\Ce ?\M-\\ ?< ?/ ?h ?2 ?>] 0 "%d")) ;; Change < to &lt; (add-to-list 'kmacro-ring '("\Cs<\Cm\C-xq\C-?&lt;" 0 "%d")) ;; Change > to &gt; (add-to-list 'kmacro-ring '("\Cs>\Cm\C-xq\C-?&gt;" 0 "%d")) ;; Change leading space to &nbsp; (add-to-list 'kmacro-ring '("\Cu\Cs^ \Cm\C-xq\C-?&nbsp;" 0 "%d")) ;; Change double space to &nbsp; (add-to-list 'kmacro-ring '("\Cu\Cs \Cm\C-xq\C-?&nbsp;" 0 "%d")) ) (defvar habra-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "Cc mh q") 'habra-wrap-quote) (define-key map (kbd "Cc mhc 1") 'habra-wrap-code) (define-key map (kbd "Cc mhc 2") 'habra-wrap-source) (define-key map (kbd "Cc mhm g") 'habra-make-macro-general) map) "Keymap for `habra-mode'.") (define-minor-mode habra-mode "Mode for `http://www.habrahabr.ru'. \\{habra-mode-map}" nil " Habr" nil (if habra-mode (progn (habra-make-macro-general) (add-to-list 'yas-extra-modes 'habra-mode) (yas-minor-mode t)) (progn (set 'yas-extra-modes (delete 'habra-mode yas-extra-modes))))) (provide 'habra-mode) 



, . Cc + m , — h (habra), , , — m (macro) — g (general). , , , . .

, , . c (code) , 1 2 . , .

It should be noted here that in any small mode the general group of macros should be loaded automatically immediately upon connection. As practice has shown, without this, it was necessary to constantly invoke a combination to access the macros. But the rest of the macros are not automatically loaded, because we remember that the macro ring has a length limitation. Therefore, in the mode for Yutyuba, general macros are loaded when the mode is turned on, and special macros (to translate the video list into a table for org-mode) are always waiting for loading via the keyboard shortcut.

Content Mode for YouTube

Source code
 ;; YouTube mode (defun youtube-make-macro-general() "Make general macros." (interactive) (add-to-list 'kmacro-ring '("https://www.youtube.com\Cj" 0 "%d")) ) (defun youtube-make-macro-playlist() "Make macros for saving playlist." (interactive) ;;     (add-to-list 'kmacro-ring '([?\Mx ?b ?r ?o ?w ?s ?e ?- ?u ?r ?l ?- ?e ?m ?a ?c ?s return ?\Cy return] 0 "%d")) ;;      (add-to-list 'kmacro-ring '("\Cs<tr\Ca\Cs</tbody\Ca\367" 0 "%d")) ;;   (, , ) (add-to-list 'kmacro-ring '([?\Cs ?< ?a ? ?h ?r ?e ?f ?= ?\" ?\Cm ?\Cw ?h ?t ?t ?p ?s ?: ?/ ?/ ?w ?w ?w ?. ?y ?o ?u ?t ?u ?b ?e ?. ?c ?o ?m ?\Cs ?& ?\Cm ?\Cb ?\Cj ?\Cs ?< ?a ? ?c ?l ?a ?s ?s ?= ?\" ?p ?l ?- ?v ?i ?d ?e ?o ?- ?t ?i ?t ?l ?e ?\Cm ?\Cw ?\Cs ?d ?a ?t ?a ?- ?s ?e ?s ?s ?i ?o ?n ?l ?i ?n ?k ?= ?\Cm ?\Cw ?\Cs ?> ?\Cm ?\Cw ?\Ck ?\M-\\ ?\Ce ?\M-\\ ?\Cj ?\Cs ?c ?l ?a ?s ?s ?= ?\" ?t ?i ?m ?e ?s ?t ?a ?m ?p ?\Cm ?\Cw ?\Cs ?l ?a ?b ?e ?l ?\Cm ?\Cw ?\Cs ?> ?\Cm ?\Cw ?\Cs ?< ?\Cb ?\Cj] 0 "%d")) ;;    (add-to-list 'kmacro-ring '("|id|Url|S|Desc|Time|\Cj|-\Cj||||<40>||\Cm\Ca" 0 "%d")) ;;   (, , )    (add-to-list 'kmacro-ring '("|\Cx\Ck\Ci|[[\Ce][link]]|-|\Ck\Ce|\Ck\Ce|\Ce\Cn\Ca" 1 "%d")) ) (defvar youtube-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "Cc mym g") 'youtube-make-macro-general) (define-key map (kbd "Cc mym p") 'youtube-make-macro-playlist) map) "Keymap for `youtube-mode'.") (define-minor-mode youtube-mode "Mode for `https://www.youtube.com'. \\{youtube-mode-map}" nil " YouTube" nil (if youtube-mode (progn (youtube-make-macro-general) (add-to-list 'yas-extra-modes 'youtube-mode) (yas-minor-mode t)) (progn (set 'yas-extra-modes (delete 'youtube-mode yas-extra-modes))))) (provide 'youtube-mode) 



It's time to send troops to the big war



. , . , , , , , -.

Source: https://habr.com/ru/post/281499/


All Articles