简体   繁体   English

在Emacs中复制和粘贴Python函数

[英]Copy and paste Python functions in Emacs

I have a program that looks something like (this is a silly example to illustrate my point, what it does is not very important) 我有一个看起来像这样的程序(这是一个愚蠢的例子来说明我的观点,它的作用不是很重要)

count = 0

def average(search_term):
    average = 0
    page = 0
    current = download(search_term, page)
    while current:
        def add_up(downloaded):
            results = downloaded.body.get_results()
            count += len(results)
            return sum(result.score for result in results)
        total = average*count
        total += add_up(current)
        average = total/count
        print('Average so far: {:2f}'.format(average))
        page += 1
        current = download(search_term, page)

If I have the cursor on any of the lines 8–11 and press a key combination I want Emacs to copy or kill the add_up function, and then I want to move the cursor to line 2 and press a key combination and paste the function there, with the correct level of indentation for the context it is pasted in. 如果我将光标放在第8-11行中的任一行上并按一个组合键,我希望Emacs复制或add_up函数,然后将光标移至第2行并按一个组合键并将函数粘贴到此处,并针对其粘贴的上下文具有正确的缩进级别。

Is this possible, and if so, how would I do that? 这可能吗?如果可以,我该怎么做?

With python-mode.el py-kill-def and yank would do the job. 使用python-mode.el py-kill-defyank可以完成这项工作。 However, there are some restrictions. 但是,有一些限制。 py-kill-def must be called from inside def in question. py-kill-def必须从有问题的def内部调用。 So needs to go upward from line 11 first. 因此需要先从第11行开始。 Also indenting after insert poses some problems: as indent is syntax, sometimes Emacs can't know which indentation is wanted. 插入后缩进也会带来一些问题:因为缩进是语法,所以有时Emacs无法知道需要哪个缩进。 In example below have an indent of 4 first and of 8 in add_up probably is not wanted - however it's legal code. 在下面的示例中,可能不希望缩进4的缩进和add_up的8缩进-但这是合法代码。 After indenting first line in body of add_up , py-indent-and-forward should be convenient for the remaining. add_up主体中缩进第一行后, py-indent-and-forward应该很方便。

def average(search_term):
    average = 0
    def add_up(downloaded):
            results = downloaded.body.get_results()
            count += len(results)
            return sum(result.score for result in results)
    page = 0
    current = download(search_term, page)
    while current:

        total = average*count
        total += add_up(current)
        average = total/count
        print('Average so far: {:2f}'.format(average))
        page += 1
        current = download(search_term, page)

For this type of thing I usually use expand-region , which I choose to bind to C-= . 对于这种类型的事情,我通常使用expand-region ,我选择将其绑定到C-=

Using your example I can select the add_up() function by pressing C-= once, kill the region normally ( Ck ), move to line 2, and yank as usual ( Cy ). 在您的示例中,我可以通过按C-=一次来选择add_up()函数,正常杀死该区域( Ck ),移至第2行,然后照常拉动( Cy )。

Depending on what else you have configured for Python you may have to clean up some whitespace, or it may get cleaned up for you. 根据您为Python配置的其他内容,您可能必须清理一些空格,或者可能会为您清理。 For example, aggressive-indent would be helpful. 例如, aggressive-indent会有所帮助。

One manual option would be to reindent the pasted code with something like Cx Cx M-\\ . 一种手动的选择是使用Cx Cx M-\\类的代码重新缩进粘贴的代码。

I've been using smart-shift (available in Melpa) for this sort of thing. 我一直在使用smart-shift (在Melpa中可用)进行此类操作。 global-smart-shift-mode to enable (beware, it binds keys). global-smart-shift-mode启用(请注意,它会绑定密钥)。 Select the block you want to move (I'd use expand-region like Chris), and the default keybind CSc <arrow> starts moving it. 选择要移动的块(我将使用像Chris这样的expand-region ),默认的键绑定CSc <arrow>开始移动它。 Once you're shifting, the arrows (without CSc ) shift further. 转移后,箭头(不包含CSc )会进一步转移。 Horizontal shifts use the major mode's indent offset ( python-indent-offset for python.el). 水平移位使用主模式的缩进偏移量(python.el为python-indent-offset )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM