1 21 22 package org.armedbear.j; 23 24 import java.awt.AWTEvent ; 25 import java.awt.event.KeyEvent ; 26 import java.awt.event.MouseEvent ; 27 import java.util.List ; 28 29 public final class DiffMode extends AbstractMode implements Constants, Mode 30 { 31 private static final DiffMode mode = new DiffMode(); 32 33 private DiffMode() 34 { 35 super(DIFF_MODE, DIFF_MODE_NAME); 36 } 37 38 public static final DiffMode getMode() 39 { 40 return mode; 41 } 42 43 public Formatter getFormatter(Buffer buffer) 44 { 45 return new DiffFormatter(buffer); 46 } 47 48 protected void setKeyMapDefaults( KeyMap km ) 49 { 50 km.mapKey(KeyEvent.VK_ENTER, 0, "diffGotoFile"); 51 km.mapKey(KeyEvent.VK_G, CTRL_MASK | SHIFT_MASK, "diffGotoFile"); 52 km.mapKey(VK_DOUBLE_MOUSE_1, 0, "diffGotoFile"); 53 km.mapKey(VK_MOUSE_2, 0, "diffGotoFile"); 54 } 55 56 public static void diff() 57 { 58 final Editor editor = Editor.currentEditor(); 59 final Buffer buffer = editor.getBuffer(); 60 File file = buffer.getFile(); 61 if (file.isLocal() && file.isFile()) { 62 File patchFile = buffer.getPatchFile(); 63 if (patchFile != null && patchFile.isFile()) { 64 boolean save = false; 65 if (buffer.isModified()) { 66 int response = 67 ConfirmDialog.showConfirmDialogWithCancelButton(editor, 68 CHECK_SAVE_PROMPT, "diff"); 69 switch (response) { 70 case RESPONSE_YES: 71 save = true; 72 break; 73 case RESPONSE_NO: 74 break; 75 case RESPONSE_CANCEL: 76 return; 77 } 78 editor.repaintNow(); 79 } 80 editor.setWaitCursor(); 81 if (!save || buffer.save()) { 82 FastStringBuffer sb = new FastStringBuffer("-u \""); 83 sb.append(patchFile.canonicalPath()); 84 sb.append("\" \""); 85 sb.append(file.canonicalPath()); 86 sb.append('"'); 87 diff(sb.toString()); 88 } 89 return; 90 } 91 } 92 diff("--help"); 93 } 94 95 public static void diff(String args) 96 { 97 final Editor editor = Editor.currentEditor(); 98 final Buffer parentBuffer = editor.getBuffer(); 99 String defaultOptions = "-u "; 100 List argList = Utilities.tokenize(args); 101 for (int i = 0; i < argList.size(); i++) { 102 String arg = (String ) argList.get(i); 103 if (arg.equals("%")) { 104 File file = parentBuffer.getFile(); 105 if (file == null) { 106 MessageDialog.showMessageDialog( 107 "There is no file associated with the current buffer.", 108 "Error"); 109 return; 110 } 111 if (file.isRemote()) { 112 MessageDialog.showMessageDialog( 113 file.netPath() + " is a remote file.", 114 "Error"); 115 return; 116 } 117 if (file.isDirectory()) { 118 MessageDialog.showMessageDialog( 119 file.canonicalPath() + " is a directory.", 120 "Error"); 121 return; 122 } 123 argList.set(i, file.canonicalPath()); 125 } else if (arg.startsWith("-")) { 126 defaultOptions = null; 127 } else { 128 File file = File.getInstance(editor.getCurrentDirectory(), arg); 129 if (file.exists()) 130 argList.set(i, file.canonicalPath()); 131 } 132 } 133 editor.setWaitCursor(); 134 FastStringBuffer sb = new FastStringBuffer("diff "); 135 if (defaultOptions != null) 136 sb.append(defaultOptions); 137 for (int i = 0; i < argList.size(); i++) { 138 String s = (String ) argList.get(i); 139 if (s.indexOf(' ') >= 0) { 140 sb.append('"'); 141 sb.append(s); 142 sb.append('"'); 143 } else 144 sb.append(s); 145 sb.append(' '); 146 } 147 String cmdline = sb.toString().trim(); 148 ShellCommand shellCommand = new ShellCommand(cmdline); 149 shellCommand.run(); 150 String output = shellCommand.getOutput(); 151 if (output.length() == 0) 152 MessageDialog.showMessageDialog(editor, "No changes", "diff"); 153 else { 154 DiffOutputBuffer buf = new DiffOutputBuffer(parentBuffer, output, 0); 155 buf.setTitle(cmdline); 156 editor.makeNext(buf); 157 editor.activateInOtherWindow(buf); 158 editor.setDefaultCursor(); 159 } 160 } 161 162 public static void gotoFile() 163 { 164 final Editor editor = Editor.currentEditor(); 165 if (editor.getDot() == null) 166 return; 167 final Buffer buffer = editor.getBuffer(); 168 if (!(buffer instanceof DiffOutputBuffer)) 169 return; 170 171 AWTEvent e = editor.getDispatcher().getLastEvent(); 174 if (e instanceof MouseEvent ) 175 editor.mouseMoveDotToPoint((MouseEvent ) e); 176 177 DiffOutputBuffer diffOutputBuffer = (DiffOutputBuffer) buffer; 178 int vcType = diffOutputBuffer.getVCType(); 179 switch (vcType) { 180 case VC_P4: 181 p4GotoFile(editor, diffOutputBuffer); 182 break; 183 case VC_CVS: 184 cvsGotoFile(editor, diffOutputBuffer); 185 break; 186 default: 187 localGotoFile(editor, diffOutputBuffer); 188 break; 189 } 190 } 191 192 private static void cvsGotoFile(Editor editor, DiffOutputBuffer diffOutputBuffer) 193 { 194 final Line dotLine = editor.getDotLine(); 195 final int dotOffset = editor.getDotOffset(); 196 final String text = dotLine.getText(); 197 if (text.startsWith("? ") || text.startsWith("Index: ")) { 198 String filename = text.substring(text.indexOf(' ')+1); 199 File file = File.getInstance(diffOutputBuffer.getDirectory(), 200 filename); 201 Buffer buf = editor.getBuffer(file); 202 if (buf != null) { 203 if (editor.getOtherEditor() != null) { 204 editor.activateInOtherWindow(buf); 205 } else { 206 editor.makeNext(buf); 207 editor.activate(buf); 208 } 209 } 210 return; 211 } 212 int lineNumber = 0; 213 int count = 0; 214 Line line = dotLine; 215 if (line.getText().startsWith("@@")) { 216 lineNumber = parseLineNumber(line); 217 } else { 218 line = line.previous(); 219 while (line != null && !line.getText().startsWith("@@")) { 220 if (!line.getText().startsWith("-")) 221 ++count; 222 line = line.previous(); 223 } 224 if (line == null) 225 return; 226 Debug.assertTrue(line.getText().startsWith("@@")); 227 lineNumber = parseLineNumber(line); 228 } 229 if (--lineNumber < 0) 231 return; 232 lineNumber += count; 233 Buffer parentBuffer = diffOutputBuffer.getParentBuffer(); 234 File dir; 235 if (parentBuffer != null) 236 dir = parentBuffer.getCurrentDirectory(); 237 else 238 dir = diffOutputBuffer.getDirectory(); 239 240 line = line.previous(); 241 while (line != null && !line.getText().startsWith("Index: ")) 242 line = line.previous(); 243 if (line == null) 244 return; 245 if (line.getText().startsWith("Index: ")) { 246 String filename = line.getText().substring(7); 247 File file = File.getInstance(dir, filename); 248 if (file != null && file.isFile()) { 249 Buffer buf = editor.getBuffer(file); 250 if (buf != null) 251 gotoLocation(editor, buf, lineNumber, 252 dotOffset > 0 ? dotOffset-1 : 0); 253 } 254 } else 255 Debug.bug(); 256 } 257 258 private static void p4GotoFile(Editor editor, 259 DiffOutputBuffer diffOutputBuffer) 260 { 261 final Line dotLine = editor.getDotLine(); 262 final int dotOffset = editor.getDotOffset(); 263 final String text = dotLine.getText(); 264 int lineNumber = 0; 265 int count = 0; 266 Line line = dotLine; 267 if (line.getText().startsWith("@@")) { 268 lineNumber = parseLineNumber(line); 269 } else { 270 line = line.previous(); 271 while (line != null && !line.getText().startsWith("@@")) { 272 if (!line.getText().startsWith("-")) 273 ++count; 274 line = line.previous(); 275 } 276 if (line == null) 277 return; 278 Debug.assertTrue(line.getText().startsWith("@@")); 279 lineNumber = parseLineNumber(line); 280 } 281 if (--lineNumber < 0) 283 return; 284 lineNumber += count; 285 Buffer parentBuffer = diffOutputBuffer.getParentBuffer(); 286 File dir; 287 if (parentBuffer != null) 288 dir = parentBuffer.getCurrentDirectory(); 289 else 290 dir = diffOutputBuffer.getDirectory(); 291 line = line.previous(); 292 while (line != null && !line.getText().endsWith(" ====")) 293 line = line.previous(); 294 if (line == null) 295 return; 296 int index = line.getText().lastIndexOf(" - "); 297 if (index >= 0) { 298 String filename = line.getText().substring(index+3); 299 if (filename.endsWith(" ====")) 300 filename = filename.substring(0, filename.length()-5); 301 File file = File.getInstance(dir, filename); 302 if (file != null && file.isFile()) { 303 Buffer buf = editor.getBuffer(file); 304 if (buf != null) 305 gotoLocation(editor, buf, lineNumber, 306 dotOffset > 0 ? dotOffset-1 : 0); 307 } 308 } 309 } 310 311 private static void localGotoFile(Editor editor, 312 DiffOutputBuffer diffOutputBuffer) 313 { 314 final Line dotLine = editor.getDotLine(); 315 String filename1 = null; 316 String filename2 = null;; 317 for (Line line = dotLine; line != null; line = line.previous()) { 318 String text = line.getText(); 319 if (text.startsWith("+++ ")) { 320 filename2 = extractFilename(text); 321 } else if (text.startsWith("--- ")) { 322 filename1 = extractFilename(text); 323 if (filename2 == null) { 324 line = line.next(); 325 if (line != null) 326 filename2 = extractFilename(line.getText()); 327 } 328 break; 329 } 330 } 331 final String text = dotLine.getText(); 332 if (text.startsWith("---")) { 333 Buffer buf = editor.getBuffer(File.getInstance(filename1)); 334 if (buf != null) { 335 editor.makeNext(buf); 336 editor.activateInOtherWindow(buf); 337 } 338 return; 339 } 340 if (text.startsWith("+++")) { 341 Buffer buf = editor.getBuffer(File.getInstance(filename2)); 342 if (buf != null) { 343 editor.makeNext(buf); 344 editor.activateInOtherWindow(buf); 345 } 346 return; 347 } 348 int oldLineNumber = -1; 349 int newLineNumber = -1; 350 int oldLines = 0; 351 int newLines = 0; 352 int unchangedLines = 0; 353 Line line = dotLine; 354 if (line.getText().startsWith("@@")) { 355 oldLineNumber = parseLineNumber(line, '-'); 356 newLineNumber = parseLineNumber(line, '+'); 357 } else { 358 line = line.previous(); 359 while (line != null && !line.getText().startsWith("@@")) { 360 if (line.getText().startsWith("-")) 361 ++oldLines; 362 else if (line.getText().startsWith("+")) 363 ++newLines; 364 else 365 ++unchangedLines; 366 line = line.previous(); 367 } 368 if (line == null) 369 return; 370 Debug.assertTrue(line.getText().startsWith("@@")); 371 oldLineNumber = parseLineNumber(line, '-'); 372 newLineNumber = parseLineNumber(line, '+'); 373 } 374 --oldLineNumber; 376 --newLineNumber; 377 String filename = filename2; 378 if (text.startsWith("-")) { 379 oldLineNumber += unchangedLines + oldLines; 380 newLineNumber += unchangedLines; 381 filename = filename1; 382 } else if (text.startsWith("+")) { 383 oldLineNumber += unchangedLines; 384 newLineNumber += unchangedLines + newLines; 385 filename = filename2; 386 } else { 387 oldLineNumber = oldLineNumber + unchangedLines + oldLines; 389 newLineNumber = newLineNumber + unchangedLines + newLines; 390 File parentFile = diffOutputBuffer.getParentBuffer().getFile(); 391 if (parentFile != null) { 392 String cp = parentFile.canonicalPath(); 393 if (cp != null) { 394 if (cp.equals(filename1)) 395 filename = filename1; 396 } 397 } 398 } 399 File dir = null; 400 Buffer parentBuffer = diffOutputBuffer.getParentBuffer(); 401 if (parentBuffer != null) 402 dir = parentBuffer.getCurrentDirectory(); 403 final File file; 404 if (dir != null) 405 file = File.getInstance(dir, filename); 406 else 407 file = File.getInstance(filename); 408 if (file != null && file.isFile()) { 409 Buffer buf = editor.getBuffer(file); 410 if (buf != null) { 411 int lineNumber = 412 (filename == filename1) ? oldLineNumber : newLineNumber; 413 final int offset = editor.getDotOffset(); 414 gotoLocation(editor, buf, lineNumber, 415 offset > 0 ? offset-1 : 0); 416 } 417 } 418 } 419 420 private static String extractFilename(String s) 421 { 422 if (s.startsWith("+++ ") || s.startsWith("--- ")) 423 s = s.substring(4); 424 int index = s.indexOf('\t'); 425 return index >= 0 ? s.substring(0, index) : s; 426 } 427 428 private static void gotoLocation(Editor editor, Buffer buf, int lineNumber, 429 int offset) 430 { 431 if (buf != null) { 432 editor.makeNext(buf); 433 Editor ed = editor.activateInOtherWindow(buf); 434 Position pos = buf.findOriginal(lineNumber, offset); 435 ed.moveDotTo(pos); 436 ed.setUpdateFlag(REFRAME); 437 ed.updateDisplay(); 438 } 439 } 440 441 private static int parseLineNumber(Line line) 442 { 443 return parseLineNumber(line, '+'); 444 } 445 446 private static int parseLineNumber(Line line, char c) 447 { 448 String s = line.getText(); 449 int index = s.indexOf(c); 450 if (index < 0) 451 return 0; 452 try { 453 return Utilities.parseInt(s.substring(index+1)); 454 } 455 catch (NumberFormatException e) { 456 Log.error(e); 457 return 0; 458 } 459 } 460 } 461 | Popular Tags |