Düşük bir süreç uzun çizgiler oluşturduğunda yavaşlamayı nasıl önleyebilirim?


14

Bazı Scheme kodlarını kesmek için Emacs'ı Geiser ile kullanıyorum. REPL'de oynadığım için bazen çoğu zaman tek bir satırda olmak üzere çok sayıda çıktıyla sonuçlanan ifadeleri değerlendiriyorum .

Örneğin, SRFI-41 (akışlar) ile oynadım ve büyük bir dosyadan bir karakter akışı oluşturdum; sonra akışı zorladım ve Geiser dosyanın tüm içeriğini arabelleğime bir karakter akışı olarak engelledi. Hemen, ben tuttu ne kadar çıkış hattına eklenen daha fazla karakter olarak durma ve hiçbir konuya Emacs zemin basarak C-gya C-c C-cben Emacs (veya Geiser) Dur gelemedi.

Emacs, girişimi tamamen yok sayarken tüm Emacs oturumumu kırdı ve bu büyük karakter akışını tek satırda yanıt vermeyen bir Geiser REPL arabelleğine yazdırmaya öncelik vermesi gerektiğini düşünüyor.

Emacs oturumumu yıkıcı merakımdan korumak için yapabileceğim bir şey var mı? (Niçin çok uzun satırlar görüntülerken Emacs neden bu kadar yavaş oluyor ?) Uzun satırlar için bir sınır belirleyebilir ve Emacs'a çok uzun satırlar görüntülemeye çalışmanın uygun olmadığını söyleyebilir miyim?



2
Benim sorum, uzun satırları göstermekle ilgili değil; İlk etapta bu tür bir şeyden nasıl kaçınabileceğimi bilmek istiyorum (Emacs, bir inferiour sürecinden satırı okur, düzeltebileceğim bir dosyadan okunmaz); ve Emacs oturumumu Emacs'ın tek bir dinamik arabelleğe adamaya nasıl kaybettiğimi nasıl önleyeceğim.
rekado

"Eh, sorum uzun satırları göstermekle ilgili değil" O zaman belki başlığınızı değiştirmelisiniz. Belki de düşük işlem çıktısını filtrelemek ve belirli sayıda karakterden sonra yeni satır eklemek istersiniz?
dadı

Gerçekten de, bunun uzun çizgilerle ilgisi yok. yesbir in ansi-termörneği için de benzer bir (ancak sahip olduğu korkunç) etkisi. Gerçekten sadece emacs duraklama veren metin hacmidir.
PythonNut

Bir ara belleğe metin ekleme oldukça hızlıdır, gerçekte olduğundan daha yavaş görünmesini sağlayan yeniden görüntüleme işlemleri. Dürüst olmak gerekirse, yesbir VTE terminal emülatöründe çalıştırmak tüm CPU çekirdeklerimi en üst düzeye çıkarır, bu yüzden örnek olarak kullanmam.
wasamasa

Yanıtlar:


12

Yorumlarda daha önce yanıtlandığı gibi, Emacs uzun satırlar için yeniden gösterilmesinde çok yavaş hale geldi, iyi bilinen bir konudur . Bunu düzeltmek çok güzel olurdu, ancak doğru bir şekilde çekilmesi için çok fazla düşünceye ihtiyaç var. Bu belgenin 6.3 bölümüne göre nasıl başarılabileceğine dair bir fikrim var (temel olarak, görsel arabellek bilgisini geçerli arabellekte saklayın ve boşluk, görüntü özellikleri, pencere değişiklikleri vb. Eklendiğinde güncelleyin, ardından bu bilgileri kullanın her zaman taramaktan kaçınmak için yeniden görüntüleme kodunu kullanın), ancak C dahili bileşenlerini çıkarmak için yeterince tanıdık değilim.

Gerçi geçici çözümler var. En belirgin olanları, ekranla ilgili parametreleri ayarlamaktır (grafiksel Emacs örneğinde görsel satır kesme işlemini etkinleştirmek, grafiksel olmayan bir Emacs kullanarak bunu otomatik olarak yapmak, Bidi özelliklerini devre dışı bırakmak vb.) Ve dosya içeriklerini önceden işlemektir. ' Daha az belirgin olanı, dosyaları gerçekte satırlarından keserek veya satırların gerçekte olduğundan daha kısa görünmesini sağlayan metin özellikleri ekleyerek, dosyaları otomatik olarak sonradan işlemektir. Bunu daha ilginç bir cevaba dönüştürmek için, sadece comint-eseri modlar için çalışacak olan eski seçeneğin oldukça çirkin bir hackini sunacağım :

(defun my-comint-shorten-long-lines (text)
  (let* ((regexp "^\\(.\\{80\\}\\).*?$")
         (shortened-text (replace-regexp-in-string regexp "\\1" text)))
    (if (string= shortened-text text)
        text
      (propertize shortened-text 'help-echo text))))

(add-hook 'comint-preoutput-filter-functions 'my-comint-shorten-long-lines)

Bu, my-comint-shorten-long-linesmuhtemelen birçok satırdan oluşan bir dize alan ve içindeki herhangi bir satırı 80 karakter veya daha uzun bir uzunlukla değiştirmek için normal ifadelerin gücünü kullanan bir işlev tanımlar , üzerine geldiğinde orijinal metni görüntüleyen kısaltılmış bir sürümle. Kanca olarak kullanıldığında, comint-preoutput-filter-functionstüm comintçıktılar görüntülenmeden önce filtrelenir .

Ancak, hack'in bu yorumu oldukça ciddi bir zayıflığa sahiptir. Temel yazı tipinin devam ettiği (örneğin, M-x ielm) modlarda , bir dizenin parçası olan satırları mutlu bir şekilde kesecek ve bu şekilde bir sonraki alıntıya kadar her şeyi dize olarak yazacak! İstediğimiz bu değil ve biraz daha fazla regex ustalığı ile düzeltilebilir (ancak muhtemelen Python gibi bir dil için bir REPL içine girer). Biz oradayken, kısaltılmış çıktıyı da vurgulayalım:

(defun my-comint-shorten-long-lines (text)
  (let* ((regexp "^\\(.\\{80\\}\\).*?\\(\"?\\)$")
         (shortened-text (replace-regexp-in-string regexp "\\1\\2" text)))
    (if (string= shortened-text text)
        text
      (propertize shortened-text 'font-lock-face 'shadow 'help-echo text))))

(add-hook 'comint-preoutput-filter-functions 'my-comint-shorten-long-lines)

Bu biraz daha iyi, ama yine de çirkin. Gibi bir şey çıktı üzerine geldiğinizde find /de M-x shellcazip değil (biz ideal olarak kısaltılmamış çizgi, tüm çıkış görüntülemek isterdim), dize algılama en iyi gelişmemiş olduğu ve kestirme yerine herşeyi fontifying ait üç nokta ile daha iyi belirtilebilir. Bunun da ötesinde, gelen metnin gruplara dönüştürülmediği bile garanti edilmez. Tüm bunlar geçici bir arabellekte işleme adımını yapmak için çığlık atıyor, ancak okuyucuya alıştırma olarak (ya da yazar potansiyel blog yazısı olarak) bırakılacak.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.