Как составить регион как "<? Php foo; bar;?>" - PullRequest
1 голос
/ 22 декабря 2010

Я хочу свернуть блок php в файле шаблона php.

  <html>
<?php
  $bar = foo();
  echo $bar;
?>
  <h1><?php echo $title; ?></h1>
  </html>

to >>>>

  <html>
  {{PHP}}
  <h1>{{PHP}}</h1>
  </html>

Во-первых, я пытаюсь использовать font-lock-add-Keywords, это не удалось. Большое спасибо @Gilles за (поддержка? Совет? Я не знаю, какое слово должно быть здесь, извините).

(eval-after-load 'php-mode
  '(progn
     (setq font-lock-multiline t)
     (font-lock-add-keywords
      'php-mode `(("\\(<?php .* ?>\\)("
                   (0 (progn (compose-region (match-beginning 1)
                                             (match-end 1) "の")
                             nil)))))))

Тогда попробую ниже, все работает.

(defun lot/php-hide ()
  "compose php block in buffer"
  (interactive)
  (beginning-of-buffer)
  (while (re-search-forward "\\(<\\?php\\(.\\|\n\\)*?\\?>\\)" nil t)
    ;; (make-overlay (match-beginning 0) (match-end 0))
    ;; (hide-region-hide)
    ;; 'hide-region-hide' doesn't work, so try compose-region
    (compose-region (match-beginning 0)
                    (match-end 0)
                    ;; "{{PHP}}" ; use word can't work perfect.
                    "の"
                    )
    )
  )

Покажите мне ошибку, если есть, спасибо XD

Ответы [ 2 ]

2 голосов
/ 23 декабря 2010

В вашем регулярном выражении есть простая ошибка: ? является специальным символом, но вы хотите сопоставить его буквально, поэтому перед ним требуется обратная косая черта. Обратите внимание, что строковый литерал и кавычки регулярного выражения являются ортогональными, поэтому обратный слеш регулярного выражения должен быть удвоен в строковом литерале.

Кроме того, регулярные выражения являются жадными, поэтому часть .* может соответствовать больше, чем вы предполагали, если у вас есть еще один случай ?>( позже в строке. Если вы замените . на [\n>], это предотвратит расширение матча за пределы первого >. Если вы используете Emacs ≥23, вы можете вместо этого использовать не жадный оператор, чтобы остановить матч как можно раньше: .*?.

"\\(<\\?php [^\n>]* \\?>\\)("

Это покажет такие вещи, как <?php foo bar?>( как Ƥ(.

круглые скобки с обратной косой чертой \(\) в регулярном выражении разделяют группу; (match-beginning 1) и (match-end 1) возвращают граничные позиции для первой (и единственной) группы.

Документация по регулярным выражениям содержится в руководстве по Emacs .

Если вы хотите, чтобы совпадение распространялось на несколько строк, вам нужно [^>]* или \\(.\\|\n\\)*? в регулярном выражении. Кроме того, вы должны указать библиотеке Font Lock расширять свои поиски на несколько строк (по умолчанию она ограничивает все поиски в конце строки по соображениям эффективности). Используйте это:

 (eval-after-load 'php-mode
   '(progn
      (setq font-lock-multiline t)
      (font-lock-add-keywords …)))
2 голосов
/ 22 декабря 2010

Итак, вы хотите ввести P, и он должен вывести что-то вроде <?php xxx; xxx; ?>?Правильно ли я понял ваш вопрос?

В этом случае проверьте yasnippet ( больше информации о emacswiki ).Он позволяет вам определять свои собственные фрагменты (синтаксис очень прост), например, P, пусть он имеет заполнители (так что вы можете заменить xxx; и xxx; чем-то другим при вызове фрагмента) и тому подобное.Это действительно удобно.Просто создайте новый фрагмент (имя файла указывает на его ярлык, т. Е. Назовите его P в этом примере) и введите что-то вроде:

# name: My own P-snippet.
# --
<?php ${first}; ${second}; ?>

Нет необходимости создавать собственные блокировки шрифтов, нетнужно использовать регулярное выражение.Просто создайте новый фрагмент.После создания (и загрузки его я обычно перезапускаю emacs, потому что мне лень) ваш фрагмент, открываю буфер php-mode, набираю P и нажимаю tab.Магия!:)

...