<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5860864680741669093</id><updated>2011-08-21T02:24:27.421Z</updated><category term='keyboard'/><category term='snippets'/><category term='xxkb'/><category term='x window'/><category term='emacs'/><category term='gnus'/><category term='xmodmap'/><category term='tips'/><category term='google'/><category term='abbrevs'/><title type='text'>emacs tips #</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/blank.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-9188334793118426262</id><published>2008-02-08T12:28:00.000Z</published><updated>2008-02-08T12:48:32.268Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='x window'/><category scheme='http://www.blogger.com/atom/ns#' term='keyboard'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='xmodmap'/><title type='text'>О переселении душ или о переназначении клавиш</title><content type='html'>&lt;p&gt;Многие пользователи Emacs используют CapsLock в качестве левого Ctrl. Это довольно удобно. Так почему же на клавишу Return не назначить правый Ctrl? Это еще больше добавляет удобства, да и симметричности с левым Ctrl, который на месте клавиши CapsLock.&lt;/p&gt;
&lt;p&gt;Небольшое отступление: некоторые пользователи нажимают комбинации C-a, C-e, C-d, используя левый Ctrl. Делать это не только неудобно, но и довольно неграмотно (скорее даже преступно :)). Если одна клавиша на левой стороне клавиатуры, а другая на правой, то пожалуйста, используйте обе руки (будь-то С-f, M-/ или C-M-s (здесь Ctrl и Alt для правой руки, а 's' для левой)). Стремитесь к эргономичности.&lt;/p&gt;
&lt;p&gt;Вернемся к теме. Возникает вопрос: куда же деть Return? А его вполне можно "повесить" на место правого Ctrl или на место Menu, если таковое имеется (между правым Alt и правым Ctrl). На некоторых ноутбуках фирмы Apple вообще нет правого Ctrl, так что данная замена будет очень кстати.&lt;/p&gt;
&lt;p&gt;В итоге мы имеем Control_L на месте клавиши CapsLock, Control_R на месте клавиши Return и Return на месте Menu (или правого Ctrl).&lt;/p&gt;
&lt;p&gt;Запускаем xev. Нажимаем клавишу "Return" (или "Enter"), вылавливаем keycode:&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt;
state ..., keycode 36 (keysym ..., Return), same_screen ...,
  &lt;/code&gt;
&lt;/pre&gt;
&lt;pre&gt;
  &lt;code&gt;
xmodmap -e "keycode 36 = Control_R"
xmodmap -e "add Control = Control_R"
  &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Получаем Control_R на месте клавиши Return. Для CapsLock и левого Ctrl:&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt;
xmodmap -e "keycode 66 = Control_L"
xmodmap -e "add Control = Control_L"
  &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Теперь назначаем Return на Menu, к примеру.&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt;
xmodmap -e "keycode 117 = Return"
  &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Не забудьте использовать xev для определения keycode.&lt;/p&gt;
&lt;p&gt;Итак, у нас высвободились две клавиши. Правый Ctrl и левый. Некоторые "вешают" цикличное переключение раскладки клавиатуры на левый Ctrl. Думаю, что это слишком "жирно". Более грамотно было бы настроить переключение по Ctrl+1 (english), Ctrl+2 (russian) или Alt+1, Alt+2, или Fn+j, Fn+k, или каким-либо другим комбинациям. Возможно помощь в этом сможет оказать статья &lt;a href="http://emacs-tips.blogspot.com/2008/01/emacs-x-window_28.html"&gt;"Emacs, X Window и единое переключение раскладки клавиатуры"&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Как же использовать высвободившиеся левый и правый Ctrl? Для меня было удобно сделать так. При нажатии правого Ctrl получать С-H в Emacs (Ctrl + Hyper), левого Ctrl -- C-s (где 's' не 's', а Super). После переназначения с помощью xmodmap получаем такую штуку. При нажатии правого Ctrl + 'k' получаем С-H-k, Ctrl + Shift + k -- C-S-H-k, Ctrl + Alt + k -- C-M-H-k. С левым Ctrl по аналогии. То есть открывается простор для назначения новых биндингов, которые вполне легко использовать.&lt;/p&gt;
&lt;p&gt;Теперь к практической части. Пускаем xev, находим keycode для левого и правого Ctrl. Берем, например, какие-нибудь braille_dot_* и назначаем:&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt;
xmodmap -e "keycode 37 = braille_dot_5 NoSymbol Control_L"
xmodmap -e "keycode 109 = braille_dot_6 NoSymbol Control_R NoSymbol NoSymbol NoSymbol NoSymbol Hyper_R"

xmodmap -e "add Mod4 = braille_dot_5"
xmodmap -e "add Mod5 = braille_dot_6"
  &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Для меня это сработало. :)&lt;/p&gt;
&lt;p&gt;Теперь добавляем все, что мы проделали в ~/.xmodmaprc&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt;
keycode 117 = Return

keycode 66 = Control_L
add Control = Control_L
keycode 36 = Control_R
add Control = Control_R

keycode 37 = braille_dot_5 NoSymbol Control_L
keycode 109 = braille_dot_6 NoSymbol Control_R NoSymbol NoSymbol NoSymbol NoSymbol Hyper_R

add Mod4 = braille_dot_5
add Mod5 = braille_dot_6
  &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;И прописываем в ~/.xinitrc&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt;
xmodmap ~/.xmodmaprc
  &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Возможно будут полезны приложения xkeycaps и xbindkeys, как более легкие инструменты для достижения результата.&lt;/p&gt;
&lt;p&gt;Для платформы Windows стоит обратить внимание на приложение xkeymacs.&lt;/p&gt;
&lt;p&gt;Кому-то покажется все это неудобно, особенно нажимать Menu для получения Return. Могу заверить, что через 2 дня от неудобства не останется и следа. Привыкнуть довольно легко. Так что найдите время, чтобы "наточить топор", господа. В качестве переходного этапа можно для начала обойтись лишь переназначением Control_L на CapsLock, Control_R -- Return, Menu -- Return и отключением левого и правого Ctrl.&lt;/p&gt;
&lt;p&gt;Все, теперь остается лишь выучить раскладку клавиатуры Дворака и благодать обязательно снизойдет.&lt;/p&gt;
&lt;p&gt;Данная статья -- лишь одна из идей по оптимизации использования клавиатуры. Хотелось бы в комментариях услышать другие подходы в данной области.&lt;/p&gt;
&lt;p&gt;Материалы к ознакомлению:&lt;/p&gt;
man xev&lt;br&gt;
man xmodmap&lt;br&gt;
/usr/include/X11/keysymdef.h&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-9188334793118426262?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/9188334793118426262/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=9188334793118426262' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/9188334793118426262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/9188334793118426262'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2008/02/blog-post.html' title='О переселении душ или о переназначении клавиш'/><author><name>Bzek</name><uri>http://www.blogger.com/profile/17023413115752588324</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-8192428942087444707</id><published>2008-01-28T14:53:00.000Z</published><updated>2008-01-29T18:58:22.903Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='xxkb'/><category scheme='http://www.blogger.com/atom/ns#' term='x window'/><category scheme='http://www.blogger.com/atom/ns#' term='keyboard'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Emacs, X Window и единое переключение раскладки клавиатуры</title><content type='html'>&lt;h3&gt;Aim&lt;/h3&gt;
&lt;p&gt;Цель: Сделать переключение раскладки X Window и внутренней раскладки Emacs по одним и тем же комбинациям клавиш: Fn+j (английский), Fn+k (русский), Fn+l (итальянский).&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;X Window&lt;/h3&gt;
&lt;p&gt;Добавляем &lt;i&gt;Option "XkbLayout" "us,ru(winkeys),it"&lt;/i&gt; в секцию &lt;i&gt;"Input Device"&lt;/i&gt; в файл &lt;i&gt;xorg.conf&lt;/i&gt;&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;emxkb&lt;/h3&gt;
&lt;p&gt;Смотрим &lt;a href="http://akshaal.livejournal.com/58473.html"&gt;http://akshaal.livejournal.com/58473.html&lt;/a&gt;, модифицируем код, получаем emxkb.c . Компилируем: 
&lt;pre width="100"&gt;
  &lt;code&gt;
    gcc -L/usr/X11R6/lib -lX11 -o emxkb emxkb.c
  &lt;/code&gt;
&lt;/pre&gt;
При исполнении &lt;i&gt;emxkb 0&lt;/i&gt; раскладка переключается на "us", &lt;i&gt;emxkb 1&lt;/i&gt; -- "ru(winkeys)", &lt;i&gt;emxkb 2&lt;/i&gt; -- "it". А если значение WM_CLASS окна равно строке "emacs", то emxkb шлет нажатие клавиш F31, F32 или F33 (в зависимости от параметра) и устанавливает раскладку для X Window на "us".
&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;emxkb.c:&lt;/p&gt;

&lt;pre width="100"&gt;
  &lt;code&gt;
/* Thanks to Evgeny Chukreev (C) 2005, GNU GPL */
/* See http://akshaal.livejournal.com/58473.html */

/* Modified a little by Bzek .) */

/* Compilation: gcc -L/usr/X11R6/lib -lX11 -o emxkb emxkb.c */

/* Usage:
 *      emxkb 0  # For first group
 *      emxkb 1  # For second group 
 *      emxkb 2  # For third group
 */

#include &amp;lt;X11/Xlib.h&amp;gt;
#include &amp;lt;X11/XKBlib.h&amp;gt;
#include &amp;lt;X11/keysym.h&amp;gt;
#include &amp;lt;X11/Xutil.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

/* For locking a group */
int lock_group (int window_id, int group);

/* For sending a key to Emacs */
int send_key_to_emacs (Display *display, int window_id, int group);


/* Main function */
int
main (int argc, char *argv[]) {

    Display *display;
    XClassHint class_hint;
    Window focus;
    int revert, group;

    /* Check arguments */
    if (argc &lt; 2) {
        fprintf (stderr, "Usage: %s &amp;lt;group&amp;gt;\n", argv[0]);
        return -1;
    }

    /* Parse arguments */
    group = strtol (argv[1], NULL, 0);

    /* Open display */
    display = XOpenDisplay (NULL);

    if (!display) {
        fprintf (stderr, "%s: Can't open display\n", argv[0]);
        return -2;
    }

    /* Get window id */
    if (!XGetInputFocus (display, &amp;focus, &amp;revert)) {
        fprintf (stderr, "%s: Can't get focus\n", argv[0]);
        return -3;
    }

    /* Get WM_CLASS */
    XGetClassHint (display, focus, &amp;class_hint);
/*     printf ("WM_CLASS: %s\n", class_hint.res_name); */

    if (class_hint.res_name != NULL
        &amp;&amp; !strncmp (class_hint.res_name, "emacs", strlen("emacs"))) {
        /* Yeah, Emacs! Send a key. */
        if (!send_key_to_emacs (display, focus, group)) {
            fprintf (stderr, "%s: Failed during sending a key to Emacs\n", argv[0]);
            return -4;
        }

        /* Change group to 0 (it should be "us") for Emacs */
        group = 0;
    }

    if (!lock_group (focus, group)) {
        fprintf (stderr, "%s: Failed during locking group\n", argv[0]);
        return -5;
    }

    /* Close display */
    XCloseDisplay (display);

    /* That is all */
    return 0;
}


int
send_key_to_emacs (Display *display, int window_id, int group) {

    XKeyEvent event;

    /* Init event */
    memset (&amp;event, 0, sizeof (event));
    event.window = window_id;
    event.display = display;
    event.root = RootWindow (display, DefaultScreen (display));
    event.state = 0;

    switch (group) {
    case 0:
        event.keycode
            = XKeysymToKeycode (display, XStringToKeysym ("F31"));
        break;
    case 1:
        event.keycode
            = XKeysymToKeycode (display, XStringToKeysym ("F32"));
        break;
    case 2:
        event.keycode
            = XKeysymToKeycode (display, XStringToKeysym ("F33"));
        break;
    default:
        event.keycode
            = XKeysymToKeycode (display, XStringToKeysym ("F31"));
        break;
    }

    /* Send KeyPress event */
    event.type = KeyPress;

    if (!XSendEvent (display, window_id, False, 0, (XEvent *) &amp;event)) {
        fprintf (stderr, "send_key_to_emacs(): Can't send KeyPress event\n");
        return -1;
    }

    /* Send KeyRelease event */
    event.type = KeyRelease;

    if (!XSendEvent (display, window_id, False, 0, (XEvent *) &amp;event)) {
        fprintf (stderr, "send_key_to_emacs(): Can't send KeyRelease event\n");
        return -2;
    }

    XSync (display, False);

    return 1;
}


int
lock_group (int window_id, int group) {

    Display *xkb_display;
    int res;

    /* Open xkb display */
    xkb_display = XkbOpenDisplay (NULL, NULL, NULL, NULL, NULL, NULL);

    if (!xkb_display) {
        fprintf (stderr, "lock_group(): Can't open display\n");
        return -1;
    }

    /* Init XKB */
    res = XkbQueryExtension (xkb_display, NULL, NULL, NULL, NULL, NULL);
    if (!res) {
        fprintf (stderr, "lock_group(): Can't init XKB\n");
        return -2;
    }

    /* Set Focus */
    if (window_id &gt; 0) {
        XSetInputFocus (xkb_display, window_id, RevertToParent, CurrentTime);
        XSync (xkb_display, False);
    }

    /* Lock Group */
    res = XkbLockGroup (xkb_display, XkbUseCoreKbd, abs (group % 4));
    if (!res) {
        fprintf (stderr, "lock_group(): Can't lock group\n");
        return -3;
    }

    XSync (xkb_display, False);
            
    /* Close xkb display */
    XCloseDisplay (xkb_display);

    return 1;
}
  &lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;h3&gt;Window Manager&lt;/h3&gt;
&lt;p&gt;Запускаем xev, жмем Fn+j, Fn+k, Fn+l, получаем что-то типа:
&lt;pre width="100"&gt;
  &lt;code&gt;
    state ..., keycode ... (keysym ..., KP_End), ...
    state ..., keycode ... (keysym ..., KP_Down), ...
    state ..., keycode ... (keysym ..., KP_Next), ...
  &lt;/code&gt;
&lt;/pre&gt;
То есть, для Fn+j (вероятно в вашем случае будет не KP_End) -- это KP_End, Fn+k -- KP_Down, Fn+l -- KP_Next 
Теперь прописываем в window manager, чтобы по KP_End запускалось emxkb 0, по
KP_Down -- emxkb 1 и по KP_Next -- emxkb 2 .
&lt;/p&gt;

&lt;br&gt;&lt;br&gt;
&lt;h3&gt;xmodmap&lt;/h3&gt;
&lt;p&gt;Определеям keycode для F31, F32, F33:
&lt;pre width="100"&gt;
  &lt;code&gt;
xmodmap -e "keycode 241 F31"
xmodmap -e "keycode 242 F32"
xmodmap -e "keycode 243 F33"
  &lt;/code&gt;
&lt;/pre&gt;
На будущее добавляем в файл &lt;i&gt;~/.xmodmaprc&lt;/i&gt; строки:
&lt;pre width="100"&gt;
  &lt;code&gt;
keycode 241 F31
keycode 242 F32
keycode 243 F33
  &lt;/code&gt;
&lt;/pre&gt;
В &lt;i&gt;~/.xinitrc&lt;/i&gt; добавляем:
&lt;pre width="100"&gt;
  &lt;code&gt;
    xmodmap ~/.xmodmaprc
    &lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;h3&gt;Emacs&lt;/h3&gt;
&lt;p&gt;Добавляем в .emacs (или init.el) строки:
&lt;pre width="100"&gt;
  &lt;code&gt;
(defun reset-flyspell-with-new-dict (dict)
  "Set new dictionary and restart flyspell"

  (unless (equal dict ispell-local-dictionary)
    (setq ispell-local-dictionary dict)
    (when flyspell-mode
      (flyspell-mode)
      (flyspell-mode)))

  (when flyspell-mode
    (save-excursion
      (flyspell-region (window-start) (window-end))))

  (message nil))

(global-set-key [(f31)]
                (lambda ()
                  (interactive)
                  ;; (reset-flyspell-with-new-dict "american")
                  (inactivate-input-method)))

(global-set-key [(f32)]
                (lambda ()
                  (interactive)
                  ;; (reset-flyspell-with-new-dict "russian")
                  (set-input-method 'russian-computer)))

(global-set-key [(f33)]
                (lambda ()
                  (interactive)
                  ;; (reset-flyspell-with-new-dict "italian")
                  (set-input-method 'italian-keyboard)))


(defun toggle-specified-isearch-input-method (new-input-method)
  "Toggle specified input method in interactive search."
  (interactive)
  (let ((overriding-terminal-local-map nil)))

  (if (eq new-input-method 'default-method) 
      (inactivate-input-method)
    (set-input-method new-input-method))
    
  (setq isearch-input-method-function input-method-function
        isearch-input-method-local-p t)
  (setq input-method-function nil)
  (isearch-update))


(add-hook 'isearch-mode-hook
          (lambda ()
            (define-key isearch-mode-map (kbd "&amp;lt;f31&amp;gt;") 
              (lambda ()
                (interactive)
                (toggle-specified-isearch-input-method 'default-method)))

            (define-key isearch-mode-map (kbd "&amp;lt;f32&amp;gt;") 
              (lambda () 
                (interactive) 
                (toggle-specified-isearch-input-method 'russian-computer)))

            (define-key isearch-mode-map (kbd "&amp;lt;f33&amp;gt;") 
              (lambda () 
                (interactive) 
                (toggle-specified-isearch-input-method 'italian-keyboard)))))
  &lt;/code&gt;
&lt;/pre&gt;
Для необходимости можно раскомментировать строки с вызовом (reset-flyspell-with-new-dict).
&lt;/p&gt;

&lt;br&gt;&lt;br&gt;
&lt;h3&gt;xxkb&lt;/h3&gt;
&lt;p&gt;Если есть желание использовать xxkb, то вот конфиг, с которым был протестирован весь этот "костыль":
&lt;pre width="100"&gt;
  &lt;code&gt;
XXkb.group.base: 1
XXkb.group.alt: 2

XXkb.mainwindow.type: normal
! possible values - normal, top, tray, wmaker

XXkb*label.text.1: En
XXkb*label.text.2: Ru
XXkb*label.text.3: It

XXkb.mainwindow.label.enable: yes
XXkb.mainwindow.enable: yes
XXkb.mainwindow.appicon: no
XXkb.mainwindow.geometry: 15x15-0+0
XXkb.mainwindow.label.background: yellow
XXkb.mainwindow.label.foreground: blue4
XXkb.mainwindow.label.font: -misc-*-r-*-13-*

XXkb.button.enable: no

XXkb.controls.add_when_start: yes
XXkb.controls.add_when_create: yes
XXkb.controls.add_when_change: no
XXkb.controls.two_state: no
XXkb.controls.button_delete: yes
XXkb.controls.button_delete_and_forget: yes
XXkb.controls.mainwindow_delete: yes
XXkb.ignore.reverse: no

XXkb.app_list.wm_class_class.alt_group1: emacs Emacs
  &lt;/code&gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;Последняя строчка впрочем даже и не нужна.&lt;/p&gt;

&lt;p&gt;Порой (у меня это случалось только с одним приложением и довольно редко) xxkb начинает капризничать и менять обратно раскладку, тогда помогает клик по значку xxkb (чудесатое решение :)).&lt;/p&gt;

&lt;p&gt;В xmonad и некоторых других wm, по свидетельствам очевидцев, xxkb вообще не хочет работать с этим "костылем", не давая переключать раскладку с помощью emxkb. Если для вас это так, тогда стоит посмотреть в сторону другого индикатора раскладки клавитуры (например в сторону xneur).&lt;/p&gt;
&lt;br&gt;&lt;br&gt;
&lt;p&gt;Тестировалось под X.Org 6.7, xxkb (1.10 и 1.11), icewm, fluxbox, ion3, awesome.&lt;/p&gt;

&lt;p&gt;При замечаниях и более элегантных решениях просьба оставить комментарий.&lt;/p&gt;

&lt;p&gt;Спасибо &lt;a href="http://vyazovoi.livejournal.com"&gt;Павлу Вязовому&lt;/a&gt; за помощь.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-8192428942087444707?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/8192428942087444707/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=8192428942087444707' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/8192428942087444707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/8192428942087444707'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2008/01/emacs-x-window_28.html' title='Emacs, X Window и единое переключение раскладки клавиатуры'/><author><name>Bzek</name><uri>http://www.blogger.com/profile/17023413115752588324</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-6078481090575415823</id><published>2007-10-13T14:24:00.000Z</published><updated>2007-10-13T23:10:02.760Z</updated><title type='text'>Несколько прибамбасов для более удобной работы с текстом.</title><content type='html'>&lt;h3&gt;Захват всей строки.&lt;/h3&gt;

&lt;p&gt;
 Этот прибамбас я подсмотрел в Textmate. Заключается он в том, чтобы замаркировать всю строку и переместить курсор в начало следуюшей строки. При этом совершенно неважно, в каком месте строки находился курсор до этого.
&lt;/p&gt;

&lt;pre&gt;
 &lt;code&gt;
(defun my-mark-line ()
  (interactive)
  (beginning-of-line)
  (cua-set-mark)
  (end-of-line)
  (next-line)
  (beginning-of-line))

(global-set-key [(alt k)] 'my-mark-line)
 &lt;/code&gt;
&lt;/pre&gt;

&lt;h3&gt;Дублирование строки одной командой.&lt;/h3&gt;

&lt;p&gt;
 Ну тут, помоему, и объяснять много не надо: обыкновенное дублирование строки по &lt;b&gt;alt-d&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;
 &lt;code&gt;
(defun my-copy-line ()
  (interactive)
  (kill-ring-save (line-beginning-position) (line-end-position))
  (end-of-line)
  (newline)
  (cua-paste nil))

(global-set-key [(alt d)] 'my-copy-line)
 &lt;/code&gt;
&lt;/pre&gt;

&lt;h3&gt;Новая строка.&lt;/h3&gt;

&lt;p&gt;
 Создаём новую строку с отступом.
&lt;/p&gt;

&lt;pre&gt;
 &lt;code&gt;
(defun my-new-line ()
  (interactive)
  (end-of-line)
  (newline-and-indent))

(global-set-key [(alt o)] 'my-new-line)
 &lt;/code&gt;
&lt;/pre&gt;

&lt;h3&gt;Комментарии.&lt;/h3&gt;

&lt;p&gt;
 Удобное комментирование и разкомментирование либо одной строки, либо замакированного блока, используя одну и ту же команду.
&lt;/p&gt;

&lt;pre&gt;
 &lt;code&gt;
(defun my-comment-or-uncomment-region (arg)
  (interactive "*P")
  (comment-normalize-vars)
  (if (and (not mark-active) (save-excursion (beginning-of-line) (not (looking-at "\\s-*$"))))
  (comment-or-uncomment-region (line-beginning-position) (line-end-position))
  (comment-dwim arg)))

(global-set-key (kbd "A-/") 'my-comment-or-uncomment-region)
 &lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
 При этом мне очень важно, чтобы знаки комментариев учитывали актуальный отступ строки. Для этого делаем:
&lt;/p&gt;

&lt;pre&gt;
 &lt;code&gt;
(setq comment-style 'indent)
 &lt;/code&gt;
&lt;/pre&gt;

&lt;h3&gt;Поиск парной скобки.&lt;/h3&gt;

&lt;p&gt;
 Мне дико нравился в своё время поиск парной скобки в Vim по нажатию %. Поэтому решил сделать подобное и в Emacs. Вот что получилось:
&lt;/p&gt;

&lt;pre&gt;
 &lt;code&gt;
(defun my-match-paren (arg)
  (interactive "p")
  (cond ((looking-at "\\s\(")
  (forward-list 1) (backward-char 1))
  ((looking-at "\\s\)")
  (forward-char 1) (backward-list 1))
  (t (self-insert-command (or arg1)))))

(global-set-key (kbd "A-%") 'my-match-paren)
 &lt;/code&gt;
&lt;/pre&gt;

&lt;h3&gt;Ну и напоследок.&lt;/h3&gt;

&lt;p&gt;
 Этот прибамбас облегчает на порядок написание SGML/HTML/XML тегов.
&lt;/p&gt;

&lt;pre&gt;
 &lt;code&gt;
(defun html-surround-region-with-tag (tag-name beg end)
  (interactive "sTag name: \nr")
  (insert "&lt;" tag-name "&gt;")
  (insert "&lt;/" tag-name "&gt;")
  (goto-char (+ end 2 (length tag-name)))
  )

(global-set-key [(control &lt;)] 'html-surround-region-with-tag)
 &lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
Жмём &lt;b&gt;control-&lt;&lt;/b&gt; и даём название тега без знаков '&lt;' и '&gt;'. Всё осталное Emacs сделает сам.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-6078481090575415823?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/6078481090575415823/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=6078481090575415823' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/6078481090575415823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/6078481090575415823'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2007/10/blog-post.html' title='Несколько прибамбасов для более удобной работы с текстом.'/><author><name>cubique</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-3990320912203649130</id><published>2007-07-30T11:35:00.000Z</published><updated>2007-08-12T20:05:41.177Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='snippets'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='abbrevs'/><title type='text'>Сокращения/snippets и лучший редактор этой вселенной</title><content type='html'>&lt;p&gt;Что я подразумеваю под сокращениями (abbrevs)? Возможно, вы уже
 видели это в TextMate для MacOS X или в какой-нибудь интегрированной
 среде разработки. В общем случае выглядит это так: вы набираете в
 редакторе for, а он (редактор) сразу после набора этого слова заменяет
 его на соответствующий ему шаблон, например такой:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
for (_;_;_) {
    _
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Причем курсор появляется в местах, помеченных как "_" (я буду
 называть их "точками перехода"). Между такими местами можно
 переключаться с помощью какой-нибудь клавиши (обычно это
 Tab). Демонстрацию работы такой функции можно
 посмотреть &lt;a href="http://www.bloomington.in.us/%7Ebrutt/msf-abbrev-demo.gif"&gt;здесь&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;По умолчанию в Emacs (по крайней мере в последних версиях) есть так
 называемые skeleton'ы, но с ними не очень удобно работать, поскольку
 точка перехода может быть только одна. В таких условиях после каждого
 банального if'а вам придется орудовать стрелками, чтобы перейти в тело
 цикла. Как по мне, так проще и быстрее код пишется без таких вот
 сокращений. Кроме того, при использовании skeleton'ов текст вставляетя
 без нормального форматирования отступов. Приходится либо делать indent
 вручную, либо дописывать костыли.&lt;/p&gt;

&lt;p&gt;Что касается сторонних скриптов (в которых проблема с единственной
 точкой перехода решена), то их вполне достаточно; самые популярные
 - &lt;a href="http://www.kazmier.com/computer/"&gt;snippet.el&lt;/a&gt;
 и &lt;a href="http://smart-snippet.googlecode.com/"&gt;smart-snippet&lt;/a&gt;. Второй
 является надстройкой над первым. Однако ни тот, ни другой, мне
 настроить так и не удалось. Да, для С/С++ все замечательно (кроме
 форматирования отступов, к которому эти скрипты относятся прямо скажем
 очень своеобразно), но к ruby-mode приделать их так и не
 получилось. Поэтому я расскажу о другом, не столь популярном скрипте
 - &lt;a href="http://www.bloomington.in.us/%7Ebrutt/msf-abbrev.html"&gt;msf-abbrev.el&lt;/a&gt;,
 который гораздо проще в настройке (как мне показалось).&lt;/p&gt;

&lt;p&gt;У меня в домашнем каталоге есть директория, куда я складываю все
 сторонние скрипты для Emacs (у меня это ~/emacs). Если у вас еще нет
 такой, рекомендую ее создать и добавить в ваш ~/.emacs следующую
 строку:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(add-to-list 'load-path "~/emacs")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;После этого чтобы загрузить какой-нибудь сторонний скрипт
 (foobar.el), вам нужно будет поместить его в этот каталог и дописать в
 конфиг что-нибудь вроде (require 'foobar) или (load "foobar"). Я
 рассчитываю на то, что вы
 скачали &lt;a href="http://www.bloomington.in.us/%7Ebrutt/msf-abbrev.el"&gt;msf-abbrev.el&lt;/a&gt;
 и поместили его в свой аналог ~/emacs. На сайте автора
 есть &lt;a href="http://www.bloomington.in.us/%7Ebrutt/mode-abbrevs-1.0beta3.tar.gz"&gt;архив&lt;/a&gt;
 с его сокращениями, но мне они показались не очень удобными. Там же
 есть ссылка
 на &lt;a href="http://www.bloomington.in.us/%7Ebrutt/glibc-abbrevs.tar.gz"&gt;архив&lt;/a&gt;
 сокращений для всех функций glibc.&lt;/p&gt;

&lt;p&gt;Что ж, приступим к настройке собственно скрипта. Открывайте
 ~/.emacs и добавляйте туда такие строки:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
(require 'msf-abbrev)
(setq-default abbrev-mode t)
(setq save-abbrevs nil)
(setq msf-abbrev-root "~/emacs/abb")
(global-set-key (kbd "C-c a") 'msf-abbrev-define-new-abbrev-this-mode)
(add-hook 'ruby-mode-hook 'msf-abbrev-load)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;В первой строке подгружается сам скрипт (если он еще не был
 загружен раньше), после чего все его функции становятся доступными. Во
 второй строке мы говорим, чтобы Emacs по умолчанию включал подрежим
 abbrev (сокращения будут работать в этом режиме). Если деятельность
 скрипта начнет вам мешать, выполните M-x abbrev-mode. В третьей строке
 мы говорим, чтобы Emacs не записывал наши сокращения в ~/.abbrevs. По
 умолчанию эта функция включена, но при использвании msf-abbrevs в ней
 нет необходимости. Далее мы определяем каталог, где будут храниться
 наши сокращения (создайте свой и вставьте вместо "~/emacs/abb").&lt;br&gt;
 После этого мы задаем клавиатурное сочетание "C-c a", которая будет
 создавать для нас новое сокращение для текущего режима. В последней
 строке добавляем новый хук к ruby-mode (я буду показывать все на
 примере Ruby). Вообще можно обойтись и без хука, вставив вместо этого
 строку (msf-abbrev-load), но я люблю, чтобы скрипт загружался только в
 нужных режимах. Если вы пишете на других языках, то вместо
 ruby-mode-hook вставьте хук для своего языка (c-mode-hook,
 java-mode-hook, python-mode-hook).&lt;/p&gt;

&lt;p&gt;Все, больше никакой правки .emacs не потребуется. Теперь будем
 обучать редактор нашим сокращениям. Загружайте по-новой Emacs,
 переходите в нужный режим (тот, для которого будете задавать
 сокращения и для которого настроили загрузку скрипта через хук: M-x
 ruby-mode). Теперь жмите "C-c a". В минибуфере появится сообщение о
 том, что директория ~/emacs/abb/ххх-mode не найдена и тут же вам
 предложат ее создать. Соглашайтесь. Дальше вас спросят об имени
 сокращения. Имя сокращения соответствует его вызову. То есть если вы
 дадите ему имя for, то и вызываться оно будет после набора в редакторе
 слова "for" (разумеется, только в том режиме, для которого оно
 определено). После ввода имени сокращения (пусть для определенности
 это будет тот же for), откроется новый буфер. Вставьте в него что-то
 вроде этого (напомню, что примеры у меня для Ruby):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
for &amp;lt;field "name"&amp;gt; in &amp;lt;field "exp"&amp;gt; do
    &amp;lt;endpoint&amp;gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Теперь сохраняйте буфер, переходите в нужный режим и
 пробуйте. Скрипт должен на лету подхватить свежесозданное сокращение
 и, если вы все сделали правильно, после ввода for появится что-то
 похожее:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
for &lt;i&gt;name&lt;/i&gt; in &lt;i&gt;exp&lt;/i&gt; do

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То, что я выделил наклонным шрифтом, скорее всего будет выделено в
 самом редакторе каким-нибудь цветом (у меня это серый). Это точки
 перехода. В между ними можно перемещаться по клавишам Tab и Shift-Tab
 (вперед и назад, соответственно). После нажатия Tab в последней точке
 перехода, курсор переместится в то место, где мы указали
 endpoint. Думаю, в целом смысл понятен. Теперь давайте заглянем в
 ~/emacs/abb/ruby-mode/ и посмотрим, что же там появилось. А появился
 там обычный текстовый файл с именем for, содержащий наш шаблон.&lt;/p&gt;

&lt;p&gt;Кроме field и endpoint скрипт принимает еще несколько ключевых
 слов: cursor, varlookup, elisp, query, choose и comment. Из них отмечу
 query, который вместо создания точки перехода просто спрашивает вас в
 минибуфере, что вставить в этом месте и choose, с помощью которого
 можно организовать комбо-бокс с несколькими вариантами выбора. Про
 остальные можете почитать
 на &lt;a href="http://www.bloomington.in.us/%7Ebrutt/msf-abbrev.html"&gt;странице
  проекта&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Надеюсь, настроив сокращения, вы станете получать от написания
 исходников (а может и не только их?) в своем любимом редакторе еще
 больше удовольствия. (:&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-3990320912203649130?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://edoc-modnar.blogspot.com/2007/07/snippets.html' title='Сокращения/snippets и лучший редактор этой вселенной'/><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/3990320912203649130/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=3990320912203649130' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/3990320912203649130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/3990320912203649130'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2007/07/snippets_8631.html' title='Сокращения/snippets и лучший редактор этой вселенной'/><author><name>edoc_modnar</name><uri>http://www.blogger.com/profile/12065625859341401766</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-6347045181511945116</id><published>2007-07-20T11:53:00.000Z</published><updated>2007-07-20T11:54:19.884Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='gnus'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Настройка Emacs для отправки почты через Gmail</title><content type='html'>Вчера приступил к настройке давно задуманной вещи, которая так и не завелась у меня в Emacs под Windows - скрещиванию Gnus и Gmail, чтобы можно было читать рассылки в удобном емаксовом интерфейсе. Вчера удалась только одна часть - настроил отправку почты через Gmail, а вот скачивание почты через pop3 так и не заработало - сегодня буду пробовать еще раз, и может быть настрою fetchmail, для автоматического вытягивания почты (что не хочется, ибо он будет вытягивать почту и тогда, когда меня нет у компа и имею доступ только через web интерфейс).
Настройка отправки почты через Gmail описана в нескольких блогах, но они все имели одну и ту же ошибку - не указывали один пакет (&lt;span style="font-weight: bold;"&gt;starttls&lt;/span&gt;), что не позволило сразу отправку.
В общем, для отправки почты нужно сделать следующее:
&lt;ol&gt;&lt;li&gt;поставить gnutls для того, чтобы &lt;span style="font-weight: bold;"&gt;smtpmail&lt;/span&gt; мог выполнить команду &lt;span style="font-style: italic;"&gt;STARTTLS&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;В .gnus написать следующее:
&lt;/p&gt;&lt;pre&gt;(setq user-mail-address "my-email@gmail.com")
(setq send-mail-function 'smtpmail-send-it
message-send-mail-function 'smtpmail-send-it
smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
smtpmail-auth-credentials '(("smtp.gmail.com" 587 "my-email@gmail.com" nil))
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
smtpmail-debug-info t)
(require 'starttls)
(require 'smtpmail)&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;протестировать отправку, при отправке письма, &lt;span style="font-weight: bold;"&gt;smtpmail&lt;/span&gt; спросит пароль, и отправит письмо. Поскольку в данном конфиге включена отладка, то вся SMTP сессия будет выводиться в буфер с именем &lt;code&gt;*trace of SMTP ...*&lt;/code&gt;
&lt;/li&gt;&lt;/ol&gt;Что означает каждая строка в приведенном конфиге?:
&lt;ul&gt;&lt;li&gt;первая строка задает адрес пользователя;
&lt;/li&gt;&lt;li&gt;вторая и третья строка заставляют отправлять почту через SMTP, а не через локальный почтовый сервер;&lt;/li&gt;&lt;li&gt;четвертая и пятая строки задают для какого сервера надо использовать STARTTLS, и какие данные пользователя будут указанны для данного сервера. Если не боитесь, то можете указать пароль сразу в данном конфиге, или сохранить его в файле ~/.authinfo и тогда для &lt;code&gt;smtpmail-auth-credentials&lt;/code&gt; можно записать &lt;code&gt;(expand-file-name "~/.authinfo")&lt;/code&gt; вместо того, что там сейчас написано;
&lt;/li&gt;&lt;li&gt;6,7 и 8 строки задают имя и порт сервера, через который будет производиться отправка писем;&lt;/li&gt;&lt;li&gt;9-я строка включает отладку, что приводит к выводу SMTP сессии в; отдельный буфер. Если все будет работать нормально, то позже можно эту строку удалить&lt;/li&gt;&lt;li&gt;10-я и 11-я строки загружают нужные пакеты.&lt;/li&gt;&lt;/ul&gt;Вот и все :-)
Оригинал статьи - &lt;a href="http://alexott-ru.blogspot.com/2007/07/emacs-gmail.html"&gt;тут&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-6347045181511945116?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/6347045181511945116/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=6347045181511945116' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/6347045181511945116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/6347045181511945116'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2007/07/emacs-gmail.html' title='Настройка Emacs для отправки почты через Gmail'/><author><name>Alex Ott</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_gSOdG3mSC3I/SVnwBuQg7_I/AAAAAAAAEdo/K3SNWhTN_Ic/S220/avatar2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-8522328956087880722</id><published>2007-06-06T07:42:00.000Z</published><updated>2007-06-12T08:42:59.175Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='keyboard'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Tip #3. Emacs'овые биндинги в программах под MS Windows</title><content type='html'>Давно уже обнаружил и даже немного попользовал замечательную программу &lt;a href="http://www.cam.hi-ho.ne.jp/oishi/indexen.html"&gt;XKeymacs&lt;/a&gt;, которая реализует поддержку сочетаний клавиш a-la Emacs для многих программ Windows.  Я до этого уже делал такое в виде переназначений многих клавиш в MS Word, в котором приходилось много писать одно время, но не было поддержки сочетаний из нескольких клавиш, например, C-x h, к которым руки уже привыкли.
Программа позволяет выбирать какие сочетания клавиш будут доступны программе, ну и конечно можно выбрать для каких программ поддержка будет предоставляться.
Тем кто уже совсем подсел на Emacs, очень советую эту программу. По себе знаю - очень часто пальцы срабатывают раньше чем ты осознаешь что ты работаешь не в Emacs ;-)
Кросспост из моего &lt;a href="http://alexott-ru.blogspot.com/"&gt;журнала&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-8522328956087880722?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/8522328956087880722/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=8522328956087880722' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/8522328956087880722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/8522328956087880722'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2007/06/emacs-ms-windows-xkeymacs-la-emacs.html' title='Tip #3. Emacs&apos;овые биндинги в программах под MS Windows'/><author><name>Alex Ott</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_gSOdG3mSC3I/SVnwBuQg7_I/AAAAAAAAEdo/K3SNWhTN_Ic/S220/avatar2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-2758700540865329011</id><published>2007-05-23T10:42:00.000Z</published><updated>2007-06-12T08:44:01.028Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><title type='text'>Tip #2. Быстрое переключение между буферами</title><content type='html'>Обычно в Emacs'e переключение между буферами производится с помощью сочетания клавиш &lt;span style="font-weight: bold;"&gt;C-x b&lt;/span&gt;, или путем выбора нужного буфера в меню.  Однако, при работе с большим количеством файлов, эти методы не совсем удобны.  Поэтому, были разработаны пакеты для более удобного переключения между буферами в Emacs'e.
Один из таких пакетов - &lt;a style="font-weight: bold;" href="http://www.emacswiki.org/cgi-bin/wiki/IswitchBuffers"&gt;iswitchb&lt;/a&gt;, который показывает список буферов, которые соответствуют тому тексту, который вы набираете.  Список буферов меняется по мере набора слова или его части, к тому же вы можете набирать любую часть слова, что особенно полезно, если вы имеете много файлов начинающихся с одного префикса.  В остальном, iswitchb полностью заменяет стандартные механизмы Emacs.
Данный пакет идет в поставке Emacs 22 (текущий CVS), а для предыдуших версий, его можно скачать с emacs-wiki.  Настройка пакета тоже проста - надо лишь поместить следующие строки в файл инициализации:
&lt;pre&gt;
(require 'iswitchb)
(iswitchb-mode 1)
&lt;/pre&gt;
Для того, чтобы не отображались некоторые буфера, их имена можно поместить в список игнорирования, который хранится в переменной &lt;span style="font-weight: bold;"&gt;iswitchb-buffer-ignore&lt;/span&gt;. Вот, например, минимальный список таких буферов:
&lt;pre&gt;
(add-to-list 'iswitchb-buffer-ignore "*Messages*")
(add-to-list 'iswitchb-buffer-ignore "*Backtrace")
(add-to-list 'iswitchb-buffer-ignore "*Quail Com")
(add-to-list 'iswitchb-buffer-ignore "*Buffer")
(add-to-list 'iswitchb-buffer-ignore "*fsm-debug")
(add-to-list 'iswitchb-buffer-ignore "*Completions")
(add-to-list 'iswitchb-buffer-ignore "^[tT][aA][gG][sS]$")
&lt;/pre&gt;
Для того, чтобы обеспечить кэширование информации, можно использовать пакет &lt;a style="font-weight: bold;" href="http://www.emacswiki.org/cgi-bin/wiki/FileNameCache"&gt;filecache&lt;/a&gt;, который умеет интегрироваться с iswitchb.  Этот пакет также идет в составе Emacs 22.  Для его использования поместите в .emacs следующие строки:
&lt;pre&gt;
(require 'filecache)
(load "iswitchb-fc")
&lt;/pre&gt;
Про другие пакеты, обеспечивающие подобную функциональность, вы можете почитать на &lt;a href="http://www.emacswiki.org/"&gt;Emacs WiKi&lt;/a&gt; - в разделе про &lt;a href="http://www.emacswiki.org/cgi-bin/wiki/IswitchBuffers"&gt;iswitchb&lt;/a&gt;, есть ссылки на них&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-2758700540865329011?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/2758700540865329011/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=2758700540865329011' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/2758700540865329011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/2758700540865329011'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2007/05/emacse-c-x-b.html' title='Tip #2. Быстрое переключение между буферами'/><author><name>Alex Ott</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_gSOdG3mSC3I/SVnwBuQg7_I/AAAAAAAAEdo/K3SNWhTN_Ic/S220/avatar2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-6813270486251670144</id><published>2007-05-18T12:15:00.000Z</published><updated>2007-05-19T15:35:29.376Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><title type='text'></title><content type='html'>&lt;h1&gt;Tip #1&lt;/h1&gt;

&lt;h3&gt;Преамбула&lt;/h3&gt;

&lt;p&gt;
Иногда, находясъ в какой-нибудь функции, требуется быстро
перейти на предыдущую или последующую объявленную
функцию в коде. Использовать для этого способ, описанный в
&lt;b&gt;Tip #0&lt;/b&gt;, мне показалось, немного накладно: для этого
нужно вызвать команду &lt;b&gt;my-show-functions-list&lt;/b&gt;, перейти в
буфер *Occur* и выбрать нужную функцию. Гораздо удобнее
было бы "скакать" по объявлениям функций, используя
определённые клавишные комбинации, оставаясь при этом в
текущем буфере.
&lt;/p&gt;

&lt;h3&gt;Задача&lt;/h3&gt;

&lt;p&gt;
Удобное и быстрое перемещение между функциями в текущем
буфере, без использования буфера &lt;b&gt;*Occur*&lt;/b&gt;.
&lt;/p&gt;

&lt;h3&gt;Решение&lt;/h3&gt;

&lt;p&gt;
Для решения задачи нам потребуются стандартные
команды Emacs &lt;b&gt;search-forward-regexp&lt;/b&gt; и
&lt;b&gt;search-backward-regexp&lt;/b&gt;. Как можно догадаться из
названий, эти две команды позволяют осуществлять
поиск по регулярному выражению в текущем буфере. В
качестве аргумента для поиска, мы будем использовать
регулярное выражение из &lt;b&gt;Tip #0&lt;/b&gt;.
Нам также потребуется создать две новые функции с
названием &lt;b&gt;my-jump-to-function-forward&lt;/b&gt; и
&lt;b&gt;my-jump-to-function-backward&lt;/b&gt;.
&lt;/p&gt;

&lt;h3&gt;Функции my-jump-to-function-forward и my-jump-to-function-backward&lt;/h3&gt;

&lt;p&gt;
Взяв за основу функцию &lt;b&gt;my-show-functions-list&lt;/b&gt; из &lt;b&gt;Tip #0&lt;/b&gt;,
получаем следуюший Emacs lisp код: 
&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre width="100"&gt;
&lt;code&gt;
(defun my-jump-to-function-forward()
  (interactive)
  (search-forward-regexp
   "^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)"
   ))

(defun my-jump-to-function-backward()
  (interactive)
  (search-backward-regexp
   "^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)"
   ))
&lt;/code&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Теперь осталось назначить клавишные комбинации. Для себя я выбрал &lt;b&gt;^N&lt;/b&gt; и &lt;b&gt;^P&lt;/b&gt;.
&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre width="100"&gt;
&lt;code&gt;
(global-set-key [(control n)] 'my-jump-to-function-forward)
(global-set-key [(control p)] 'my-jump-to-function-backward)
&lt;/code&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Всё. Можно наслаждаться быстрыми "прыжками" между
функциями, оставаясь при этом в текущем буфере.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-6813270486251670144?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/6813270486251670144/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=6813270486251670144' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/6813270486251670144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/6813270486251670144'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2007/05/blog-post_18.html' title=''/><author><name>cubique</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5860864680741669093.post-920452212454983324</id><published>2007-05-17T19:52:00.000Z</published><updated>2007-05-19T15:35:44.137Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><title type='text'></title><content type='html'>&lt;h1&gt;Tip #0&lt;/h1&gt;

&lt;h3&gt;Задача&lt;/h3&gt;
&lt;p&gt;Удобное и быстрое перемещение между функциями в текущем буфере.&lt;/p&gt;

&lt;h3&gt;Решение&lt;/h3&gt;
&lt;p&gt;
В Emacs есть дико полезная команда list-matching-lines. Эта команда принимает, в качестве аргумента, регулярное выражение и возвращает обратно найденые совпадения, в виде списка в отдельный буфер *Occur*. Вот её-то мы и будем использовать для решения задачи.
&lt;/p&gt;

&lt;h3&gt;Подбираем регулярное выражение&lt;/h3&gt;
&lt;p&gt;
Так как я в основом работаю с PHP и Python, то регулярное выражение будет составлено с учётом только этих двух языков.
&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre color="blue" width="100"&gt;
&lt;code&gt;
^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)
&lt;code&gt;
&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Конечно, вся эта бодяга выглядет немного коряво, можно сделать гораздо изящнее. Но это было первое, что пришло мне в голову и оно работает:)
&lt;/p&gt;

&lt;h3&gt;Функция my-show-functions-list&lt;/h3&gt;
&lt;p&gt;
Создав и проверив регулярное выражение, можно заняться созданием специальной функции с последующим размещением её в .emacs (конфигурационный файл редактора). Функцию я обозвал my-show-functions-list. Если вы создаёте новую функцию для Еmacs, советую придумать какой-нибудь префикс (у меня это "my-") и всегда использовать его в начале имени вашей новой функции. Это позволит в дальнейшем удобно отделять ваши собственные команды от стандартных команд Еmacs.
&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre width="100"&gt;
&lt;code&gt;
(defun my-show-functions-list()
  (interactive)
  (list-matching-lines "^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)"))
&lt;/code&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Теперь осталось прописать комбинацию клавиш для быстрого вызова нашей новой команды. Я это дело повесил на ^F11 (Control + F11).
&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre width="100"&gt;
&lt;code&gt;
(global-set-key [C-f11] 'my-show-functions-list)
&lt;code&gt;
&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Вот собственно и всё. Теперь нужно перегрузить Emacs и открыть какой-нибудь *.php или *.py файл с некоторым кол-вом функций для проверки того, что у нас получилось. При нажатии ^F11 будет открыто новое окно с буфером *Occur*, в котором приведён список всех объявленных в файле функций. Перейдя в буффер *Occur* и выбрав из списка, посредством клавиши Return нужную функцию, вы, тем самым, переместите курсор на строку с объявлением той самой функции в вашем файле.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5860864680741669093-920452212454983324?l=emacs-tips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emacs-tips.blogspot.com/feeds/920452212454983324/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5860864680741669093&amp;postID=920452212454983324' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/920452212454983324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5860864680741669093/posts/default/920452212454983324'/><link rel='alternate' type='text/html' href='http://emacs-tips.blogspot.com/2007/05/emacs-tip-nr-1.html' title=''/><author><name>cubique</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
