Atur wilayah penyangga dengan mode utama lainnya

12

Saya memiliki buffer yang memperlihatkan dokumentasi untuk modul Ansible. Buffer ini memiliki mode utama sendiri yang menyediakan semua hal standar. Khususnya, ini mengklasifikasikan buffer untuk menyorot markup inline, opsi, bagian, dll. Semua dalam semua, itu sangat mirip dengan M-x man.

Di bagian bawah dokumentasi biasanya ada beberapa contoh kode dalam YAML. Saya ingin mengklasifikasikan ini juga. Saya bisa menambahkan kata kunci kunci font saya sendiri untuk YAML, tentu saja, tetapi saya lebih suka menggunakan kembali fontifikasi Mode YAML.

Bagaimana saya bisa melakukan itu? Secara khusus, bagaimana saya bisa menggunakan mode utama yang berbeda untuk mengklasifikasikan wilayah buffer tertentu?

Perhatikan bahwa Mode YAML tidak perlu aktif di wilayah ini. Seluruh buffer hanya merupakan buffer tampilan pasif, dan tidak dimaksudkan untuk diedit. Saya benar-benar hanya memerlukan fontifikasi yang dihasilkan seolah-olah Mode YAML aktif di wilayah itu.

Saya kira saya bisa menyalin wilayah buffer ke buffer sementara, mengaktifkan Mode YAML, mengatur buffer, dan menyalin semua properti teks. Apakah itu akan berhasil? Jika demikian, bagaimana cara menyalin properti teks, dan properti apa yang relevan untuk disalin? Atau ada pendekatan yang lebih baik?

lunaryorn
sumber
Bagaimana penerapan non-yaml fontification? Apakah Anda menerapkan properti teks secara manual, atau Anda menggunakan mode kunci-font?
Malabarba
Tautan dalam pos ini merangkum setidaknya sebagian besar opsi di luar sana: wisdomandwonder.com/link/8610/…
grettke

Jawaban:

10

Saya baru-baru ini menemukan masalah yang sama, pada dasarnya saya ingin mengklasifikasikan potongan kode dalam dokumentasi yang saya dapatkan dari sumber lain. Saya mengikuti pendekatan yang disebutkan di akhir jawaban Anda dan itu berhasil baik untuk saya. Fungsi saya berakhir dengan beberapa hal seperti berikut ini

(defun my-fontify-yaml (text)
  (with-temp-buffer
    (erase-buffer)
    (insert text)
    (delay-mode-hooks (yaml-mode))
    (font-lock-default-function 'yaml-mode)
    (font-lock-default-fontify-region (point-min)
                                      (point-max)
                                      nil)
    (buffer-string)))

Seperti @Malabarba tunjukkan dalam komentar pendekatan sederhana di atas tidak berfungsi jika buffer tujuan menggunakan font-lock-mode. Namun kita dapat menipu mode font-lock-mode untuk meyakini bahwa string sudah font dikunci dengan menyetel properti teks font-lock-faceke face, (kita mendapatkan faceset properti, ketika kita menggunakan fungsi di atas) dan mengatur properti teks fontifiedke t. Fungsi berikut mengambil string yang dikembalikan oleh fungsi di atas dan melakukan pemrosesan yang diperlukan sehingga string tersebut dimasukkan dengan huruf (ini diambil dari org-src-font-lock-fontify-blockfungsi mode-org

(defun my-fontify-using-faces (text)
  (let ((pos 0))
    (while (setq next (next-single-property-change pos 'face text))
      (put-text-property pos next 'font-lock-face (get-text-property pos 'face text) text)
      (setq pos next))
    (add-text-properties 0  (length text) '(fontified t) text)
    text))

Sekarang Anda dapat menggunakannya sebagai berikut

(insert (my-fontify-using-faces (my-fontify-yaml "application: test\nversion: 1")))
Iqbal Ansari
sumber
Ini adalah solusi yang sama dengan yang saya temukan sx.el, tetapi penting untuk dicatat bahwa itu hanya akan berfungsi jika buffer tujuan tidak menggunakan mode font-lock-mode.
Malabarba
Baik! Saya baru menyadari ini bekerja untuk saya karena saya menggunakan buffer di mana font-lock tidak digunakan (Help buffer)
Iqbal Ansari
@Malabarba menemukan cara untuk membuat pekerjaan ini dengan buffer tujuan dengan mode font-lock-mode diaktifkan
Iqbal Ansari
Terima kasih banyak, bekerja dengan sempurna !
lunaryorn
Oh bagus! Senang saya bisa membantu :)
Iqbal Ansari
3

Library Narrow Indirect ( narrow-indirect) dapat membantu di sini - lihat komentar tajuknya. Itu bergantung pada:

  1. penyempitan, yang membatasi pengeditan untuk sebagian pada buffer, dan
  2. buffer tidak langsung, yang menyalin buffer di buffer lain agar Anda dapat mengubah mode utama.

Perhatikan bahwa penyempitan dinonaktifkan secara default karena dianggap pemula-tidak ramah (pengikatan default adalah C-x n n). Anda dapat mengaktifkannya dengan meletakkan yang berikut ini di file init Anda:

(put 'narrow-to-region 'disabled nil)

Anda juga dapat melihat buatan tangan myfn-narrow-indirectsaya di conf saya .

freakhill
sumber
Apakah penyempitan sebenarnya memengaruhi penguncian font, yaitu menjauhkannya dari luar wilayah yang dipersempit? Apakah kunci font benar-benar tidak pernah menghapus batasan buffer?
lunaryorn
Lagi pula, paket wiki bukanlah opsi.
lunaryorn
Selain itu, Anda tidak perlu menghapus disabledproperti dari perintah untuk memanggilnya dari Emacs Lisp. Ini hanya memengaruhi penggunaan interaktif.
lunaryorn
0

Saya akan menyarankan melihat blok org-src-font-lock-fontify-yang menyediakan fungsi ini untuk blok sumber mode-org. Tampaknya hanya menyalin bagian-bagian yang relevan ke buffer lain, mengaktifkan mode utama di sana, dan kemudian menyalin teks yang sudah di-fontifikasi kembali. Meretas, tetapi tampaknya berhasil.

Joakim Hårsman
sumber
2
Jawaban ini lebih mirip komentar sejauh memberikan arahan yang disarankan untuk mengatasi masalah, tetapi bukan jawaban yang lengkap. Harap pertimbangkan untuk mengubahnya ke komentar.
Dan