emacs python 缩进问题_emacs上的多行python缩进

我同意Aaron关于您的风格选择的可取性,但是由于我也同意他关于EmacsLisp很有趣的观点,我将描述您如何实现这一点。在

Emacspython-mode计算函数^{}中一行的缩进,用于处理连续行的相关部分深埋在函数内部,无法轻松配置它。在

所以我们有两个选择:将整个python-calculate-indentation替换为我们自己的版本(每当{}发生变化时,python-mode就会成为维护的噩梦);或者

“Advise”函数python-calculate-indentation:也就是说,将它包装在我们自己的函数中,该函数处理我们感兴趣的情况,否则将遵从原始函数。在

选项(2)在这种情况下似乎是可行的。所以让我们开始吧!首先要阅读manual on advice,它建议我们的建议应该如下所示:(defadvice python-calculate-indentation (around continuation-with-dot)

"Handle continuation lines that start with a dot and try to

line them up with a dot in the line they continue from."

(unless

(this-line-is-a-dotted-continuation-line) ; (TODO)

ad-do-it))

这里ad-do-it是一个神奇的令牌,defadvice用原始函数代替它。从Python背景出发,您可能会问:“为什么不使用这种装饰风格?”Emacs建议机制设计为(1)将建议与原始建议很好地分开;以及(2)为一个不需要协作的函数提供多个建议;(3)允许您单独控制哪些建议被打开和关闭。当然可以想象用Python编写类似的东西。在

以下是如何判断当前行是否是虚线延续线:

^{pr2}$

这有一个问题:对beginning-of-line的调用实际上将点移动到行的开头。哎呀。我们不想在仅仅计算缩进时移动点。所以我们最好用一个调用^{}来结束这一点,以确保该点不会走投无路。在

我们可以通过向后跳过标记或带圆括号的表达式(Lisp称之为“S-expressions”或“sexps”)来找到需要对齐的点,直到找到点,否则就可以找到语句的开头。在缓冲区的受限部分进行搜索的一个好的Emacs习惯用法是narrow缓冲区只包含我们想要的部分:(narrow-to-region (point)

(save-excursion

(end-of-line -1)

(python-beginning-of-statement)

(point)))

然后继续向后跳过sexps,直到找到点,或者直到backward-sexp停止前进:(let ((p -1))

(while (/= p (point))

(setq p (point))

(when (looking-back "\\.")

;; Found the dot to line up with.

(setq ad-return-value (1- (current-column)))

;; Stop searching backward and report success (TODO)

...)

(backward-sexp)))

这里ad-return-value是一个神奇的变量,defadvice使用它来从建议的函数返回值。丑陋但实用。在

现在有两个问题。首先,backward-sexp可以在某些情况下发出错误信号,因此我们最好捕获该错误:(ignore-errors (backward-sexp))

另一个问题是跳出循环,同时也表示成功。我们可以通过声明一个命名的block,然后调用return-from,同时完成这两个操作。Blocks and exits是常见的Lisp特性,因此我们需要(require 'cl)

让我们把它们放在一起:(require 'cl)

(defadvice python-calculate-indentation (around continuation-with-dot)

"Handle continuation lines that start with a dot and try to

line them up with a dot in the line they continue from."

(unless

(block 'found-dot

(save-excursion

(beginning-of-line)

(when (and (python-continuation-line-p)

(looking-at "\\s-*\\."))

(save-restriction

;; Handle dotted continuation line.

(narrow-to-region (point)

(save-excursion

(end-of-line -1)

(python-beginning-of-statement)

(point)))

;; Move backwards until we find a dot or can't move backwards

;; any more (e.g. because we hit a containing bracket)

(let ((p -1))

(while (/= p (point))

(setq p (point))

(when (looking-back "\\.")

(setq ad-return-value (1- (current-column)))

(return-from 'found-dot t))

(ignore-errors (backward-sexp))))))))

;; Use original indentation.

ad-do-it))

(ad-activate 'python-calculate-indentation)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值