--- +简介
这个问题是关于缩进多行字符串,例如对于Perl,在emacs' cperl-mode,这样它们就不会破坏代码流。
我知道如何获得我想要的缩进,在字符串上使用=~ s/^[^\S\n]*\|//mhr
之类的转换,并提供emacs:关于cperl-calculate-indent
的建议,使用syntax-ppss
来识别我何时进入一个字符串。
麻烦的是,有时我想做这样的缩进,有时候不是。
我寻求有关约定的建议,BKM,暗示所需的缩进是什么。
my $legacy = qw{
This string
should
not be indented};
my $needs_trimming = (q{
|BEGIN
| SUB
|END
} =~ s/^[^\S\n]*\|//mgr);
my $needs_different_triming = (q{ + -
, ? :
| & ^
|| &&
| =~ s/\s+/ /gr);
我希望别人在我面前解决这个问题。
--- + DETAIL:
我问这是一个emacs / cperl-mode问题,但这个问题对于允许多行字符串的语言来说是通用的。不仅仅是Perl,还有Javascript,C / C ++,Javascript(Multiline strings that don't break indentation),LISP和elisp等。
我经常编写使用多行字符串的Perl代码。
我不喜欢多行字符串如何打破缩进:
if(cond) {
my $var = q{
START Line crossing string needs
to be indented
differently than rest of code
FINISH
};
my $var2 = ...
}
我更喜欢保持相同的缩进,所以我经常做
之类的事情 if(cond) {
my $var = (q{
|START Line crossing string needs
| to be indented
| differently than rest of code
|FINISH
} =~ s/^[^\S\n]*\|//mgr);
my $var2 = ...
}
if(cond) {
my $var = fix_string( {unindent=>'|',trim=>1,},
q{
|START Line crossing string needs
| to be indented
| differently than rest of code
|FINISH
} =~ s/^[^\S\n]*\|//mgr);
my $var2 = ...
}
好的,所以这很好用,我已经做了好几年,可能是几十年。
过去效果不佳的是缩进,使用perl-mode' and
cperl-mode'等软件包。
好的,所以我用
修复了这个问题(defun cperl-calculate-indent--hack--/ag (orig-fun &rest args)
"hack / experimenting with cperl-calculate-indent"
(interactive)
(let ((state (syntax-ppss)))
(cond
((and (nth 3 state) ;in string
(nth 8 state) ; beginning of string
(< (nth 8 state) (point-at-bol)) ; on different line
)
(save-excursion
(goto-start-of-string--ag)
(+ 4 (current-column)))
)
(t (apply orig-fun args))
)
)
)
(advice-add 'cperl-calculate-indent :around #'cperl-calculate-indent--hack--/ag)
;;(advice-remove 'cperl-calculate-indent #'cperl-calculate-indent--hack--/ag)
所以现在我可以缩进多行字符串了。如果那就是我想做的事。
不幸的是,有时我确实要缩进多行字符串。有时我不会。
此外,我可以对这样的多行字符串进行不同类型的缩进/转换:
我知道如何做到这些。我可以为任何惯例制定一个识别器。
但是......我正在寻找关于如何区分的建议,理想的标准做法或BKM。别人会发现可读的东西。
E.g。我考虑使用PerlX::QuoteOperator my_q
创建自己的运算符。但这是非标准的,可能会混淆他人,并可能在将来破裂。此外,我真正想做的只是提供一个缩进提示,而不是改变语言。
E.g。如上所述,我已经使用了fixup函数
fixup_string( q{ ... } )
。我可以在这些上进行模式匹配。但是当用户添加新的修复功能等时,这会中断。
E.g。我考虑过查看字符串的第一行,例如
fixup_string( q{:
:not indented
: indented
} )
这适用于我的前缀s / ^ [^ \ S \ n] *:// mgr,但在其他情况下则不行。
(我目前正在做(looking-at ".[~!@#$%^&*_+=|:;'?/]$"))
,这很容易,但是有明显的问题(比如,如果我想要一个字符串来启动"|\n..."
该怎么办。即它没有通过测试&#34 ;不要破坏现有代码&#34;。)
如果Perl的评论不是最终的,那么就像C&#39的`/.../'我可能dp
fixup_string( q/*indent-here*/{|
|
|
} )
但Perl确实有这样的非终结评论。 (是吗?有没有相同的句法技巧?)
因此我的问题。
我确信其他人之前已经解决了这个问题。我很想知道他们做了什么。
在许多方面,这只是同一缓冲区https://emacswiki.org/emacs/MultipleModes内的多个模式的特例。我想避免 https://www.emacswiki.org/emacs/HtmlModeDeluxe中提到的问题。