Back to Home

Emacs and Python (article 2 of the cycle)

emacs python

Emacs and Python (article 2 of the cycle)

    According to the results of research on the work of programmers, about 20% of the time is spent directly writing code and about 80% of the time is spent viewing the old one, analyzing it. Based on this premise, the text editor must first provide convenient means of navigating the code. Most of the features described just deal with navigation and analysis.

    In this article I will try to demonstrate the maximum convenience in daily use of the Emacs editor features for the Python language, and more specifically for editing Django projects.

    As the proverb says: "They are waiting for the promised three years." Although three years have not passed, but already pretty much from my previous article “Emacs for beginners: introduction”. I won’t “spread my head over the tree”, but try to show as briefly as possible how various Emacs features work when applied to Python.



    Format of the article:
    • feature description
    • example how to enable it in your config
    • and an accompanying video demonstration of the work. Warning: the sound quality on all videos is so-so. Correct, but later ...


    For those who are interested in applying the whole recipes - my config is available (Mercurial) here , and here: the recipe for its application .

    Content


    • 1. Integrated documentation
    • 1.1. Rope pydoc
    • 1.2. Pylookup - Python Standard Library Documentation Index
    • 1.2.1. For indexing also Django documentation
    • 2. Python debugger: pdb
    • 3. Rgrep
    • 4. Occur
    • 5. Blocks in Emacs
    • 6. Yasnippet - input automation with snippets
    • 7. Navigation by python code
    • 7.2. By functions and classes of the current file via IM-python
    • 7.3. By functions and classes of the current file via Speedbar
    • 7.4. Going to the place of definition of the variable [class, method]
    • 7.5. Bookmarks
    • 7.6. File search by name pattern
    • 7.7. Open project file: rope-file-find
    • 8.1. Python Ident Left / Right
    • 8.2. Fighting blank text
    • 8.3. Visualization of excess line length
    • 8.4. Auto completion
    • 8.4.1. Autocomplete Rope
    • 8.4.2. Autocomplete hippie-expand
    • 8.5. Comments in the text
    • 9. Code quality testing
    • 9.1. integration with Flymake: pyflymake
    • 9.2. pep8 call
    • 9.3. pylint call
    • 10. Django specifics
    • 11. Compilation mode for python and quick start
    • 12. Finally


    1. Integrated documentation




    Pretty convenient feature. In any place if you forgot some details on the documentation, you can call one of the options for showing the documentation:

    • pylookup - indexed Sphinx option for Python standard library
    • pydoc - inline documentation from an object (via ropemacs)


    I show these features separately as they are independent of each other.

    1.1. Rope pydoc




    The recipe for inclusion: according to the recipe for inclusion of rope is separate and conversation and is described in:


    After turning on the rope, its keybindings and menus start working:
    • In the menu, this function is available through: [Rope] -> [Shown documentation]
    • Keybinding: Cc d




    1.2. Pylookup - Python Standard Library Documentation Index




    The package is put from here: https://github.com/tsgates/pylookup . It has two active components: we place pylookup.el in the second, readable emacs for loading Lisp, and pylookup.py somewhere where it will be accessible on the way for the user.

    Indexed like this:
    ./pylookup.py -d /var/db/pylookup/pylookup.db -u /usr/share/doc/python-docs-2.*/html


    In emacs we configure module loading and a convenient key for a call. I have configured
    the keys Control + Shift + Menu .

    It is included like this (see also: cfg_pylookup.el ):

    (eval-when-compile (require 'pylookup))
    (setq pylookup-program "/usr/local/bin/pylookup.py")
    (setq pylookup-db-file "/var/db/pylookup/pylookup.db")
    (global-set-key [(control shift menu)] 'pylookup-lookup)
    




    1.2.1. For indexing also Django documentation:




    Install django-docs:

    cd ~/
    svn co http://code.djangoproject.com/svn/django/trunk/docs/ django-docs
    cd django-docs
    make html
    cd _build/html
    ln -s genindex.html genindex-all.html
    


    And we supplement the command from above:

    ./pylookup.py -d /var/db/pylookup/pylookup.db -u /usr/share/doc/python-docs-2.*/html -u ~/django-docs/_build/html/
    




    2. Python debugger: pdb




    There is a wonderful pdbtrack module that “monitors” the movements of the program code during debugging using the keys n, s and others. And by the way, skillfully working with pdb can achieve more than in similar visual debugging tools.

    pdbtrack is turned on automatically with the main python-mode enabled.

    In order for it to be called in emacs, you need to put a line like:
    import pdb; pdb.set_trace () in your code. An executable program must be executed in emacs / shell.



    3. Rgrep




    rgrep - fast line search in all files with a specific extension. It is worth noting that since the version of emacs 23.x, developers have changed something in the call interface and now it is impossible to separate extensions with a space, such as [* .html * .py] it became impossible if you didn’t know the workaround, of course:
    to enter a space in rgrep - screen it with the

    Cq key rgrep works amazingly fast, and even in our largest project with tens of thousands of files, it finds the search in a split second, which is important for frequently performed searches.

    I have rgrep bound to a key: C-f7



    4. Occur




    occur shows the occurrence of this line in the current file. In order to make it convenient to call, I made a macro that automatically selects the current word and then calls occor on it. I have this function attached to a key: Cz o



    5. Blocks in Emacs




    Blocks are:
    • ordinary
    • square


    Also, blocks can be stored in different registers, respectively, you can work with different blocks at the same time.



    5.1. Multiple blocks



    Yes. It is not used very often, but when applied, it saves you a lot of time that would be spent on walking up and down on klipper / parcellite or even worse (if you have one clipboard).

    Keys:

    • Cx rs char - memorize a block into a named buffer symbol, for example Cx rs1 - memorize a block by name 1.
    • Cx ri char - paste from a named block


    5.1. Square blocks



    5.1.1. Visual square blocks

    The visual mode is activated with the C-enter button. A rectangular area appears in which you can fill in the text, delete,
    or copy the entire rectangle. In this mode, all standard buttons for working with the block work - Alt + Y to memorize the
    block and Ctrl + Y to paste.

    5.1.2. Non-visual square blocks


    There is a second version of square blocks, somewhat stripped down, but working for terminal mode. It works like this: start
    to select the block as usual (C-space) but at the same time work with the block by keys:

    • Cx rr char - remember a rectangular block in a named register
    • Cx ri char - paste from register


    5.2. View kill ring


    Some convenient replacement for the named block is the klipper analogue built into emacs, called killring:

    (require 'browse-kill-ring)
    (global-set-key (kbd "C-c k") 'browse-kill-ring)
    


    5.3. Confusing situation with blocks and copy keys



    It is worth noting that the situation with blocks and key bindings to operations is confused for several objective, historical
    reasons:

    • Buttons familiar to all Windows for working with Cc Cv blocks do not work by default
    • There are two clipboards in xorg: primary and secondary
    • Klipper, Parcellite also engaged in the management of secretions often change sequence, adding a mess to everything
    • Emacs has changed the procedures for working with xorg primary / secondary selection in its current version 0.24


    As a result, often even such a trivial thing as copying in blocks becomes a difficult stage for learning
    emacs to master .

    Pouring water into the fire is also what the xorg True way to copy blocks: Control Insert to copy and Shift Insert
    to paste the block. In this case, the mouse copies to one clipboard and keyboard selections get into another.

    For beginners, I often advise you to learn the “True way” right away and not try to turn on the so-called cua-mode, which is designed to free Cc Cv from
    standard emacs key bindinds, depriving the end user of a lot of convenient functionality. If we study emacs, then learn
    two additional keys:
    • Alt-w to remember a block
    • Cw to paste it


    not a super problem. For those for whom it is, turn on Cua-mode safely and work on, but most likely you will still
    return to the topic and return the standard keys when you feel that there are not enough convenient keyboard shortcut keys.

    6. Yasnippet - input automation with snippets




    Yasnippet is a convenient way to automate the input of frequent but difficult to remember blocks of text.



    It is installed as an independent emacs package, usually available in the repository of your system.

    Configurable as:

    (add-to-list 'load-path "/usr/share/emacs/site-lisp/yasnippet")
    (autoload 'yas/initialize "yasnippet" "Do necessary initialization.")
    (autoload 'yas/load-directory "yasnippet"
      "Load snippet definition from a directory hierarchy." t)
    (require 'yasnippet) ;; not yasnippet-bundle
    (yas/initialize)
    (yas/load-directory "/usr/share/emacs/etc/yasnippet/snippets")
    (yas/load-directory "~/.emacs.d/yasnippets/")
    (setq hippie-expand-try-functions-list
          (cons 'yas/hippie-try-expand hippie-expand-try-functions-list))
    (global-set-key [(\t)] 'indent-for-tab-command)
    (setq yas/trigger-key (kbd "M-n"))
    


    7. Navigation by python code




    7.1. Up and Down Functions


    Keys:
    • Alt + Down - down a function (class) down
    • Alt + Up - per function (class) up
    • Cc a - to the beginning of the class
    • Cc e - to the end of the class




    Configuration:
    (defun py-to-start-of-class()
      (interactive)
      (py-beginning-of-def-or-class 'class)
    )
    (defun py-to-end-of-class()
      (interactive)
      (py-end-of-def-or-class 'class)
    )
    (add-hook 'python-mode-hook
                   '(lambda ()
      (local-set-key [(s menu)] 'rope-code-assist)
      (local-set-key [(s up)] 'python-move-to-start-of-class)
      (local-set-key [(s down)] 'python-move-to-end-of-class)
      (local-set-key [(meta down)] 'py-end-of-def-or-class)
      (local-set-key [(meta up)] 'py-beginning-of-def-or-class)
      (local-set-key (kbd "C-c C-a") 'py-to-start-of-class)
      (local-set-key (kbd "C-c C-e") 'py-to-end-of-class)
      (local-set-key (kbd "s-q") 'py-shift-region-left)
      (local-set-key (kbd "s-w") 'py-shift-region-right)
      )
           )
    


    7.2. By functions and classes of the current file via IM-python




    Keys (works not only in pyhon, but generally where):
    • Cc v - show a list of definitions in the current file


    Definition see here: idomenu.el



    7.3. By functions and classes of the current file via Speedbar




    I have configured the Scroll_Lock key:
    (global-set-key [Scroll_Lock] 'speedbar)
    




    7.4. Going to the place of definition of the variable [class, method]




    Configured via Rope and bookmark on the keys:
    • Alt + Enter - go to the place of definition
    • Alt + Shift + Enter - look back




    The drawback is that recording the history of transitions is global and each transition leaves garbage in bookmarks,
    it will be necessary to rewrite this moment in Lisp with an array. But so far it works.

    (defun rope-goto-definition-save-place ()
       """ save current place as 'save-place' bookmark and rope-goto-definition """
       (interactive)
       (bookmark-set "save-place" 1)
       (rope-goto-definition)
    )
    (defun rope-return ()
       """ save current place as 'save-place' bookmark and rope-goto-definition """
       (interactive)
       (bookmark-jump "save-place")
    )
    (global-set-key [(M return)] 'rope-goto-definition-save-place)
    (global-set-key [(M shift return)] 'rope-return)
    


    7.5. Bookmarks



    • Cz b - put a link
    • Cz Up - go to the link above (in the current file)
    • Cz Down - go to the link below (in the current file)
    • Cz space - go to the global list of links




    (require 'bm)
    (global-set-key (kbd "C-z b") 'bm-toggle)
    (global-set-key (kbd "C-z ") 'bm-previous)
    (global-set-key (kbd "C-z C-p") 'bm-previous)
    ;(global-set-key [(control shift down)] 'bm-next)
    ;(global-set-key [(control shift n)] 'bm-next)
    (global-set-key (kbd "C-z ") 'bm-next)
    (global-set-key (kbd "C-z C-n") 'bm-next)
    (global-set-key (kbd "C-z ") 'bm-show-all)
    


    7.6. File search by name pattern



    It works in any mode, not directly related to Python, just a convenient function. Called by:
    • CSf - search for a file by name


    (global-set-key [(control shift f)] 'find-name-dired)
    




    7.7. Open project file: rope-file-find




    It’s very convenient, especially to open a linked file, for example a template file for view in Django.
    • Cx pf - ope-find-file - find a file using the Rope package




    8. Working with python text


    8.1. Python Ident Left / Right




    • sq, Cc <, Cc Cl - move the block to the left
    • sw, Cc>, Cc Cr - move the block to the right




    8.2. Fighting blank text



    • Cz wd - take blank text




    (define-key global-map  "C-zws"         'show-trailing-whitespace)
    (define-key global-map  "C-zwh"         'hide-trailing-whitespace)
    (define-key global-map  "C-zwd"         'delete-trailing-whitespace)
    


    8.3. Visualization of excess line length




    It is established:
    (make-face 'mode-line-80col-face)
    




    8.4. Auto completion




    8.4.1. Autocomplete Rope




    Starts working when Rope is installed.



    8.4.2. Autocomplete hippie-expand




    ( global-set-key "M-" 'hippie-expand )
     




    8.5. Comments in the text




    • CSz, C- # - comment or uncomment the highlighted block of code




    (global-set-key [(control \#)] 'comment-or-uncomment-region)
    (global-set-key [(control shift z)] 'comment-or-uncomment-region)
    


    ; hippie expand
    (global-set-key "\M- " 'hippie-expand)
    


    9. Code quality testing




    9.1. integration with Flymake: pyflymake




    To support integration with flymake, you will need to install pyflakes, pylint packages and configure their location in your
    copy of the file:

    pyflymake.py
    And also install this Lisp code:
    cfg_flymake.el



    Unfortunately, even after a lot of processing, this solution is not ideal. Sometimes flymake writes _flymake files out of place on
    network services, sometimes it simply doesn’t work correctly. But in fact, in 98% of cases, it is very useful as it allows you to
    earlier detect a mistake made.

    9.2. pep8 call




    The module is installed in the system: pep8.



    ; pep8
    (require 'python-pep8)
    (global-set-key (kbd "C-c p 8") 'pep8)
    


    9.3. pylint call




    Similarly. First, install the pylint system package and then:

    ; pylint
    (require 'python-pylint)
    (global-set-key (kbd "C-c p l") 'pylint)
    




    10. Django specifics




    1) You need to start the project from django-shell - so that pdb is available.
    2) There are several different django templates syntax display modules.



    11. Compilation mode for python and quick start



    Anywhere in a python program, if it is a stand-alone script, you can run it through the Cc Cc key .
    When an error is generated in this case, the cursor will be in place of the error.

    Option number two: run the program from the compile option. In my config, it is configured as:

    (global-set-key [C-f9] 'compile)
    


    If you use the compile function, you can use the F8 / Shift-F8 error jump.

    In both cases, the pdb call will not work; the programs are launched without a connection to the terminal.



    12. Finally




    What is not included in this article



    I tried to describe the features most related to editing Python files. Many were not included in this review, although they relate directly to working with a Python project, for example, such a feature as working with a version control system - it deserves a separate article, which I intend to do in the [possibly near] future.

    The article is not finished, as comments arrive I will definitely make changes and additions.

    What I expect from reader comments :
    • Tell me what I forgot (or did not know), I will add.
    • Who is not lazy to do a similar review on vim, Sublime, and so on? First of all, the features described here are of interest and those [useful] features that are not present in Emacs but are present elsewhere.


    PS Sound quality let us down, I wrote using ffmpeg -vf crop = 970: 505: 7: 15 -f alsa -i hw: 0 -f x11grab -r 25 -s 1680x1050 -i: 0.0 -s 1280x720 -vcodec libx264 -vpre lossless_ultrafast filename.avi and
    the microphone on the laptop. Firstly, keystrokes are loudly heard, secondly, the sound is quiet and sometimes extraneous noises are heard. Alas ... Perhaps I will re-shoot the video using the
    headset, but so far there is - that is. Better than without them, right?

    Read Next