区分需要缩进的多行字符串和不需要缩进的多行字符串

时间:2016-11-27 20:58:41

标签: perl emacs indentation multilinestring cperl-mode

--- +简介

这个问题是关于缩进多行字符串,例如对于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)

所以现在我可以缩进多行字符串了。如果那就是我想做的事。

不幸的是,有时我确实要缩进多行字符串。有时我不会。

  • E.g。我可能会继承我不想意外的遗留代码 如果我在cperl-mode中编辑它就会中断。
  • 此外,我可以对这样的多行字符串进行不同类型的缩进/转换:

    1. 无 - 多行字符串的标准cperl-mode缩进
    2. 在行首开始修剪前缀,例如s / ^ [\ S \ n] *
    3. 有时我想要与cperl-mode相同的缩进 到qw {} - 基本上,我创建了自己的qw,允许类似的东西 没有警告的逗号,s / \ s + / / g
    4. 有时我可能希望字符串像HTML一样缩进, 或C,或......

我知道如何做到这些。我可以为任何惯例制定一个识别器。

但是......我正在寻找关于如何区分的建议,理想的标准做法或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中提到的问题。

0 个答案:

没有答案