001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 */ 019package org.nuxeo.shell.swing; 020 021import javax.swing.text.BadLocationException; 022 023/** 024 * The last line in the console - where the user type the commands. Must be instantiated each time a new line is used. 025 * (after CRLF) 026 * 027 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 028 */ 029public class CmdLine { 030 031 protected int index; 032 033 protected int start; 034 035 protected String prompt; 036 037 protected int cmdStart; 038 039 protected Console console; 040 041 public CmdLine(Console console) { 042 try { 043 this.console = console; 044 this.index = console.getLineCount() - 1; 045 start = console.getLineStartOffset(index); 046 prompt = console.reader.getDefaultPrompt(); 047 cmdStart = start + prompt.length(); 048 } catch (Exception e) { 049 throw new RuntimeException(e); 050 } 051 } 052 053 public int getIndex() { 054 return index; 055 } 056 057 public int getStart() { 058 return start; 059 } 060 061 public int getCmdStart() { 062 return cmdStart; 063 } 064 065 public int getEnd() { 066 try { 067 return console.getLineEndOffset(index); 068 } catch (BadLocationException e) { 069 throw new RuntimeException(e); 070 } 071 } 072 073 public String getLineText() { 074 try { 075 return console.getDocument().getText(start, getEnd() - start); 076 } catch (BadLocationException e) { 077 throw new RuntimeException(e); 078 } 079 } 080 081 public String getPrompt() { 082 return prompt; 083 } 084 085 /** 086 * Get the caret position relative to the beginning of the command text (see getCmdStart()) 087 * 088 * @return 089 */ 090 public int getLocalCaretPosition() { 091 int cp = console.getCaretPosition() - cmdStart; 092 return cp < 0 ? 0 : cp; 093 } 094 095 public String getText() { 096 try { 097 return console.getDocument().getText(cmdStart, getEnd() - cmdStart); 098 } catch (BadLocationException e) { 099 throw new RuntimeException("Failed to get line text", e); 100 } 101 } 102 103 public void setText(String text) { 104 int end = getEnd(); 105 console.replaceRange(text, cmdStart, end); 106 console.setCaretPosition(console.getDocument().getLength()); 107 } 108 109 public void setTextFromCaret(String text) { 110 int end = getEnd(); 111 console.replaceRange(text, console.getCaretPosition(), end); 112 console.setCaretPosition(end); 113 } 114 115 public void write(String text) { 116 int cp = console.getCaretPosition(); 117 int end = getEnd(); 118 int len = text.length(); 119 if (cp < end) { 120 int e = cp + len; 121 if (e > end) { 122 console.replaceRange(text, cp, end); 123 } else { 124 console.replaceRange(text, cp, e); 125 } 126 } else { 127 console.insert(text, cp); 128 } 129 console.setCaretPosition(cp + len); 130 // console.repaint(); 131 } 132 133 public void sync() { 134 StringBuffer sb = console.reader.getCursorBuffer().getBuffer(); 135 sb.setLength(0); 136 sb.append(getText()); 137 console.reader.getCursorBuffer().cursor = getLocalCaretPosition(); 138 } 139 140 public void rsync() { 141 setText(console.reader.getCursorBuffer().getBuffer().toString()); 142 console.setCaretPosition(cmdStart + console.reader.getCursorBuffer().cursor); 143 } 144 145 public boolean canMoveCaret(int where) { 146 int cp = console.getCaretPosition() + where; 147 return cp >= cmdStart && cp <= getEnd(); 148 } 149 150 public int setCompletionWord(String word) { 151 int p = getLocalCaretPosition(); 152 String text = getText(); 153 Word w = getWord(text, p); 154 // replace w with word 155 int ws = cmdStart + w.index; 156 int we = ws + w.length(); 157 console.replaceRange(word, ws, we); 158 console.setCaretPosition(ws + word.length()); 159 return getLocalCaretPosition(); 160 } 161 162 /** 163 * Get the word from the command line which is near the given relative caret position. Used for completion. 164 * 165 * @param pos 166 * @return 167 */ 168 public Word getWord(String text, int pos) { 169 if (text.length() == 0) { 170 return new Word("", 0); 171 } 172 if (pos <= 0) { 173 // get next word 174 int i = text.indexOf(' '); 175 String w = i <= 0 ? "" : text.substring(0, i); 176 return new Word(w, 0); 177 } 178 // get the previous word. 179 int i = text.lastIndexOf(' ', pos); 180 if (i == -1) { 181 i = 0; 182 int e = text.indexOf(' '); 183 if (e == -1) { 184 return new Word(text, 0); 185 } else { 186 return new Word(text.substring(0, e), 0); 187 } 188 } else { 189 i++; 190 int e = text.indexOf(' ', i); 191 if (e == -1) { 192 return new Word(text.substring(i), i); 193 } else { 194 return new Word(text.substring(i, e), i); 195 } 196 } 197 } 198 199 static class Word { 200 public int index; 201 202 public String text; 203 204 public Word(String text, int index) { 205 this.text = text; 206 this.index = index; 207 } 208 209 public int length() { 210 return text.length(); 211 } 212 213 @Override 214 public String toString() { 215 return text + " [" + index + "]"; 216 } 217 } 218}