Teks sementara di lokasi jendela tanpa teks untuk di-propertize / overlay?

9

T: bagaimana cara saya menunjukkan sementara teks di jendela di lokasi layar tanpa teks untuk propertize / overlay?

Saya akrab dengan ide dasar di balik properti teks dan overlay (lihat juga utas ini ), telah menggunakannya beberapa kali, tetapi saya sama sekali tidak mahir dengan mereka. Pemahaman saya yang terbatas adalah bahwa perlu ada teks untuk propertize atau overlay, tapi saya bertanya-tanya bagaimana cara menggunakan bagian dari jendela yang tidak memiliki teks di dalamnya.

Berikut screenshot untuk contoh:

masukkan deskripsi gambar di sini

Bagaimana bisa seseorang meletakkan teks (sementara) di salah satu kotak merah di tangkapan layar, yaitu, ruang kosong di sebelah kanan teks, atau di bawah baris terakhir di buffer?

Dan
sumber
Singkatnya, Anda dapat menggunakan properti tampilan untuk menampilkan teks yang tidak ada di sana. Seseorang mungkin memberikan jawaban penuh sebelum saya pulang.
Malabarba
mode perusahaan menyelesaikan meletakkan overlay pada teks jika ada cukup setelah atau sebelum titik dengan properti tampilan, atau menggunakan properti after-string untuk menampilkan sesuatu di bawah ujung buffer. Saya kurang yakin tentang menampilkan sesuatu di samping, tetapi tampaknya mungkin dengan lebar dan posisi hamparan yang tepat.
wasamasa
Bisakah Anda tidak hanya insertmengirim teks ke buffer dan menganjurkan itu?
rekado

Jawaban:

6

Saya telah membuat contoh fungsi yang mengambil string dan untuk sementara menampilkannya dengan batas waktu setelah teks buffer:

(defun my-momentarily-display-after-buffer-end (string &optional timeout)
  (let ((ov (make-overlay (point-max) (point-max))))
    (overlay-put ov 'after-string
                 (concat (propertize " " 'display
                                     '(space :align-to (+ left-fringe 10)))
                         (propertize string 'display
                                     '(raise -1))
                         "\n\n"))
    (sit-for (or timeout 5))
    (delete-overlay ov)))

Mantra berikut akan menghasilkan contoh kotak merah bawah Anda:

(my-momentarily-display-after-buffer-end "Nothing to see here...")

Alasannya adalah karena overlay menggunakan marker sebagai posisi untuk ditampilkan. Menggunakan posisi terluar sebagai awal dan akhir hamparan memungkinkan Anda menampilkan teks setelahnya dengan menggunakan after-stringproperti. Karena overlay dapat berisi teks yang di-propertisasi, saya mengaturnya agar tampak berlekuk dan dengan spasi putih di sekitarnya.

Contoh lain dapat menggunakan ide yang sama untuk menampilkan teks setelah akhir baris:

(defun my-momentarily-display-after-line-end (string &optional timeout)
  (let ((ov (make-overlay (line-end-position) (line-end-position))))
    (overlay-put
     ov 'after-string
     (concat (propertize " " 'display
                         `(space :align-to (- right-fringe
                                              ,(1+ (length string)))))
             string))
    (sit-for (or timeout 5))
    (delete-overlay ov)))

Doa berikut akan menghasilkan contoh kotak merah sebelah kanan Anda:

(my-momentarily-display-after-line-end "annotation")

Anda dapat menjadi jauh lebih gila dan menambahkan wajah untuk membedakan overlay ini dari teks buffer, menampilkannya lebih lama daripada untuk timeout, menyesuaikan posisi mereka, mendeteksi ketika tidak ada ruang kosong dan menggunakan overlay normal dari teks propertized, dll. Saya sarankan untuk melihat kode sumber mode perusahaan karena sangat mudah dibaca dan menunjukkan penggunaan overlay yang lebih rumit (dan sebagian besar bebas bug) untuk membuat menu sembulan yang fleksibel dengan fitur yang disarankan.

wasamasa
sumber
2

Anda dapat sementara menampilkan teks dalam buffer dengan fungsi momentary-string-display. Dibutuhkan pesan untuk ditampilkan dan posisi di buffer.

Ini:

(momentary-string-display "hello there" 200)

akan menempatkan string "halo di sana" pada posisi 200 di buffer. Ini akan memindahkan semua teks lain pada titik ini ke samping untuk memberi ruang bagi "halo dunia", tetapi semuanya akan dikembalikan ke tempatnya semula ketika Anda menekan tombol apa saja.

Anda tidak perlu teks dalam buffer untuk membuat overlay, meskipun itu adalah persyaratan untuk properti teks. Berikut hamparan dengan lebar nol yang menghasilkan teks tambahan untuk ditampilkan:

(let ((ov (make-overlay 1 1)))
  (overlay-put ov 'before-string "this text is not part of the buffer"))

Perhatikan bahwa hamparan ini akan menyingkirkan teks buffer; itu tidak akan mencakup teks pada posisi yang diberikan.

Tampaknya tidak mungkin untuk menempatkan overlay pada posisi apa pun di buffer yang lebih besar dari point-max/ buffer-size, yaitu Anda mungkin tidak akan dapat menempatkan teks pada posisi tertentu di bawah teks buffer kecuali Anda meretas batasan ini. Anda dapat, tentu saja, menempatkan teks tepat setelah teks buffer dengan after-stringproperti pada overlay disematkan ke point-maxposisi.

rekado
sumber