Отличие многострочных строк, которые требуют отступа от тех, которые не
---+ КРАТКОЕ ОПИСАНИЕ
Этот вопрос касается отступа многострочных строк, например, для 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.
Кроме того, существуют различные типы отступов / преобразований, которые я могу сделать для таких многострочных строк:
- None - стандартный отступ cperl-mode для многострочных строк
- Обрезать префикс в начале строки, например, s/^[\S\n]*
- Иногда мне нужен такой же отступ, который дает cperl-mode для qw{} - в основном, я создаю свой собственный qw, который позволяет такие вещи, как запятые без предупреждений, s/\s+/ /g
- Иногда я действительно хочу, чтобы строка была с отступом как 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.