অবিচ্ছিন্নভাবে একটি কমেন্ট প্রক্রিয়া থেকে আউটপুট জন্য অপেক্ষা করুন


12

প্রথমত, একটি দাবি অস্বীকার। আমি এটি বহুবার গবেষণা করেছি এবং আমি নিশ্চিত যে আমি উত্তরটি ইতিমধ্যে এক বা অন্যভাবে খুঁজে পেয়েছি তবে আমি এটি বুঝতে পারি না।

আমার সমস্যা নিম্নলিখিত:

  • আমার একটি প্রক্রিয়া কমেন্টের মাধ্যমে চলছে
  • আমি ইনপুটটির একটি লাইন প্রেরণ করতে, আউটপুট ক্যাপচার করতে এবং এটি শেষ হয়ে গেলে দেখতে চাই (যখন আউটপুটটির শেষ লাইনটি একটি প্রম্পটের জন্য রিজেক্সের সাথে মেলে)
  • প্রক্রিয়াটি আউটপুট প্রেরণ শেষ করলেই আমি অন্য একটি লাইন ইনপুট (উদাহরণস্বরূপ) প্রেরণ করতে চাই।

কিছুটা ব্যাকগ্রাউন্ডের জন্য, এমন কোনও প্রোগ্রামের সাথে ইন্টারঅ্যাকশন প্রয়োগকারী একটি মোড মোডের কথা চিন্তা করুন, যা নির্বিচারে দীর্ঘ সময় ধরে নির্বিচারে আউটপুট দিতে পারে। এটি একটি অস্বাভাবিক পরিস্থিতি হওয়া উচিত না, তাই না? ঠিক আছে, আমার যে অংশটি ইনপুটগুলির মধ্যে অপেক্ষা করতে হবে এটি অস্বাভাবিক, তবে সামগ্রিকভাবে ইনপুটটি প্রেরণের কয়েকটি সুবিধা রয়েছে:

  • আউটপুট বাফারটি সুন্দরভাবে ফর্ম্যাট করা হয়েছে: ইনপুট আউটপুট ইনপুট আউটপুট ...
  • আরও গুরুত্বপূর্ণ বিষয়, কোনও প্রক্রিয়ায় প্রচুর পাঠ্য প্রেরণ করার সময়, পাঠ্যটি টুকরো টুকরো করে কেটে দেওয়া হয় এবং প্রক্রিয়া দ্বারা টুকরোগুলি পেস্ট করা হয়; কাটিং পয়েন্টগুলি স্বেচ্ছাচারিত হয় এবং এটি কখনও কখনও অবৈধ ইনপুট করে তোলে (উদাহরণস্বরূপ, আমার প্রক্রিয়াটি সনাক্তকারীটির মাঝখানে কোনও ইনপুট কাট সঠিকভাবে পেস্ট করবে না)

যাই হোক, অস্বাভাবিক না, এটি সক্রিয় আউট এটি করা হয় জটিল। এই মুহুর্তে, আমি এর লাইনে কিছু ব্যবহার করছি

(defun mymode--wait-for-output ()
  (let ((buffer (mymode-get-buffer)))
    (with-current-buffer buffer
      (goto-char (point-max))
      (forward-line 0)
      (while (not (mymode-looking-at-prompt))
        (accept-process-output nil 0.001)
        (redisplay)
        (goto-char (point-max))
        (forward-line 0))
      (end-of-line))))

এবং আমি প্রতিবার ইনপুট লাইন প্রেরণের পরে এবং পরবর্তীটি পাঠানোর আগে এটি কল করি। ঠিক আছে ... এটি কাজ করে, এটি ইতিমধ্যে কিছু।

তবে এটি আউটপুটটির জন্য অপেক্ষা করার সময় ইমাসকে ঝুলিয়ে রাখে। কারণটি সুস্পষ্ট, এবং আমি অনুভব করেছি যে আমি যদি লুপটিতে কোনও ধরণের অ্যাসিনক্রোনাস sleep-for(উদাহরণস্বরূপ 1s) অন্তর্ভুক্ত করি তবে এটি আউটপুটকে 1 এস দ্বারা বিলম্বিত করবে, তবে ঝুলন্ত দমন করবে। এটি বাদে মনে হয় যে এই ধরণের অ্যাসিনক্রোনাসের sleep-for অস্তিত্ব নেই

নাকি তা করে? আরও সাধারণভাবে, ইমাস সহ এটি অর্জনের কোনও মূ ?় উপায় আছে কি? অন্য কথায়:

কীভাবে কোনও প্রক্রিয়াতে ইনপুট প্রেরণ করা যায়, আউটপুটটির জন্য অপেক্ষা করুন, তারপরে আরও ইনপুট, সংশ্লেষক্রমে প্রেরণ করবেন?

আশেপাশে অনুসন্ধান করার সময় (সম্পর্কিত প্রশ্নগুলি দেখুন), আমি মূলত সেন্ডিনেলগুলির উল্লেখ দেখেছি (তবে আমার মনে হয় না যে এটি আমার ক্ষেত্রে প্রযোজ্য, যেহেতু প্রক্রিয়াটি শেষ হয় না) এবং কিছু কমেন্ট হুক (তবে কি তবে আমার উচিত?) হুক বাফার-লোকাল করুন, আমার "অবশিষ্ট রেখাগুলি মূল্যায়ন করুন" একটি ফাংশনে পরিণত করুন, এই ফাংশনটি হুকটিতে যুক্ত করুন এবং পরে হুকটি পরিষ্কার করুন? যা সত্যিই নোংরা শোনায়, তাই না?)।

আমি নিজেকে দুঃখিত করে দিচ্ছি না, বা যদি সত্যিই কোথাও একটি সুস্পষ্ট উত্তর পাওয়া যায় তবে আমি প্রক্রিয়া মিথস্ক্রিয়তার সমস্ত জটিলতার দ্বারা সত্যই বিভ্রান্ত হয়ে পড়েছি বলে আমি দুঃখিত।

যদি প্রয়োজন হয় তবে আমি এটি সমস্ত কার্যকরী উদাহরণ হিসাবে তৈরি করতে পারি, তবে আমি আশঙ্কা করছি যে এটি আমার আগে পাওয়া সমস্তগুলির মতো আরও একটি "নির্দিষ্ট প্রক্রিয়া উত্তর সহ একটি নির্দিষ্ট প্রক্রিয়া প্রশ্ন" তৈরি করবে।

এসও সম্পর্কিত কিছু সম্পর্কিত প্রশ্ন:


@nicael সম্পর্কিত লিঙ্কগুলি সম্পর্কে কি ভুল?
টি। ভেরন

তবে এগুলি অন্তর্ভুক্ত করার জন্য আপনার কী দরকার?
নিকেল

2
ঠিক আছে, আমি এগুলি সম্পর্কিত প্রশ্নগুলির মতো পেয়েছি, যদিও উত্তরগুলি আমাকে সহায়তা না করে। যদি কেউ আমাকে সহায়তা করতে চান, সম্ভবত তারা আমার চেয়ে এই বিষয়টির আরও গভীর জ্ঞান রাখবেন, তবে সম্ভবত তাদের আগেও গবেষণা করার প্রয়োজন হবে। এই ক্ষেত্রে, প্রশ্নগুলি তাদের কিছু সূচনা পয়েন্ট দেয়। এবং তদ্ব্যতীত, যদি কোনও দিন এই পৃষ্ঠায় কেউ অবতরণ করেন তবে আমি যে লিঙ্কটি করেছি তার সাথে আরও সমস্যার সাথে, তাদের উপযুক্ত প্রশ্নের শর্টকাট থাকবে ut
টি। ভেরন

@ এনিকায়েল (প্রথম পোস্টে পিং করতে ভুলে গেছেন, দুঃখিত) লিঙ্কগুলি এমএক্স.এসএক্স থেকে নয় এমন সমস্যা কি?
টি। ভেরন

ঠিক আছে. আপনি আপনার পুনর্বিবেচনায় ফিরে যেতে পারেন, এটি আপনার পোস্ট।
নিকেল

উত্তর:


19

প্রথমত, আপনি accept-process-outputযদি অ্যাসিক্রোনাস প্রসেসিং চান তবে আপনার ব্যবহার করা উচিত নয় । ইমাকস প্রতিটি সময় আউটপুট গ্রহণ করবে যখন এটি ব্যবহারকারী ইনপুটটির জন্য অপেক্ষা করছে।

যাওয়ার সঠিক উপায় হ'ল আউটপুট আটকানোতে ফিল্টার ফাংশন ব্যবহার করা। আপনার কাছে এখনও পাঠানোর জন্য লাইন রয়েছে কিনা তার উপর নির্ভর করে আপনাকে ফিল্টার (গুলি) তৈরি বা মুছতে হবে না। পরিবর্তে, আপনি সাধারণত প্রক্রিয়াটির আজীবন একক ফিল্টার ঘোষণা করবেন এবং রাষ্ট্রটি ট্র্যাক করতে এবং প্রয়োজন অনুসারে বিভিন্ন কাজ করতে বাফার-স্থানীয় ভেরিয়েবলগুলি ব্যবহার করবেন।

নিম্ন-স্তরের ইন্টারফেস

ফিল্টার ফাংশন হ'ল আপনি যা সন্ধান করছেন। ফিল্টার ফাংশনগুলি হ'ল সেন্ডিনেলগুলি সমাপ্ত হওয়ার ফলাফল।

(defun mymode--output-filter (process string)
  (let ((buffer (process-buffer process)))
    (when (buffer-live-p buffer)
      (with-current-buffer buffer
        (goto-char (point-max))
        (forward-line 0)
        (when (mymode-looking-at-prompt)
          (do-something)
          (goto-char (point-max)))))))

ম্যানুয়াল বা অনেক উদাহরণ যে (এ গিয়ে Emacs সঙ্গে আসা তাকান grepজন্য process-filter.elফাইল)।

এর সাথে আপনার ফিল্টার ফাংশনটি নিবন্ধ করুন

(set-process-filter 'mymode--output-filter)

কমেন্ট ইন্টারফেস

কমেন্ট একটি ফিল্টার ফাংশন সংজ্ঞায়িত করে যা কিছু কাজ করে:

  • প্রক্রিয়া আউটপুট থাকা উচিত বাফারে স্যুইচ করুন।
  • comint-preoutput-filter-functionsএকটি যুক্তি হিসাবে নতুন পাঠ্য পাস করে তালিকায় ফাংশনগুলি চালান ।
  • উপর ভিত্তি করে কিছু অ্যাডহক ডুপ্লিকেট প্রম্পট নির্মূলকরণ সম্পাদন করুন comint-prompt-regexp
  • বাফারের শেষে প্রক্রিয়া আউটপুট sertোকান
  • comint-output-filter-functionsএকটি যুক্তি হিসাবে নতুন পাঠ্য পাস করে তালিকায় ফাংশনগুলি চালান ।

আপনার মোড কমেন্টের উপর ভিত্তি করে দেওয়া হয়েছে, আপনার ফিল্টারটি এতে নিবন্ধিত করা উচিত comint-output-filter-functionscomint-prompt-regexpআপনার প্রম্পটের সাথে মেলে সেট করা উচিত । আমি মনে করি না কমিন্টের একটি সম্পূর্ণ আউটপুট অংশ সনাক্ত করার জন্য একটি বিল্ট-ইন সুবিধা আছে (অর্থাত্ দুটি প্রম্পটের মধ্যে), তবে এটি সাহায্য করতে পারে। comint-last-input-endশেষ ইনপুট অংশের শেষে মার্কার সেট করা আছে। শেষ প্রম্পটের সমাপ্তির পরে আপনার একটি নতুন আউটপুট খণ্ড রয়েছে comint-last-input-end। শেষ প্রম্পটের শেষটি কীভাবে পাওয়া যায় তা ইমাসের সংস্করণটির উপর নির্ভর করে:

  • 24.3 অবধি, ওভারলেটি comint-last-prompt-overlayসর্বশেষ প্রম্পটটি ছড়িয়ে দেয়।
  • 24.4 থেকে, ভেরিয়েবলটিতে comint-last-promptশেষ প্রম্পটের শুরু এবং শেষের দিকে চিহ্নিতকারী রয়েছে।
(defun mymode--comint-output-filter (string)
  (let ((start (marker-position comint-last-input-end))
        (end (if (boundp 'comint-last-prompt-overlay)
                 (and comint-last-prompt-overlay (overlay-start comint-last-prompt-overlay))
               (and comint-last-prompt (cdr comint-last-prompt))))
  (when (and start end (< start end))
    (let ((new-output-chunk (buffer-substring-no-properties start end)))
      ...)))

প্রসেসটি input ইনপুট প্রাপ্তি, উত্সাহিত আউটপুট, ডিসপ্লে প্রম্পট than ব্যতীত অন্য ক্রম অনুসারে আউটপুট নির্গত হওয়ার ক্ষেত্রে আপনি সুরক্ষাগুলি যুক্ত করতে চাইতে পারেন}


ভেরিয়েবল কমেন্ট-লাস্ট-প্রম্পট-ওভারলে কমেন্ট.এলে ইমাস 25-এ সংজ্ঞায়িত করা হবে বলে মনে হয় না। এটা অন্য কোথাও থেকে এসেছে?
জন কিচিন

@ জনকিচিন কমেন্টের সেই অংশটি ২৪.৪ এ পরিবর্তিত হয়েছে, আমি আমার উত্তরটি ২৪.৩ এর জন্য লিখেছি। আমি 24-পরবর্তী পোস্ট পদ্ধতি যুক্ত করেছি।
গিলস 'দুষ্ট হওয়া বন্ধ করুন'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.