Отличие многострочных строк, которые требуют отступа от тех, которые не

---+ КРАТКОЕ ОПИСАНИЕ

Этот вопрос касается отступа многострочных строк, например, для Perl, в emacs-режиме cperl, чтобы они не нарушали поток кода.

Я знаю, как получить нужный отступ, используя такие преобразования, как =~ s/^[^\S\n]*\|//mhr на строку, и предоставление Emacs: о совете cperl-calculate-indent, с помощью syntax-ppss узнавать, когда я в строке.

Беда в том, что иногда я хочу сделать такой отступ, а иногда нет.

То, что я ищу совет относительно соглашений, BKMs, для намека, что является желаемым отступом.

    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);

Я ожидаю, что другие решили эту проблему до меня.

---+ ДЕТАЛИ:

Я задаю это как вопрос в режиме emacs/cperl, но проблема является общей для языков, которые допускают многострочные строки. Не только Perl, но и Javascript, C/C++, Javascript ( многострочные строки, которые не нарушают отступ), 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-режим.

ОК, так что я исправил это, используя

(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)

Так что теперь я могу сделать отступ для многострочных строк. Если это то, что я хочу сделать.

К сожалению, иногда я хочу сделать отступ для многострочной строки. А иногда нет.

  • Например, я могу унаследовать устаревший код, который не хочу случайно взломать, если я отредактирую его в режиме cperl.
  • Кроме того, существуют различные типы отступов / преобразований, которые я могу сделать для таких многострочных строк:

    1. None - стандартный отступ cperl-mode для многострочных строк
    2. Обрезать префикс в начале строки, например, s/^[\S\n]*
    3. Иногда мне нужен такой же отступ, который дает cperl-mode для qw{} - в основном, я создаю свой собственный qw, который позволяет такие вещи, как запятые без предупреждений, s/\s+/ /g
    4. Иногда я действительно хочу, чтобы строка была с отступом как HTML, или C, или...

Я знаю, как сделать каждый из них. Я могу поднять распознаватель для любого соглашения.

Но... Я ищу предложения, в идеале стандартные практики или BKM, как сделать это различие. То, что другие найдут читабельным.

Например, я подумал о создании своих собственных операторов, используя PerlX::QuoteOperator my_q, Но это нестандартно, может запутать других и может сломаться в будущем. Кроме того, я действительно хочу дать намек на отступ, а не менять язык.

Например, как объяснено выше, я уже использую функции исправления fixup_string( q{ ... } ), Я мог бы сопоставить образец с этим. Но это ломается, когда пользователь добавляет новые функции исправления и т. Д.

Например, я рассмотрел, глядя на первую строку строки, например,

fixup_string( q{:
                 :not indented 
                 :     indented
              } )

Это работает для моего префикса s/^[^\S\n]*://mgr, но не в других случаях.

(Я сейчас занимаюсь (looking-at ".[~!@#$%^&*_+=|:;'?/]$")), что достаточно просто, но с очевидными проблемами (например, что, если я хочу, чтобы строка начиналась "|\n...", Т.е. он не проходит тест "не нарушайте разумно существующий код".)

Если бы у Perl был комментарий, который НЕ должен заканчиваться строкой, как у C / `/ / /, я мог бы использовать dp

fixup_string( q/*indent-here*/{|
                 | 
                 |
              } )

но у Perl есть такие не-конец строки комментариев. (Есть ли? Есть ли синтаксический трюк, который является эквивалентом?)

Поэтому мой вопрос.

Я уверен, что другие решили эту проблему раньше. Я хотел бы знать, что они сделали.


Во многих случаях это просто особый случай нескольких режимов внутри одного буфера, https://emacswiki.org/emacs/MultipleModes. Я хотел бы избежать проблем, упомянутых в https://www.emacswiki.org/emacs/HtmlModeDeluxe.

0 ответов

Другие вопросы по тегам