डेमॉन मोड: स्टार्टअप पर डिफर इंटरैक्टिव?


16

(ध्यान दें, इसके विपरीत शीर्षक, यह प्रश्न समान नहीं है कि डेमॉन मोड में कैसे शुरू करें और इंटरेक्टिव संवादों को दबाएं? जैसा कि सबमिटर द्वारा उस प्रश्न का "जवाब" दिया गया था, जो एक विशेष संकेत को प्रकट करने का कारण बन रहा था।)

मैं जानना चाहता हूं कि क्या एक सामान्य तरीका है जो emacs --daemonहमेशा एक मिनीबफ़र में प्रदर्शित एक प्रॉम्प्ट के उत्तर की प्रतीक्षा में लटकाए रखने से है जो अभी तक मौजूद है।

इन संकेतों का उत्तर देने के लिए किसी इमैक्यूलरेंट के साथ कनेक्ट करना असंभव है, क्योंकि सर्वर तब तक शुरू नहीं होता है जब तक एमएसीएस स्टार्टअप अनुक्रम को पूरा नहीं करता है। (इसका मतलब है, अगर आपके पास ALTERNATE_EDITOR खाली स्ट्रिंग पर सेट है, जो ऐसा बनाता है जो emacsclientएक सर्वर को एक नया डेमॉन शुरू नहीं कर सकता है, तो आप कई इमैक डैमों के साथ समाप्त हो सकते हैं जो सभी अटक गए और इंतजार कर रहे हैं।) मुझे killall emacsसमस्या को ठीक करना होगा और ठीक करना होगा। जारी रखने से पहले।

जब मैं इसे पहचानता हूं, तो मैं इसे पहचानने के साथ ही स्टार्टअप पर संकेत देने के लिए प्रत्येक चीज के साथ व्हेक-ए-मोल खेल सकता हूं (यह गैर-डेमॉन मोड में Emacs शुरू करके और यह पूछ रहा है कि क्या है), लेकिन यह एक समाधान नहीं है क्योंकि यह अगले डेमन को रोक नहीं सकता है एक नए कारण के लिए स्टार्टअप पर लटकने से।

एक उदाहरण देने के लिए: सिस्टम रीबूट या एमएसीएस क्रैश के बाद एक सामान्य कारण यह लटका होगा, जब पहली पोस्ट-रिबूट एमैक ने जानना चाहा कि क्या डिफॉल्ट एमएसीएस से लॉकफाइल्स चोरी करना ठीक था। मैं उस प्रॉम्प्ट को बनाने के लिए सलाह देकर उसे ठीक कर सकता था जो हमेशा बिना बातचीत के "हां" का जवाब देता था। लेकिन फिर, पिछले सत्र में सेव की गई फाइलों में से एक ट्रेंप फाइल थी जिसमें एक sudo या SSH पासवर्ड की आवश्यकता होती थी, इसलिए डेमन के पासवर्ड प्रॉम्प्ट पर प्रतीक्षा की जा रही थी। तो मैं ठीक करता हूं कि आपत्तिजनक फाइलों को हटाने के लिए सत्र फ़ाइल ( viया emacs -q!) को मैन्युअल रूप से संपादित करके - लेकिन यह अगली बार ऐसा होने से नहीं रखता है।

इसलिए, मैं स्टार्टअप पर अपने सत्र को स्वचालित रूप से लोड करना बंद कर सकता हूं और इसे एक कमांड में बदल सकता हूं, जिसे मुझे अपने पहले इमैकलिएंट से मैन्युअल रूप से निष्पादित करना होगा। लेकिन अगर यह पृष्ठभूमि में मेरे सत्र को लोड नहीं कर रहा है, तो जब तक मैं इसका उपयोग करने के लिए तैयार हो जाता हूं, तब तक डेमन का पूरा उद्देश्य खो जाता है!

तो मुझे क्या पसंद है:

  • (सर्वश्रेष्ठ) मिनीबफ़र को स्थगित करने का कोई तरीका तब तक संकेत देता है जब तक कि मैं एक इमोस्क्लिएंट को नहीं खोलता, जबकि अभी भी प्रारंभिक आरम्भ के बाकी को पूरा कर रहा हूँ।
  • (ठीक है) किसी भी तरह से सभी मिनीबफ़र प्रॉम्प्ट बनाने के लिए मैंने पहले से ही सलाह नहीं दी है, जैसा कि ऊपर वर्णित है, noजब तक कि कोई इमैक्शिएंट नहीं चल रहा है। मैं अपने ट्रम्प बफ़र्स के साथ रह सकता हूं ताकि यह ज्यादातर काम करता रहे।

क्या इन लक्ष्यों को प्राप्त करने का कोई तरीका है?


क्या इस प्रकार के मुद्दों को प्रोग्रामिक रूप से पुन: पेश करने का एक तरीका है ताकि समुदाय समस्या निवारण कर सके?
मेलियोरैटस

1
ठीक है, जैसा कि मैंने पहली पंक्ति में लिखा था, किसी दिए गए उदाहरण को ठीक करना काफी आसान है ... "डॉक्टर, यह दर्द होता है जब मैं ऐसा करता हूं ..." "फिर ऐसा मत करो।" मुद्दा सामान्य मामला है। लेकिन समस्या पैदा करने का एक सरल तरीका स्टार्टअप को डेस्कटॉप के माध्यम से पुनर्स्थापित करना है (read-desktop), फिर, चलने से पहले emacs --daemon, पूर्णांक को .emacs.desktop.lock (जहां उस फ़ाइल को रखना है, दुर्भाग्यवश, आपके कॉन्फ़िगरेशन पर निर्भर करता है, द्वारा एक फर्जी लॉक फ़ाइल बनाएं। , लेकिन संभवत: या तो आपका होमेडिर या ~ / .emacs.d /
ट्रे

1
उदाहरण के लिए, यह अक्सर उल्लेखित मामला है: emacs.stackexchange.com/questions/8147/… या emacs.stackexchange.com/questions/31621/… संदर्भ प्रदान कर सकता है।
ट्रे

यह बग संबंधित लगता है: बग # 13697 - यह बताने का एक तरीका कि क्या Emacs उपयोगकर्ता के साथ बातचीत कर सकते हैं , लेकिन किसी ने भी उस पर काम नहीं किया है, जहां तक ​​मुझे पता है।
1

@npostavs लिंक के लिए धन्यवाद- मैंने बग को एनोटेट किया है, हालांकि यह गलत शुरुआत हुई है कि मैंने इसे हटाने से पहले यहां टिप्पणी की थी (हटाए जाने के बाद)!
ट्रे

जवाबों:


2

हमारी चर्चा ने साफ़ किया कि आपके पास कोई भी एक्स-सर्वर नहीं है जो आपके लिए मेरा पहला समाधान बेकार कर रहा है।

निम्नलिखित में मैं एक दूसरा समाधान प्रस्तुत करता हूं जो पाठ टर्मिनल फ्रेम के साथ काम करता है।

जब आपके इनिशियलाइज़ेशन के लिए उपयोगकर्ता इनपुट की आवश्यकता होती है, तो avoid-initial-terminalEmacs के साथ सलाह दी जाती है, जब तक कि आप टेक्स्ट टर्मिनल फ्रेम नहीं खोलते। प्रॉम्प्ट उस फ़्रेम के मिनीबफ़र में दिखाई देता है और आप अपनी इंटरैक्टिव प्रतिक्रिया दे सकते हैं।

कोड से संबंधित इन्फोस को कोड में टिप्पणी के रूप में दिया जाता है। TODOविवरण के साथ मार्कर हैं जो आपको दिखाते हैं कि आपको अपना कॉन्फ़िगरेशन कहां डालना है। वर्तमान में वहाँ परीक्षण प्रपत्र हैं जो कोड को मान्य करते हैं।

;; TODO: Do here configure the server if needed.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Startup the server:
;; Analysis of read_from_minibuffer in src/minibuf.c and daemon_type in src/emacs.c
;; shows that daemon-initialized must have run before read-passwd / read-string
;; works on frames. Before it only works on stdin & stdout.
(server-start) ;;< early start
(let ((after-init-time before-init-time))
  (daemon-initialized)) ;; Finalize the daemon, 

(advice-add 'daemon-initialized :override #'ignore)
;;< Ignore `daemon-initialized' after initialization. It may only run once!
;; Now the background emacs is no longer marked as daemon. It just runs the server.

(defun prevent-server-start (&rest _ignore)
  "Prevent starting a server one time after `server-start' has been advised with this."
  (advice-remove 'server-start #'prevent-server-start))

(advice-add 'server-start :override #'prevent-server-start)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Prepare waiting for a real terminal frame when user input is required:

(defun avoid-initial-terminal (fun &rest args)
  "Wait until we are no longer on \"intial-terminal\".
Afterwards run `fun' with frame on the other terminal selected."
  (message "Avoiding initial terminal. Terminal: %S" (get-device-terminal nil))
  (while (string-equal
      (terminal-name (get-device-terminal nil))
      "initial_terminal")
    (sleep-for 1))
  ;; (message "Selected frame: %S; Running %S with %S." (selected-frame) fun args)
  (apply fun args))

(advice-add 'read-string :around #'avoid-initial-terminal)

(advice-add 'read-passwd :around #'avoid-initial-terminal)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; TODO: Your initialization that is not daemon related
;; and may require user input:

;; Currently this is just a test.
(read-passwd "Passwd: ")

(read-string "String: ")

(y-or-n-p "y-or-n query")

टेस्ट: एमएसीएस-संस्करण: 26.1

1) भागो emacs --daemon एक कंसोल पर ।

2) emacsclient --ttyदूसरे कंसोल पर चलाएं । आपसे वहां पासवर्ड और स्ट्रिंग मांगी जाती है। बाद में आपको y-or-np क्वेरी का जवाब देना होगा।


3

ठीक वही नहीं जो आप पूछ रहे हैं, लेकिन शायद आपकी मूल समस्या का हल:

मैं जानना चाहूंगा कि क्या कोई सामान्य तरीका है कि emacs को रखें - हमेशा के लिए लटकने से एक minibuffer में प्रदर्शित एक प्रॉम्प्ट के उत्तर की प्रतीक्षा में जो अभी तक मौजूद नहीं है।

यदि डेमॉन आपको इसके स्टार्टअप-चरण में उठने वाले सवालों के जवाब के लिए एक ग्राफिकल फ्रेम देता है, तो आप कहीं अटकते नहीं हैं।

नीचे दिया गया कोड एक सामान्य सलाह को परिभाषित करता है my-with-initial-frameजो पहले उपलब्ध डिस्प्ले पर एक फ्रेम खोलता है (जैसे,:0.0 ) ।

उस सलाह को आसानी से जोड़ा जा सकता है जैसे कमांड को क्वेरी करना y-or-n-pयाread-passwd जैसा कि नीचे दिखाया गया है।

बस एक फ्रेम खोलने से आपको उपयोगकर्ता इंटरफ़ेस पर प्रश्नों का उत्तर देने के लिए काफी संभावना मिल सकती है। एक के लिए एक संवाद बॉक्स का उपयोग भी कर सकता हैy-or-n-p लेकिन इसके लिए विशिष्ट क्वेरी कमांड के लिए विशेष समाधान की आवश्यकता होगी। मैं उससे बचना चाहता था।

यदि आप अपने इनिट फ़ाइल में उस कोड को आज़माते हैं, तो सुनिश्चित करें कि यह पहली बात है।

(when (daemonp)

  (defun my-with-initial-frame (&rest _)
    "Ensure a frame on display :0.0 and ignore args."
    (let* ((display-list (x-display-list))
           (display-re (and display-list (regexp-opt display-list)))
           (term (and display-re (cl-some (lambda (term) (and (string-match display-re (terminal-name term)) term)) (terminal-list))))
           (frame (and term (cl-some (lambda (frame) (and (frame-live-p frame) frame)) (frames-on-display-list term)))))
      (select-frame (or frame (make-frame-on-display (getenv "DISPLAY"))))))

  (message "Advising querying functions with `my-with-initial-frame'.")
  (advice-add 'y-or-n-p :before #'my-with-initial-frame)
  (advice-add 'read-passwd :before #'my-with-initial-frame))

परीक्षा:

मान्यताओं:

एक चल रहा है जो कार्यक्रमों के माध्यम से कनेक्ट कर सकते हैं xserver है DISPLAY पर्यावरण चर के ।

एक्सटर्म पर इनपुट:

emacs --daemon

emacsclient --eval '(y-or-n-p "A")'

y-or-n-pक्वेरी प्रॉम्प्ट के साथ एक फ़्रेम खोलता है A (y or n)। उस प्रश्न का उत्तर दें और पुनः प्रयास करें:

emacsclient --eval '(y-or-n-p "B")'

B (y or n)एक ही फ्रेम में शीघ्रता के साथ नई क्वेरी । उस फ्रेम को बंद करें, जैसे, साथ C-x 5 0और फिर से प्रयास करें:

emacsclient --eval '(y-or-n-p "C")'

क्वेरी प्रॉम्प्ट के साथ एक नया फ़्रेम खुलता है C (y or n)

पासवर्ड इनपुट के लिए भी यही काम करता है।


@ मुझे अपने कोड के साथ कुछ समस्या थी (वास्तव में परीक्षण के साथ)। एक्स-सर्वर शुरू करने से पहली बार काम नहीं किया। मैंने शुरू में ध्यान नहीं दिया क्योंकि मैंने डेमॉन को फिर से शुरू नहीं किया। मैंने अब उसे ठीक किया। कृपया फिर से परीक्षण करें। धन्यवाद।
तोबियास

मेरे लिनक्स वर्चुअल में ग्राफिकल टर्मिनल संलग्न नहीं है, इसलिए मैं नहीं चला सकता xterm। इसके अलावा, मुझे नहीं लगता कि यह समाधान उन लोगों के लिए काम कर सकता है, जो अगर आपके पास स्टार्टअप पर चलने के लिए डेमॉन स्थापित है, तो यह लॉगिन स्क्रीन के शीर्ष पर एक फ्रेम खोलने की कोशिश करेगा, जिसकी अनुमति नहीं है, इसलिए यह दुर्घटनाओं।
ट्रे

टोबियास, क्षमा याचना करता है, अगर ऊपर से आवाज आती है - मैंने अपने फोन पर जवाब दिया और खुद को छोटा कर लिया, तो मुझे विस्तृत करने का प्रयास करें: एकमात्र फायदा मैं यह देख सकता हूं कि server-startस्टार्टअप के अंत में डेमॉन का उपयोग करने और न चलाने का आप क्या वर्णन करते हैं इसके बजाय, यदि आप एक स्वच्छ स्टार्टअप के लिए होते हैं, तो आपको इंतजार नहीं करना पड़ेगा। लेकिन ... आपको इंतजार करना होगा, क्योंकि जब तक मुझे गलतफहमी नहीं होती है, तब तक आप अपने सिस्टम लॉगिन स्क्रिप्ट में Emacs डेमन को शुरू करने के लिए कार्य नहीं डाल सकते हैं क्योंकि GUI तब उपलब्ध नहीं होगा। (और मेरी तरह एक मामले में, यह बाद में, कभी भी नहीं होगा।)
ट्रे

@ क्या आप किसी चैट में शामिल हो सकते हैं ?
तोबिस

1

मुझे लगता है कि प्रॉम्प्ट्स को स्थगित करना सामान्य रूप से मुश्किल होने वाला है, लेकिन Emacs को बदलना काफी आसान होना चाहिए ताकि ऐसे प्रॉम्प्ट तुरंत एक त्रुटि का संकेत दें।

इतना ही नहीं, लेकिन अगर आप बहुत सारे जिमनास्टिक के बिना उन संकेतों का जवाब नहीं दे सकते हैं, तो मुझे लगता है कि यह एक बग के रूप में योग्य है, इसलिए मैं आपको इसके लिए एक बग रिपोर्ट प्रस्तुत करने की सलाह दूंगा।


मुझे लगता है कि मुझे थोड़ा और विस्तार चाहिए। उपरोक्त टिप्पणी के लिए टिप्पणी में उल्लिखित डेस्कटॉप सेव-फाइल लॉक पर विचार करें। किसी विशेष रूप से "डेस्कटॉप" का जिक्र किए बिनाWarning: desktop file appears to be in use by PID xxx. Using it may cause conflicts. Use it anyway? (y or n) , किसी को प्रॉम्प्ट को त्रुटि में बदलने के बारे में कैसे जाना जाएगा (क्योंकि इस तरह, नौसिखिया होने के नाते, अजीब-ए-मोल होता है)?
ट्रे

स्टीफन, वहाँ भी एक मुद्दा है जो मुझे परेशान नहीं करता है क्योंकि मैं इस तरह से Emacs डेमॉन नहीं चलाता हूं, लेकिन आम तौर पर उपयोगी उत्तर देने के लिए पते की आवश्यकता हो सकती है: गलत तरीके से बाहर निकलने से Emacs सिस्टमड या अन्य वॉचडॉग के माध्यम से फिर से शुरू होगा। एक पाश में। लेकिन त्रुटियों को नजरअंदाज करते हुए और पहले लॉग-इन करने *Messages*से संभवत: पहले क्लाइंट पर अपर्याप्त हेड-अप कनेक्ट होता है कि कुछ गंभीर रूप से जागृत हो सकता है और उपयोगकर्ता को किसी भी राज्य के संचालन का प्रयास करने से पहले तत्काल ध्यान देने की आवश्यकता है।
ट्रे

(उन लोगों के लिए स्पष्ट करने के लिए जो डेमॉन का उपयोग नहीं करते हैं - यदि आप इसे मैन्युअल रूप से शुरू करते हैं, या तो रिक्त स्ट्रिंग पर सेट पर्यावरण चर के साथ emacs --daemonशुरू करके , आप आउटपुट को देखेंगे जो टर्मिनल में डेमॉन तक गूंज जाता है। इनिशियलाइज़ेशन पूरा करता है और Emacs तैयार हो जाता है। लेकिन कई Emacs ने सिस्टम स्टार्टअप या लॉग इन समय पर डेमॉन शुरू कर दिया है, और आउटपुट या तो लॉग इन किया जाता है या फेंक दिया जाता है।emacsclientALTERNATE_EDITOR*Messages*
Trey

1
@ ट्रे: त्रुटि सिग्नलिंग कार्य desktopमें नहीं होना चाहिए y-or-n-p(या अभी तक कम)। स्टार्टअप के दौरान होने वाली त्रुटियों को प्रदर्शित करने में देरी करने के लिए हमारे पास कुछ तंत्र हैं, इसलिए हम उनका उपयोग तब कर सकते हैं, जब उन्हें प्रदर्शित करने के लिए पहली emacsclient डेमॉन से कनेक्ट हो।
स्टीफन

किसी भी मामले में, हालांकि, अधिकांश उपयोगकर्ता मना नहीं *Messages*करते हैं- और जब थोड़ी-सी उपयोग की जाने वाली *Warnings*प्रणाली बफर को एक विंडो पॉप अप करती है यदि चेतावनी उत्पन्न होने पर एक सक्रिय फ्रेम मौजूद होता है, तो इस मामले में, कोई फ्रेम मौजूद नहीं है, और यह doesn चेतावनी के मुद्दे के बाद पहले खाली होने तक पॉप-अप को हटाना आसान नहीं है। यदि ऐसा किया जा सकता है, तो yes-or-no-pइसके बजाय पूर्व-ग्राहक चेतावनी देने का आपका सुझाव काफी आदर्श होगा। (मुझे संदेह है कि उपयोगकर्ता *Messages*स्टार्टअप पर कंघी करते हैं!)
ट्रे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.