2009-06-26 14 views
7

के साथ टर्मिनल कर्सर को चालू करने के लिए टर्मिनल कर्सर को लौटाना मैं एक फ़िल्टर (एक टर्मिनल आउटपुट के लिए निर्धारित पाइप में) लिख रहा हूं जिसे कभी-कभी एक पंक्ति को "ओवरराइट" करने की आवश्यकता होती है। यह \n तक पहुंचने तक विशेष व्यवहार का आह्वान करते हुए, चरित्र-दर-चरित्र को stdout करने के लिए stdin पास करके काम करता है। मेरी समस्या यह बताती है कि लाइन की शुरुआत में कैसे वापसी करें।रैपिंग सक्षम

पहली बात मैंने सोचा था कि \r या एएनएसआई अनुक्रम \033[1G का उपयोग कर रहा था। हालांकि, अगर लाइन टर्मिनल पर लपेटने के लिए काफी लंबा था (और इसलिए इसे स्क्रॉल करने के कारण), तो यह केवल कर्सर को वर्तमान भौतिक लाइन पर ले जायेगा।

मेरा दूसरा विचार लाइन की लंबाई (पिछले \n के बाद से पारित वर्णों की संख्या) को ट्रैक करना था, और फिर कई बार \b गूंजना था। हालांकि, यह गलत हो जाता है यदि रेखा में नियंत्रण वर्ण या भागने के अनुक्रम होते हैं (और संभवतः यूनिकोड?)।

सभी विशेष अनुक्रमों की खोज करने और मेरे चरित्र गणना को समायोजित करने के लिए इसका उपयोग करने से कम, क्या यह हासिल करने का एक आसान तरीका है?

उत्तर

0

आप एक सरल ioctl साथ टर्मिनल आयाम को क्वेरी कर सकते हैं:

#include <sys/types.h> 
#include <sys/ioctl.h> 

// ... 

struct winsize ws; 
ioctl(1, TIOCGWINSZ, &ws); 

// ws.ws_col, ws.ws_row should now contain terminal dimensions 

इस तरह आप मुद्रण लाइन के अंत परे कुछ भी रोका जा सकता है और केवल \r विधि का उपयोग करें। terminfo डेटाबेस में save_cursor और restore_cursor स्ट्रिंग क्षमताओं के लिए

+0

सुझाव के लिए धन्यवाद! दुर्भाग्यवश कुछ कारण हैं कि मुझे नहीं लगता कि यह मेरे लिए काम करेगा: * मुझे अभी भी पता लगाना होगा कि किनारे के करीब मैं हूं * मैं आखिरी बात नहीं कर सकता पाइपलाइन संदर्भ के लिए; मेरा फ़िल्टर पैटर्न से मेल खाने वाला है, और रंगीन भागने के दृश्यों से घिरे मिलान करने वाले तारों को "पुनः लिखना" है। मैं 'fgets() 'का उपयोग नहीं कर सकता और एक समय में पूरे तारों पर काम नहीं कर सकता, क्योंकि मेरा कुछ इनपुट" गतिशील "आउटपुट (उदाहरण के लिए एक बढ़ती प्रगति स्थिति) उत्पन्न करेगा जो थोड़ी देर के लिए \ n' आउटपुट नहीं करता है। –

0
 
$ cat >test.sh <<'EOF' 
> #!/bin/sh 
> tput sc 
> echo 'Here is a really long multi-line string: .............................................................................................' 
> tput rc 
> echo 'I went back and overwrote some stuff!!!!' 
> echo 
> EOF 
$ sh test.sh 
I went back and overwrote some stuff!!!! ....................................... 
...................................................... 

देखो।

+0

मेरी समझ यह है कि आरसी और एससी कर्सर के * भौतिक * स्थान को सहेजता है (\ 033 [s और \ 033 [u) के समतुल्य। यदि लाइन-रैप के कारण टर्मिनल स्क्रॉल की पूरी सामग्री, स्ट्रिंग की शुरुआत अब एक ही भौतिक स्थिति पर नहीं है। (कम से कम, यह व्यवहार मैं xterm में देखता हूं।) –

+0

आह, ऐसा लगता है कि मेरे टर्मिनल में भी ऐसा लगता है। ओह ... – ephemient

4

भले ही एक "जादू अनुक्रम" था, जब एक कंसोल पर लिखा गया हो, तो आखिरी लिखित रेखा को विश्वसनीय रूप से मिटाना होगा, फिर भी आपको आउटपुट पर लाइन और अनुक्रम मिलेगा (हालांकि कंसोल पर छुपा हुआ है)। सोचें कि क्या होगा यदि किसी ने फ़ाइल को आउटपुट लिखा हो, या पाइप को अन्य फ़िल्टरों में पास कर दिया हो? क्या वे इस तरह के इनपुट को संभालने के बारे में जानेंगे? और मुझे मत बताओ कि आप सीधे कंसोल से कहीं और लिखने की संभावना से इंकार करते हैं। जल्द या बाद में, कोई आउटपुट रीडायरेक्ट करना चाहता है - शायद आप भी!

ऐसा करने का सही तरीका स्मृति में प्रत्येक पंक्ति को बफर करना है क्योंकि यह संसाधित हो रहा है, और फिर यह तय करना है कि इसे आउटपुट करना है या नहीं। इस के आसपास वास्तव में कोई रास्ता नहीं है।

+0

वास्तव में, यह मेरा मूल समाधान था। ब्रेक होने वाली एकमात्र जगह एक प्रगति प्रतिशत जैसी चीजों के लिए है जो समय के साथ बढ़ती है (\ b के साथ ओवरराइटिंग), जहां कई सेकंड या मिनट के लिए \ n नहीं है, इसलिए काफी अवधि के लिए ब्लॉक पर fgets() और इतने पर।संयोग से, मैंने संभावना को छूट दी है कि मेरा फ़िल्टर पाइपलाइन में आखिरी चीज नहीं है (मैंने पहले की टिप्पणी में जो कहा था उसके बावजूद), क्योंकि कंसोल आउटपुट को सुंदर बनाने के लिए टूल के अलावा इसे इस्तेमाल करने का कोई कारण नहीं है! –

+0

पाइप में आखिरी वस्तु होने के बारे में एक त्वरित टिप्पणी: क्या आप यह सुनिश्चित नहीं कर सकते कि stdout टर्मिनल पर जाता है, जैसा कि 'ls' करता है? –

संबंधित मुद्दे