열등한 프로세스가 긴 줄을 생성 할 때 속도 저하를 방지하는 방법은 무엇입니까?


14

Geiser와 함께 Emacs를 사용하여 일부 Scheme 코드를 해킹합니다. REPL에서 놀면서 때로는 종종 한 줄에 많은 결과를 초래 하는 표현식을 평가 합니다.

예를 들어 방금 SRFI-41 (스트림)을 사용하여 큰 파일에서 캐릭터 스트림을 만들었습니다. 그런 다음 스트림을 강제 실행하고 Geiser는 파일의 전체 내용을 문자 스트림으로 버퍼에 넣었습니다. 거의 즉시, Emacs는 출력 라인에 추가 된 곳에서 점점 더 많은 문자를 정지 시키며, 아무리 길게 누르 C-g거나 C-c C-cEmacs (또는 Geiser)를 중지시킬 수 없었습니다.

이맥스는 이제 내 입력을 완전히 무시하면서 전체 Emacs 세션을 중단했습니다.이 대규모 문자 스트림을 한 줄에 모두 응답하지 않는 Geiser REPL 버퍼로 인쇄하는 것을 우선시해야한다고 생각했습니다.

Emacs 세션을 파괴적인 호기심으로부터 보호하기 위해 할 수있는 일이 있습니까? ( 어쨌든 아주 긴 줄을 표시 할 때 왜 Emacs가 너무 느려 집니까?) 긴 줄을 제한하고 Emacs에게 아주 긴 줄을 표시하지 않는 것이 좋다고 말할 수 있습니까?



2
글쎄, 내 질문은 긴 줄 ​​자체를 표시하는 것이 아닙니다. 나는 이런 종류의 것을 처음부터 피할 수있는 방법을 알고 싶다. 그리고 이맥스 세션이 하나의 동적 버퍼에 헌신하기 위해 이맥스 세션을 잃는 것을 막을 수있는 방법에 관한 것입니다.
rekado

"글쎄, 내 질문은 긴 줄을 표시하는 것이 아니다"그렇다면 제목을 변경해야 할 수도 있습니다. 아마도 열등한 프로세스 출력을 필터링하고 특정 문자 수 후에 줄 바꿈을 추가하고 싶습니까?
nanny

실제로 이것은 긴 줄과는 거의 관련이 없습니다. yesansi-term예를 들어 비슷한 (하지만이 있다는 끔찍한) 효과를. 실제로는 emacs를 일시 중지시키는 텍스트의 양입니다.
PythonNut

버퍼에서의 텍스트 삽입은 매우 빠르며, 실제보다 느리게 표시되는 재표시 작업입니다. 솔직히 말해서 yesVTE 터미널 에뮬레이터에서 실행 하면 모든 CPU 코어가 최대가되므로 예제로 사용하지는 않습니다.
wasamasa

답변:


12

의견에서 이미 대답했듯이, Emacs는 긴 줄을 다시 표시하는 데 매우 느려지는 것은 잘 알려진 문제 입니다. 그것을 고치는 것은 매우 좋을 것이지만, 올바르게 뽑히려면 많은 생각이 필요합니다. 이 문서 의 섹션 6.3에 따라 어떻게 수행 할 수 있는지에 대한 아이디어가 있습니다 (기본적으로 현재 버퍼에 비주얼 라인 정보를 저장하고 공백 삽입, 속성 표시, 창 변경 등으로 업데이트 한 다음 해당 정보를 사용하십시오). 스캔을 항상 피하는 재표시 코드)) 그러나 C 내부 요소를 잘 이해하지 못합니다.

그래도 해결 방법이 있습니다. 가장 분명한 것은 디스플레이 관련 매개 변수를 조정하는 것입니다 (그래픽 Emacs 인스턴스에서 시각적 줄 잘림 활성화, 그래픽이 아닌 Emacs를 사용하여 자동으로 수행, Bidi 기능 비활성화 등) 및 파일 내용 전처리 덜 분명한 것은 파일을 실제로 사후 처리하는 것입니다. 실제로 줄을 잘라내거나 줄을 실제보다 짧게 표시하는 텍스트 속성을 추가하는 것입니다. 이것을 더 흥미로운 답변으로 바꾸기 위해 이전 옵션에 대한 추악한 해킹을 제시합니다.이 옵션은 comint파생 모드 에서만 작동 합니다.

(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)

이것은 my-comint-shorten-long-lines많은 행으로 구성 될 수있는 문자열을 취하고 정규 표현식의 힘을 사용하여 80 자 이상의 길이로 줄을 바꾸면 단축 된 버전으로 원래 텍스트를 표시하는 함수를 정의 합니다. 후크 인으로 사용되면 표시되기 전에 comint-preoutput-filter-functions모든 comint출력 을 필터링합니다 .

그러나 이러한 핵의 표현은 상당히 심각한 약점을 가지고 있습니다. 기본 글꼴 화가 진행되는 모드 (예 :) M-x ielm에서는 문자열의 일부인 줄을 행복하게 잘라 내고 다음 인용 부호까지 문자열로 모든 것을 글꼴 화합니다! 그것은 우리가 원하는 것이 아니며 좀 더 정규 표현식으로 고칠 수 있습니다 (그러나 아마도 파이썬과 같은 언어의 REPL 내부에서 깨질 것입니다). 우리가 그것을하는 동안, 단축 출력도 강조하자 :

(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)

조금 나아지지만 여전히 추악합니다. find /in 과 같은 결과물을 가리키면 M-x shell매력적이지 않습니다 (우리는 이상적으로 단축되지 않은 줄만을 표시하고 싶을 것입니다). 문자열 감지는 기껏해야 초보적이며 모든 것을 글꼴 화하는 대신 줄임표로 잘릴 수 있습니다. 게다가, 들어오는 텍스트가 배치로 바뀌지 않는다는 보장조차 없습니다. 이 모든 것은 임시 버퍼에서 처리 단계를 수행하기 위해 비명을 지르지 만 독자는 운동으로 (또는 잠재적 인 블로그 게시물로 저자는) 남겨 둘 것입니다.


4

파이썬과 마찬가지로 이와 마찬가지로 python-mode.el의 솔루션 ( https://launchpad.net/python-mode )은 comint-mode를 통하지 않고 직접 프로세스에 연결하는 것입니다.

start-process문자열 에 의존 하고 프로세스 전송 문자열

예를 들어 함수 py--start-fast-processpy--fast-send-string-intern

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.