• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
3  *
4  * This software is distributable under the BSD license. See the terms of the
5  * BSD license in the documentation provided with this software.
6  */
7 package jline;
8 
9 import java.io.*;
10 
11 /**
12  *  Representation of the input terminal for a platform. Handles
13  *  any initialization that the platform may need to perform
14  *  in order to allow the {@link ConsoleReader} to correctly handle
15  *  input.
16  *
17  *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
18  */
19 public abstract class Terminal implements ConsoleOperations {
20     private static Terminal term;
21 
22     /**
23      *  @see #setupTerminal
24      */
getTerminal()25     public static Terminal getTerminal() {
26         return setupTerminal();
27     }
28 
29     /**
30      *  Reset the current terminal to null.
31      */
resetTerminal()32     public static void resetTerminal() {
33         term = null;
34     }
35 
36     /**
37      *  <p>Configure and return the {@link Terminal} instance for the
38      *  current platform. This will initialize any system settings
39      *  that are required for the console to be able to handle
40      *  input correctly, such as setting tabtop, buffered input, and
41      *  character echo.</p>
42      *
43      *  <p>This class will use the Terminal implementation specified in the
44      *  <em>jline.terminal</em> system property, or, if it is unset, by
45      *  detecting the operating system from the <em>os.name</em>
46      *  system property and instantiating either the
47      *  {@link WindowsTerminalTest} or {@link UnixTerminal}.
48      *
49      *  @see #initializeTerminal
50      */
setupTerminal()51     public static synchronized Terminal setupTerminal() {
52         if (term != null) {
53             return term;
54         }
55 
56         final Terminal t;
57 
58         String os = System.getProperty("os.name").toLowerCase();
59         String termProp = System.getProperty("jline.terminal");
60 
61         if ((termProp != null) && (termProp.length() > 0)) {
62             try {
63                 t = (Terminal) Class.forName(termProp).newInstance();
64             } catch (Exception e) {
65                 throw (IllegalArgumentException) new IllegalArgumentException(e
66                     .toString()).fillInStackTrace();
67             }
68         } else if (os.indexOf("windows") != -1) {
69             t = new WindowsTerminal();
70         } else {
71             t = new UnixTerminal();
72         }
73 
74         try {
75             t.initializeTerminal();
76         } catch (Exception e) {
77             e.printStackTrace();
78 
79             return term = new UnsupportedTerminal();
80         }
81 
82         return term = t;
83     }
84 
85     /**
86      *  Returns true if the current console supports ANSI
87      *  codes.
88      */
isANSISupported()89     public boolean isANSISupported() {
90         return true;
91     }
92 
93     /**
94      *  Read a single character from the input stream. This might
95      *  enable a terminal implementation to better handle nuances of
96      *  the console.
97      */
readCharacter(final InputStream in)98     public int readCharacter(final InputStream in) throws IOException {
99         return in.read();
100     }
101 
102     /**
103      *  Reads a virtual key from the console. Typically, this will
104      *  just be the raw character that was entered, but in some cases,
105      *  multiple input keys will need to be translated into a single
106      *  virtual key.
107      *
108      *  @param  in  the InputStream to read from
109      *  @return  the virtual key (e.g., {@link ConsoleOperations#VK_UP})
110      */
readVirtualKey(InputStream in)111     public int readVirtualKey(InputStream in) throws IOException {
112         return readCharacter(in);
113     }
114 
115     /**
116      *  Initialize any system settings
117      *  that are required for the console to be able to handle
118      *  input correctly, such as setting tabtop, buffered input, and
119      *  character echo.
120      */
initializeTerminal()121     public abstract void initializeTerminal() throws Exception;
122 
123     /**
124      *  Returns the current width of the terminal (in characters)
125      */
getTerminalWidth()126     public abstract int getTerminalWidth();
127 
128     /**
129      *  Returns the current height of the terminal (in lines)
130      */
getTerminalHeight()131     public abstract int getTerminalHeight();
132 
133     /**
134      *  Returns true if this terminal is capable of initializing the
135      *  terminal to use jline.
136      */
isSupported()137     public abstract boolean isSupported();
138 
139     /**
140      *  Returns true if the terminal will echo all characters type.
141      */
getEcho()142     public abstract boolean getEcho();
143 
144     /**
145      *  Invokes before the console reads a line with the prompt and mask.
146      */
beforeReadLine(ConsoleReader reader, String prompt, Character mask)147     public void beforeReadLine(ConsoleReader reader, String prompt,
148                                Character mask) {
149     }
150 
151     /**
152      *  Invokes after the console reads a line with the prompt and mask.
153      */
afterReadLine(ConsoleReader reader, String prompt, Character mask)154     public void afterReadLine(ConsoleReader reader, String prompt,
155                               Character mask) {
156     }
157 
158     /**
159      *  Returns false if character echoing is disabled.
160      */
isEchoEnabled()161     public abstract boolean isEchoEnabled();
162 
163 
164     /**
165      *  Enable character echoing. This can be used to re-enable character
166      *  if the ConsoleReader is no longer being used.
167      */
enableEcho()168     public abstract void enableEcho();
169 
170 
171     /**
172      *  Disable character echoing. This can be used to manually re-enable
173      *  character if the ConsoleReader has been disabled.
174      */
disableEcho()175     public abstract void disableEcho();
176 
getDefaultBindings()177     public InputStream getDefaultBindings() {
178         // Mac bindings are slightly different from Unix/Linux.
179         // For instance, the Delete key behavior is different between them.
180         return Terminal.class.getResourceAsStream(
181                 System.getProperty("os.name").toLowerCase().startsWith("mac") ?
182                     "keybindings-mac.properties" : "keybindings.properties");
183     }
184 }
185