Debian, Dojo, Django, Python

Делюсь опытом в описанных технологиях. Блог в первую очередь выполняет роль памяток для меня самого.

Не-IT: польза записной книжки

Сегодня на Хабре наткнулся на статью Записывай всё. Признаюсь, читал не очень внимательно, тем более что в книге Фила Портера "Съесть или быть съеденным" рассматривается не только этот вопрос корпоративной политики, но и многие другие, причём более обстоятельно. Однако, данный пост сподвиг меня написать комментарий. Дабы его увидело больше людей, я решил перенести сюда свои мысли по поводу пользы записных книжек.

Записывайте всё, что вам говорят

Что бы ни говорил Большой Босс, лучше записать его слова дословно и как можно подробнее. Во-первых, он будет видеть, что вам не всё равно, что он говорит. Это значит, что он будет требовать с вас именно то, что вы записали. Во-вторых, даже если у вас хорошая память, плохая может быть у него, а запись - она и есть запись. Её можно потом зачитать. Другими словами, чем подробнее вы ведёте записи, тем лучше для вас - вы ничего не забудете и будете понимать задачу почти так же, как её понимает ваш босс.

Запись - вещественное доказательство

Есть такой тип руководителей, названия которому я не знаю, но могу дать им характеристику. Эти люди ставят задачу, а через некоторое время требуют с вас не то или не совсем то, что говорили. Допустим, Большой Босс хочет купить партию компьютеров на базе процессоров "Эльбрус", чтобы потом их продавать в комплекте с софтом вашей фирмы. Вы едете к поставщику и договариваетесь о поставке нужного количества комплектов. Их привозят, и тут Большой Босс спрашивает:

- Ты что, идиот?

Вы не понимаете, в чём дело.

- Я же сказал, взять самые мощные компьютеры! Надо было брать на базе Xeon'ов!

Тут вы достаете свою записную книжку, открываете нужную страницу и говорите:

- Нет, вы сказали "Эльбрус". Я записал.

Записная книжка выручит вас в подобных ситуациях

Записывайте, кто помимо вас слышал постановку задачи

Большой босс может сказать, что он такого не говорил либо сказал по-другому. Если у вас есть список свидетелей, вы можете обратиться к ним.

Используйте ручки разных цветов

Скорее всего, в большой фирме у вас будет больше одного руководителя, например, руководитель отдела и руководитель проекта. Используйте ручки разных цветов, чтобы не путать, кто из них что говорит. Ну или записывайте фамилию.

Уведомляйте коллег, что их слова тоже записываются

Не надо вести записи из-под полы. Ведите их открыто, т.е. пусть ваши жертвы коллеги и начальство знают, что вы, как компьютер, ведёте полный лог всех разговоров. Они будут строже формулировать задачи и не будут болтать лишнего. С другой стороны, выкладывать свои заметки в общий доступ тоже не стоит - начальство не любит, когда на него собирают компромат (а компроматом можно считать что угодно, доказывающее, что ошиблись не вы, а руководитель).

Отмечайте выполненные задачи

Я ставлю рядом с каждой задачей кружок, а иногда так же и дату, если задача срочная, т.е. должна быть выполнена к определенному сроку. Если задача выполнена успешно, я ставлю галочку и дату выполнения. Если отменена - зачеркиваю одной чертой, как на знаке "Остановка запрещена". Проваленная задача отмечается крестом.

Хоткеи в EMACS

Запись была обновлена 11.09.2016 г. Исправлены ошибки в разметке, из-за которых не выводились на экран некоторые элементы кода.

Основы

Я долгое время пользовался пакетом ergoemacs и был доволен, однако, со временем он стал обрастать функциями, которые мне стали не нужны, а иногда откровенно глючили на моём самосборном EMACS'е. Пришлось изучить, как настраиваются хоткеи в редакторе.

Во-первых, вместо привычных Ctrl, Alt и Shift в EMACS для обозначения модификаторов используются другие значения:

C Ctrl
M Alt
S Shift

Ни в одном руководстве по EMACS вы не найдете записи типа Ctrl+S - там будет написано C-S, хотя по сути эти две записи идентичны.

Во-вторых, клавиши, которые нажимаются вместе, записываются через дефис.

Третье, регистр имеет значение.

Последнее, что нужно знать о клавиатурных комбинациях EMACS - некоторые команды состоят из последовательного нажатия разных клавиатурных комбинаций, например, выход из редактора выглядит так: C-x C-c, что означает следующее:

  • Сначала нажимаем Ctrl+X
  • Теперь нажимаем Ctrl+C

Так же команда выхода из редактора требует подтверждения, если имеются модифицированные буферы, но об этом я напишу в другой раз.

К делу!

Перед тем, как использовать какую-либо клавиатурную комбинацию, следует убедиться, что она уже не привязана к какому-либо действию, либо освободить её от этой привязки. Ниже показано, как удалить привязку команды к комбинации и тут же связать её с новой командой:

(global-unset-key (kbd "C-S-c C-S-c"))
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
Обратите внимание, что привязывать к комбинациям следует только те команды, про которые "знает" EMACS, иначе при запуске он будет выдавать ошибки в конфигурации.

С простыми клавишами разобрались, добавим функциональные:

(require 'neotree)
(require 'ibuffer)
(require 'magit)
(require 'dired)

(global-set-key [f2] 'ibuffer)
(global-set-key [f3] 'dired)
(global-set-key [f8] 'neotree-toggle)
(global-set-key [f10] 'magit-status)

Теперь посмотрим, как описываются стрелки:

;; Resize windows
(global-set-key (kbd "S-C-<left>") 'shrink-window-horizontally)
(global-set-key (kbd "S-C-<right>") 'enlarge-window-horizontally)
(global-set-key (kbd "S-C-<down>") 'shrink-window)
(global-set-key (kbd "S-C-<up>") 'enlarge-window)

Можно ли сделать с полученными знаниями что-то полезное? Да! Давайте удалим ergoemacs и начнем вместо него использовать свои собственные комбинации!

;;; Package --- Summary
;;; Commentary:
;;; Keybindings for non-latin layout

;;; Code:

(setq initial-major-mode (quote text-mode))

(defun cfg:reverse-input-method (input-method)
  "Build the reverse mapping of single letters from INPUT-METHOD."
  (interactive
   (list (read-input-method-name "Use input method (default current): ")))
  (if (and input-method (symbolp input-method))
      (setq input-method (symbol-name input-method)))
  (let ((current current-input-method)
        (modifiers '(nil (control) (meta) (control meta))))
    (when input-method
      (activate-input-method input-method))
    (when (and current-input-method quail-keyboard-layout)
      (dolist (map (cdr (quail-map)))
        (let* ((to (car map))
               (from (quail-get-translation
                      (cadr map) (char-to-string to) 1)))
          (when (and (characterp from) (characterp to))
            (dolist (mod modifiers)
              (define-key local-function-key-map
                (vector (append mod (list from)))
                (vector (append mod (list to)))))))))
    (when input-method
      (activate-input-method current))))

(cfg:reverse-input-method 'russian-computer)

(require 'neotree)
(require 'ibuffer)
(require 'magit)
(require 'dired)

(global-set-key [f2] 'ibuffer)
(global-set-key [f3] 'dired)
(global-set-key [f8] 'neotree-toggle)
(global-set-key [f10] 'magit-status)

;; Multiple cursors
(global-unset-key (kbd "C-S-c C-S-c"))
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)

;; Resize windows
(global-set-key (kbd "S-C-<left>") 'shrink-window-horizontally)
(global-set-key (kbd "S-C-<right>") 'enlarge-window-horizontally)
(global-set-key (kbd "S-C-<down>") 'shrink-window)
(global-set-key (kbd "S-C-<up>") 'enlarge-window)

(defun xah-new-empty-buffer ()
  "Open a new empty buffer.
URL `http://ergoemacs.org/emacs/emacs_new_empty_buffer.html'
Version 2015-06-12"
  (interactive)
  (let ((ξbuf (generate-new-buffer "untitled")))
    (switch-to-buffer ξbuf)
    (funcall (and initial-major-mode))
    (setq buffer-offer-save t)))

;; Save/close/open
(global-set-key (kbd "C-w") 'kill-this-buffer)
(global-set-key (kbd "C-s") 'save-buffer)
(global-set-key (kbd "C-S-s") 'write-file)
(global-set-key (kbd "C-r") 'revert-buffer)
(global-set-key (kbd "C-a") 'mark-whole-buffer)
(global-set-key (kbd "M-'") 'comment-or-uncomment-region)
(global-set-key (kbd "C-o") 'dired)
(global-set-key (kbd "C-n") 'xah-new-empty-buffer)
(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)

;; Buffers and windows
(global-set-key (kbd "C-<next>") 'next-buffer)
(global-set-key (kbd "C-<prior>") 'previous-buffer)
(global-set-key (kbd "C-<tab>") 'other-window)

(global-set-key (kbd "M-3") 'delete-other-windows)
(global-set-key (kbd "M-4") 'split-window-horizontally)
(global-set-key (kbd "M-5") 'split-window-vertically)
(global-set-key (kbd "M-6") 'balance-windows)

(global-set-key (kbd "C-f") 'isearch-forward)
(global-set-key (kbd "C-h") 'query-replace)
(global-set-key (kbd "C-S-h") 'query-replace-regexp)

(global-set-key (kbd "M-a") 'execute-extended-command)
(global-set-key (kbd "M-x") 'kill-whole-line)
(global-set-key (kbd "<esc>") 'keyboard-quit)

(setq x-select-enable-clipboard t)

;; Highlight search resaults
(setq search-highlight        t)
(setq query-replace-highlight t)

;;; keyboard.el ends here

У меня конфигурация разбита на несколько маленьких файлов, и я привёл целиком содержимое keyboard.el. Полагаю, не проблема выбросить ненужное и оставить нужное. Большая часть команд будет работать без установки дополнительных пакетов.

Об этом блоге

Меня зовут Дунаевский Максим, и я программист-самоучка. Чем я пользуюсь:

  • EMACS
  • Django
  • Django Rest Framework
  • bower
  • Dojo
  • Debian Linux
  • Windows 10

Угораю по литературному программированию, книге "Шаблоны проектирования", по статическим анализаторам, autopep8 и isort, а так же интересным задачам. В этот блог пишу только когда есть время.

Как сказано в примечании к моему блогу, он выполняет в первую очередь роль дневника, и только во вторую - пособие для начинающих. С одной стороны, неспособность профессионала снизойти до уровня новичка и объяснить ему всё доступно есть снобизм, а с другой мне лень описывать вещи, которые можно найти в первой десятке выдачи Google. Кроме того, в связи со сменой работы, места жительства и рода деятельности программирование и администрирование с декабря 2015 года перешли на второй план, статьи будут выходить очень редко, если вообще будут. У меня всё, извините, если кого-то задел.

Несколько слов о Dojo Framework

Немного о Dojo Framework

Введение

Dojo Dramework - проект, ведущий свою историю с 2004 года. Причиной, побудившей авторов создать его, стала политика фирмы, где они тогда работали: Sencha хотела денег, и в общем-то, цели своей достигла, на их странице можно полюбоваться совершенно нескромными ценами на ExtJS, они же хотели сделать библиотеку бесплатной

Так и не решив проблему мирным путём, группа энтузиастов откололась, чтобы создать свой собственный фреймворк, что им очень даже удалось.

Обзор возможностей

"Из коробки" Dojo содержит практически весь тот функционал, что мы можем найти в jQuery. Правда, вместо $() там используется dojo.query(), но суть не в этом - это лишь малая часть того, что Dojo на самом деле умеет.

Асинхронная подгрузка модулей

Последние 2 года я читаю о том, что в Angular 2 будет реализована асинхронная подгрузка модулей. В Dojo эта фича была реализована в 2009, но не позиционировалась как "серебрянная пуля", в отличие от. Скажу даже больше, это самый что ни на есть базовый функционал. Всё приложение не просто можно, а даже нужно разбивать на маленькие модули. Люди, знакомые с require.js, оценят написанный ниже код:

require([
      "dojo",
      "dojo/domReady!"
], function(
    dojo
){
    dojo.query("div.centered").style({
      color: "orange",
      textWeight: "bold"
    });
});

Классическое наследование

Стоян Стефанов в своей книге "JavaScript. Шаблоны" выразил мысль о том, что для подготовленного программиста наследование через прототип, используемое в JS, является более мощным, чем классическое (через классы). Не могу с ним согласиться, поскольку сама концепция является довольно спорной.

Существует множество способов обойти прототипное наследование JavaScript, и один из них предлагает Dojo. И не просто предлагает, а так же реализует концепцию множественного наследования, когда результирующий класс получает все свойства и методы своих родителей. Для объявления класса в Dojo имеется метод declare(). С его помощью можно очень легко создать новый "класс" (не в том смысле, в каком мы понимаем его говоря о языках с чистым классическим наследованием, например, C++ или Python, а лишь его эмуляцию).

Именно данный метод Dojo предлагает использовать для создания виджетов, о чём сказано ниже.

Dijit и Dojox

Dijit

Dijit представляет собой готовую библиотеку виджетов, входящую в официальную поставку Dojo. В комплекте идёт несколько тем и базовые контролы, необходимые для создания Rich Interface Applications - кнопки, меню, диалоговые окна (опять эмуляция, ясное дело), поля выбора, деревья, списки, панели... Лучше посмотрите сами вот здесь.

Можно создавать свои собственные компоненты (виджеты) на основе имеющихся. Есть даже базовые классы - _BaseWidget, _TemplatedMixin и другие. Да, здесь нет директив из мира Angular, и контроллеров тоже. И сервисов нет, о, Боже, я в аду! Если нам нужно использовать какой-то виджет, мы пишем в свойстве элемента DOM, например, data-dojo-type="dijit/form/Button", и получаем кнопку. Соответственно, нет здесь и проблем с приоритетом директив, и возни с transclude, контролллерами и прочими столь милыми сердцу фанатов Angular надстройками над языком, которые ко второй версии весело отомрут, будучи заменены Web-компонентами.

Dojox

Как я понял, это набор не входящих в официальную поставку виджетов. Авторы могут поддерживать, а могут и не поддерживать их. Исправление ошибок? Новые фичи? Какой-то Road Map? Всё на совести автора, никто ничего не обещает. Однако, библиотека и набор возможностей впечатляют.

Причины непопулярноcти Dojo

Причин множество, я остановлюсь на тех, которые кажутся мне наиболее явными и значительными. Отсортированы в порядке всплытия в памяти.

Скудная документация

Документация к Dojo не просто бедная, а очень бедная. Некоторые статьи были написаны ещё в нулевых, и с тех пор ни разу серьёзно не перерабатывались. Литература? Самое свежее, что я видел - книга 2009 года. От жизни отстала очень сильно.

Высокий порог вхождения

Angular не может похвастать доброжелательностью к новичкам, однако, даже там, сев вечером с кружкой чая ближе к ночи уже можно сделать что-то более-менее работающее. В случае с Dojo ситуация совершенно иная. Фреймворк требует долгого, настойчивого изучения. Используемые в нём подходы серьёзно отличаются от тех, к которым привыкли пользователи Angular и jQuery.

Слабый пиар

В отличие от Google, пихающего свой Angular буквально везде, IBM - один из основных спонсоров проекта - практически никак его не продвигает. Попробуйте сами найти на YouTube какой-нибудь dojoConf или вебинар по новым возможностям. Может быть, у вас получится найти how-to или разбор сложного примера? Дайте мне ссылку! В основном всё, что я находил, описывается следующим образом: "Вот смотрите, числа обладают свойствами коммутативности. 2+2=4. Зная это, не трудно доказать теорему Ферма". Другими словами, пропущен средний уровень, порой даже складывается впечатление, что спецов, которые могут написать высококачественную статью про Dojo и имеют на это время, свободное от загребания бабла, попросту не существует.

Итоги

Так стоит ли тратить время на этот фреймворк?

Сейчас я не готов ответить на этот вопрос однозначно. Свой новый проект я начал писать на нём, и пока дело не сильно продвинулось. Однако, как мне кажется, Dojo именно тот проект, на который стоит равняться. Многие идеи, которые первыми появились именно в нём, впоследствии были заимствованы другими фреймворками. Исходный код и сама структура проекта (а так же виджетов Dijit) являются хорошим образцом продуманного, профессионального подхода. Стиль, модульность, комментарии - всё это выполнено блестяще.

CSRF-токены и CBV, требующие авторизации

Всё, что нужно знать о CSRF-токенах в Django

Всё Middleware оставлены по-умолчанию, т.е. в settings.py никаких изменений не вносилось.

Ниже идёт код, который позволяет прописать в шаблон Cookies с CSRF-токеном:

from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.generic import View


class Index(View):

    def get(self, request):
        context = {}
        context.update(csrf(request))
        return render_to_response(
            'index.html',
            RequestContext(request, context)
        )

В сам шаблон нужно не забыть включить одну важную строку:

{% csrf_token %}

Без этой строки печенька покрошена на страницу НЕ БУДЕТ. Не знаю, почему, просто вот такой интересный факт.

Миксин для CBV (Class Based Views), которым нужна авторизация:

from os import path

from django.contrib.auth.decorators import login_required
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.template.context import RequestContext
from django.views.generic import View


class LoginRequiredMixin(object):
    """Собственно примесь """

    @classmethod
    def as_view(cls, **initkwargs):
        view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
        return login_required(view, login_url='/login/')


class ProfileView(LoginRequiredMixin, View):

    def get(self, request, *args, **kwargs):
        c = {}
        c.update(csrf(request))

        user = request.user

        template_path = path.join(
            'admin',
            'index.html',
        )

        return render_to_response(
            template_path,
            RequestContext(request, c)
        )

EMACS для Python

Введение

Решил наконец написать статью о том, как настроить EMACS для удобной работы с Python'ом. Ниже список рассматриваемых вопросов:

  • Разбиение конфигурации на части
  • Пакеты
  • Ergoemacs
  • Anaconda-mode

Разбиение конфигурации на части

Долгое время мой .emacs представлял собой всего один файл. Естественно, править его было не очень удобно. С течением времени он рос и становился толще, наконец, в определённый момент поддерживать его стало совершенно невозможно. К счастью, я подсмотрел на StackOverflow, как можно разбить его на несколько маленьких частей.

Для подгрузки параметров из других файлов нужно в .emacs написать следующее:

;;; package --- Summary
;;; Commentary:
;;; Main EMACS settings file, load settings from parts.

;;; Code:

(load "~/.emacs.d/fonts.el")
(load "~/.emacs.d/packages.el")
(load "~/.emacs.d/ergoemacs.el")
(load "~/.emacs.d/personal.el");
(load "~/.emacs.d/keyboard.el")
(load "~/.emacs.d/variables.el")
(load "~/.emacs.d/flycheck.el")
(load "~/.emacs.d/rust.el")
(load "~/.emacs.d/python.el")
(load "~/.emacs.d/web.el")

;;; .emacs ends here

Здесь load - функция, выполняющая загрузку указанного файла. Сам файл находится в каталоге .emacs.d/ и называется fonts.el. Туда я положил настройки шрифтов. Затем идёт подгрузка файла, отвечающего за список пакетов. При необходимости недостающие пакеты будут установлены из MELPA, MELPA-STABLE или другого из указанных репозиториев, впрочем, об этом я уже писал ранее.

Я не буду давать рекомендаций по поводу того, на сколько частей нужно разбивать конфигурацию, как эти части называть и так далее, каждый решает сам, потому что, например, несколько дней назад я не видел необходимости выносить настройки шрифтов отдельно, а сейчас решил, что так будет лучше. Как видите, за настройки для разработки на Python'е отвечает файл .emacs.d/python.el, в него я поместил все нужные параметры EMACS'а.

Пакеты

Как я уже говорил, автоматическую установку пакетов я описывал в другой статье, ниже перечислю лишь те пакеты, которые понадобятся, а так же дам краткое описание того, для чего они нужны.

anaconda-mode

Данный пакет служит для поддержки функциональности IDE при работе с файлами Python'а, как то быстрый переход к декларациям, вывод документации и т.д.

company

Данный пакет рекомендуется как более современная замена пакету auto-complete. Ничего не имею против последнего, но лично мне использовать указанный приятнее.

company-anaconda

Автодополнение в режиме anaconda-mode, без этого подсказки работать не будут.

ergoemacs-mode

В общем-то, не скажу, что этот пакет жизненно необходим, но он даёт необходимые удобства, например, упрощает работу с командами, заменяя стандартные хоткеи EMACS'а на свои, более близкие к тем, которыми пользуются нормальные люди, например, комбинации Ctrl+C и Ctrl+V, а так же многие другие начинают работать так, как это принято в подавляющем большинстве современных программ, т.е. копируют и вставляют текст. Подробнее можно почитать на сайте проекта.

flycheck, flycheck-pos-tip

Стандарт де-факто для проверки синтаксиса. Какой именно синтаксис и чем будет проверяться - настраивается. По умолчанию для Python'а используются flake8, pylint и pycompile. Естественно, чтобы данные средства работали, они должны присутствовать в системе.

helm

Система подсказок. Допустим, нажали Вы Alt+X, начинаете вводить lis, а он сразу выдаёт отфильтрованные команды, в которых присутствует данная строка. Можно стрелками выбрать нужную строку и нажать Enter. Умеет подсказывать не только команды, но так же имена файлов, виртуальные окружения и многое другое, легко расширяется. Практически незаменимое средство.

neotree

Пакет просто выводит дерево файлов слева. Можно забиндить отображение / скрытие на горячую клавишу, работать станет в разы удобнее.

python-mode

Базовый пакет для поддержки EMACS'ом Python'а.

py-autopep8

Пакет позволяет применить autopep8 - средство для автоформатирования кода по стандартам. Можно настроить на автоформат кода при сохранении файла. Удобно, хотя в старых проектах, где код писан ногами, порождает тонны баттхёрта у тех, кто будет делать ревью вашего кода.

py-isort

Сортирует импортированные файлы. Можно передать разные настройки. Лично я предпочитаю импорт 1-1, т.е. одна строка - один модуль или класс. Рекомендую, т.к. в этом случае с помощью flycheck будет проще удалять неиспользованные модули - выделил строку, нажал Backspace, сохранил.

pyvenv, virtualenvwrapper

Позволяет EMACS'у видеть виртуальные окружения и нормально с ними работать.

pip-requirements

Небольшой пакет для удобного редактирования файла зависимостей. Если кто не в курсе - файл REQUIREMENTS создаётся в корне Python-проекта и позволяет в одну команду установить все нужные для работы зависимости:

pip install -r REQUIREMENTS -U

В чём плюс данного пакета? Он выдаёт подсказки по именам, подгружая список с PyPi - главного всемирного рассадника питонячьих пакетов.

Установка через pip (от имени root)

pip install autopep8 flake8 isort pylint -U

Ergoemacs

Данный пакет довольно активно развивается и предоставляет кучу удобств. Вся его конфигурация у меня вынесена в отдельный файл, и чтобы далеко не ходить, публикую его ниже:

;;; Package --- Summary
;;; Comment:
;;; Settings for ergoemacs-mode

;;; Code:

(require 'ergoemacs-mode)

;;; Ergoemacs
(setq ergoemacs-theme nil)
(setq ergoemacs-keyboard-layout "us")
(setq ergoemacs-ini-mode t)
(setq ergoemacs-use-menus t)
(setq ergoemacs-smart-paste nil)
(setq ergoemacs-ctl-c-or-ctl-x-delay 0.3)
(ergoemacs-mode 1)

;;; ergoemacs.el ends here

Anaconda-mode

Тут речь не только об anaconda-mode, ниже приводится весь файл настроек для Python. Надеюсь, комментарии помогут в понимании данных настроек

;;; Package --- Summary
;;; Commentary:
;;; Settings for Python

;;; Code:

;;; Импорт необходимых модулей
(require 'py-autopep8)
(require 'py-isort)
(require 'pip-requirements-mode)

;;; Псевдоним для команды pyvenv-workon, пользователи virtualenv оценят удобство
(defalias 'workon 'pyvenv-workon)

;;; Автоматически загружать модуль python-mode, писать в статус баре "Python-mode"
(autoload 'python-mode "python-mode" "Python mode." t)

;;; Применять python-mode для файлов с расширением .py
;;; Использовать интерпретатор python для python-mode
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(add-to-list 'interpreter-mode-alist '("python" . python-mode))

(add-to-list 'auto-mode-alist '("\\REQUIREMENTS" . pip-requirements-mode))
(add-to-list 'auto-mode-alist '("\\REQUIREMENTS.txt" . pip-requirements-mode))
(add-to-list 'auto-mode-alist '("\\requirements" . pip-requirements-mode))
(add-to-list 'auto-mode-alist '("\\requirements.txt" . pip-requirements-mode))

;;; Подсвечивать строки, которые обычно используются при отладке
(defun annotate-pdb()
  (interactive)
  (highlight-lines-matching-regexp "import ipdb")
  (highlight-lines-matching-regexp "import pdb")
  (highlight-lines-matching-regexp "set_trace()")
  (highlight-phrase "TODO")
  (highlight-regexp "FIXME")
  (highlight-regexp "BUG")
  )

;;; В Python-mode автоматически включать anaconda-mode, pdb и
;;; автоматически применять autopep8 при сохранении файла
(add-hook 'python-mode-hook 'anaconda-mode)
(add-hook 'python-mode-hook 'annotate-pdb)
(add-hook 'python-mode-hook 'py-autopep8-enable-on-save)

;;; Перед сохранением так же отсортировать импортированные модули.
;;; Правило сортировки: одна строка - один модуль
(add-hook 'before-save-hook 'py-isort-before-save)
(setq py-isort-options '("-sl"))

;;; python.el ends here

Теперь следует перезапустить EMACS, чтобы он подхватил настройки, и начать работать. Ниже приводится вид моего EMACS'а, когда я пишу на Python.

Конфиг на GitHub

Ошибка "memmove does not exist on this platform"

Который раз вижу вот эту ошибку:

extensions/expat/lib/xmlparse.c:75:2: error: #error memmove does not exist on this platform, nor is a substitute available

Решение очень легко гуглится на StackOverflow, но для себя я решил сохранить, чтобы далеко не ходить. Проблема заключается в том, что в одном из заголовочных файлов Python 2.7 не определена константа HAVE_MEMMOVE

Решение

  • Открыть файл /usr/include/python2.7/pyconfig.h
  • Добавить в его конец строку

    #define HAVE_MEMMOVE 1

Послесловие: хватит уже пользоваться Python 2.7, Гвидо не для того старался с тройкой.