Syntax highlighting is changeable.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / php / PHPCompletionProcessor.java
index ac3f814..5d50dee 100644 (file)
@@ -10,6 +10,7 @@
  Klaus Hartlage - www.eclipseproject.de
  **********************************************************************/
 package net.sourceforge.phpeclipse.phpeditor.php;
+
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
@@ -18,27 +19,31 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.SortedMap;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
 import net.sourceforge.phpdt.core.ToolFactory;
 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
-import net.sourceforge.phpdt.internal.corext.template.ContextType;
-import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
-import net.sourceforge.phpdt.internal.corext.template.php.PHPUnitContext;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
 import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
 import net.sourceforge.phpdt.internal.ui.text.java.PHPCompletionProposalComparator;
 import net.sourceforge.phpdt.internal.ui.text.template.BuiltInEngine;
 import net.sourceforge.phpdt.internal.ui.text.template.DeclarationEngine;
 import net.sourceforge.phpdt.internal.ui.text.template.IdentifierEngine;
-import net.sourceforge.phpdt.internal.ui.text.template.IdentifierProposal;
-import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine;
-import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpdt.internal.ui.text.template.SQLProposal;
+import net.sourceforge.phpdt.internal.ui.text.template.contentassist.TemplateEngine;
+import net.sourceforge.phpdt.ui.IWorkingCopyManager;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
 import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
 import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
+import net.sourceforge.phpeclipse.ui.IPreferenceConstants;
+import net.sourceforge.phpeclipse.ui.overlaypages.Util;
+
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.jface.text.BadLocationException;
@@ -53,14 +58,17 @@ import org.eclipse.jface.text.contentassist.IContextInformation;
 import org.eclipse.jface.text.contentassist.IContextInformationExtension;
 import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
 import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.text.templates.TemplateContextType;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IFileEditorInput;
-import net.sourceforge.phpeclipse.overlaypages.Util;
+
 import com.quantum.model.Bookmark;
 import com.quantum.model.BookmarkCollection;
 import com.quantum.model.NotConnectedException;
 import com.quantum.util.connection.ConnectionUtil;
+
 /**
  * Example PHP completion processor.
  */
@@ -69,17 +77,17 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
    * Simple content assist tip closer. The tip is valid in a range of 5
    * characters around its popup location.
    */
-  protected static class Validator
-      implements
-        IContextInformationValidator,
-        IContextInformationPresenter {
+  protected static class Validator implements IContextInformationValidator,
+      IContextInformationPresenter {
     protected int fInstallOffset;
+
     /*
      * @see IContextInformationValidator#isContextInformationValid(int)
      */
     public boolean isContextInformationValid(int offset) {
       return Math.abs(fInstallOffset - offset) < 5;
     }
+
     /*
      * @see IContextInformationValidator#install(IContextInformation,
      *      ITextViewer, int)
@@ -87,6 +95,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     public void install(IContextInformation info, ITextViewer viewer, int offset) {
       fInstallOffset = offset;
     }
+
     /*
      * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int,
      *      TextPresentation)
@@ -96,74 +105,121 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
       return false;
     }
   };
-  private static class ContextInformationWrapper
-      implements
-        IContextInformation,
-        IContextInformationExtension {
+
+  private static class ContextInformationWrapper implements
+      IContextInformation, IContextInformationExtension {
     private final IContextInformation fContextInformation;
+
     private int fPosition;
+
     public ContextInformationWrapper(IContextInformation contextInformation) {
       fContextInformation = contextInformation;
     }
+
     /*
      * @see IContextInformation#getContextDisplayString()
      */
     public String getContextDisplayString() {
       return fContextInformation.getContextDisplayString();
     }
+
     /*
      * @see IContextInformation#getImage()
      */
     public Image getImage() {
       return fContextInformation.getImage();
     }
+
     /*
      * @see IContextInformation#getInformationDisplayString()
      */
     public String getInformationDisplayString() {
       return fContextInformation.getInformationDisplayString();
     }
+
     /*
      * @see IContextInformationExtension#getContextInformationPosition()
      */
     public int getContextInformationPosition() {
       return fPosition;
     }
+
     public void setContextInformationPosition(int position) {
       fPosition = position;
     }
   };
+
+  private class TableName {
+    String fTableName;
+
+    TableName() {
+      fTableName = null;
+    }
+
+    /**
+     * @return Returns the tableName.
+     */
+    public String getTableName() {
+      if (fTableName == null) {
+        return "<!--no-table-->";
+      }
+      return fTableName;
+    }
+
+    /**
+     * @param tableName
+     *          The tableName to set.
+     */
+    public void setTableName(String tableName) {
+      fTableName = tableName;
+    }
+  }
+
   private char[] fProposalAutoActivationSet;
+
   protected IContextInformationValidator fValidator = new Validator();
+
   private TemplateEngine fTemplateEngine;
+
   private PHPCompletionProposalComparator fComparator;
+
   private int fNumberOfComputedResults = 0;
-  public PHPCompletionProcessor() {
-    ContextType contextType = ContextTypeRegistry.getInstance().getContextType(
+
+  private IEditorPart fEditor;
+
+  protected IWorkingCopyManager fManager;
+
+  public PHPCompletionProcessor(IEditorPart editor) {
+    fEditor = editor;
+    fManager = PHPeclipsePlugin.getDefault().getWorkingCopyManager();
+    TemplateContextType contextType = PHPeclipsePlugin.getDefault().getTemplateContextRegistry().getContextType(
         "php"); //$NON-NLS-1$
     if (contextType != null)
       fTemplateEngine = new TemplateEngine(contextType);
     fComparator = new PHPCompletionProposalComparator();
   }
+
   /**
    * Tells this processor to order the proposals alphabetically.
    * 
    * @param order
-   *            <code>true</code> if proposals should be ordered.
+   *          <code>true</code> if proposals should be ordered.
    */
   public void orderProposalsAlphabetically(boolean order) {
     fComparator.setOrderAlphabetically(order);
   }
+
   /**
    * Sets this processor's set of characters triggering the activation of the
    * completion proposal computation.
    * 
    * @param activationSet
-   *            the activation set
+   *          the activation set
    */
   public void setCompletionProposalAutoActivationCharacters(char[] activationSet) {
     fProposalAutoActivationSet = activationSet;
   }
+
   /*
    * (non-Javadoc) Method declared on IContentAssistProcessor
    */
@@ -174,8 +230,9 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     return internalComputeCompletionProposals(viewer, documentOffset,
         contextInformationPosition);
   }
+
   private int getLastToken(ITextViewer viewer, int completionPosition,
-      PHPUnitContext context) {
+      JavaContext context, TableName tableName) {
     IDocument document = viewer.getDocument();
     int start = context.getStart();
     int end = context.getEnd();
@@ -206,21 +263,31 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
           System.out.println(startText);
         }
         int token = ITerminalSymbols.TokenNameEOF;
-        
-        token = getLastSQLToken(startText);
-        
+        //        token = getLastSQLToken(startText);
+        tableName.setTableName(getLastSQLTableName(startText));
         Scanner scanner = ToolFactory.createScanner(false, false, false);
         scanner.setSource(startText.toCharArray());
         scanner.setPHPMode(true);
-        
         int beforeLastToken = ITerminalSymbols.TokenNameEOF;
         int lastToken = ITerminalSymbols.TokenNameEOF;
+        char[] ident;
         try {
           token = scanner.getNextToken();
           lastToken = token;
           while (token != ITerminalSymbols.TokenNameERROR
               && token != ITerminalSymbols.TokenNameEOF) {
             beforeLastToken = lastToken;
+            if (lastToken==ITerminalSymbols.TokenNameVariable) {
+              ident = scanner.getCurrentTokenSource();
+              if (ident.length==5 &&
+                  ident[0]=='$' &&
+                  ident[1]=='t' &&
+                  ident[2]=='h' &&
+                  ident[3]=='i' &&
+                  ident[4]=='s') {
+                beforeLastToken = ITerminalSymbols.TokenNamethis_PHP_COMPLETION;
+              }
+            }
             lastToken = token;
             //                                                         System.out.println(scanner.toStringAction(lastToken));
             token = scanner.getNextToken();
@@ -228,23 +295,134 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
         } catch (InvalidInputException e1) {
         }
         switch (lastToken) {
-          case ITerminalSymbols.TokenNameMINUS_GREATER :
-            // dereferencing operator '->' found
-            lastSignificantToken = ITerminalSymbols.TokenNameMINUS_GREATER;
-            if (beforeLastToken == ITerminalSymbols.TokenNameVariable) {
-              lastSignificantToken = ITerminalSymbols.TokenNameVariable;
-            }
-            break;
-          case ITerminalSymbols.TokenNamenew :
-            lastSignificantToken = ITerminalSymbols.TokenNamenew;
-            break;
+        case ITerminalSymbols.TokenNameMINUS_GREATER:
+          // dereferencing operator '->' found
+          lastSignificantToken = ITerminalSymbols.TokenNameMINUS_GREATER;
+          if (beforeLastToken == ITerminalSymbols.TokenNameVariable) {
+            lastSignificantToken = ITerminalSymbols.TokenNameVariable;
+          }
+          break;
+        case ITerminalSymbols.TokenNamenew:
+          lastSignificantToken = ITerminalSymbols.TokenNamenew;
+          break;
         }
       }
     } catch (BadLocationException e) {
     }
     return lastSignificantToken;
   }
-  
+
+  String getSQLTableName(String sqlText, int start) {
+    int tableNameStart = -1;
+    int currentCharacterPosition = start + 1;
+    char ch;
+    try {
+      while (true) {
+        ch = sqlText.charAt(currentCharacterPosition++);
+        if (tableNameStart == -1 && Character.isJavaIdentifierStart(ch)) {
+          tableNameStart = currentCharacterPosition - 1;
+        } else {
+          if (!Character.isJavaIdentifierPart(ch)) {
+            return sqlText.substring(tableNameStart,
+                currentCharacterPosition - 1);
+          }
+        }
+      }
+    } catch (IndexOutOfBoundsException e) {
+      if (tableNameStart >= 0) {
+        return sqlText.substring(tableNameStart, currentCharacterPosition - 1);
+      }
+    }
+    return "";
+  }
+
+  private String getLastSQLTableName(String startText) {
+    int token;
+    // scan for sql identifiers
+    char ch = ' ';
+    int currentSQLPosition = startText.length();
+    int identEnd = -1;
+    String ident = null;
+    boolean whiteSpace = true;
+    try {
+      while (true) {
+        ch = startText.charAt(--currentSQLPosition);
+        if (ch >= 'A' && ch <= 'Z') {
+          if (identEnd < 0) {
+            identEnd = currentSQLPosition + 1;
+          }
+        } else if (ch >= 'a' && ch <= 'z') {
+          if (identEnd < 0) {
+            identEnd = currentSQLPosition + 1;
+          }
+        } else if (identEnd >= 0) {
+          ident = startText.substring(currentSQLPosition + 1, identEnd);
+          // select -- from -- where --
+          // update -- set -- where --
+          // insert into -- ( -- ) values ( -- )
+          if (ident.length() >= 4 && ident.length() <= 6) {
+            ident = ident.toLowerCase();
+            switch (ident.length()) {
+            //              case 3 :
+            //                if (ident.equals("set")) {
+            //                  // System.out.println("set");
+            //                  token = ITerminalSymbols.TokenNameSQLset;
+            //                  return token;
+            //                }
+            //                break;
+            case 4:
+              if (ident.equals("from")) {
+                //                  System.out.println("from");
+                token = ITerminalSymbols.TokenNameSQLfrom;
+                return getSQLTableName(startText, identEnd);
+              } else if (ident.equals("into")) {
+                //                System.out.println("into");
+                token = ITerminalSymbols.TokenNameSQLinto;
+                return getSQLTableName(startText, identEnd);
+              }
+              break;
+            //              case 5 :
+            //                if (ident.equals("where")) {
+            //                  // System.out.println("where");
+            //                  token = ITerminalSymbols.TokenNameSQLwhere;
+            //                  return token;
+            //                }
+            //                break;
+            case 6:
+              //                if (ident.equals("select")) {
+              //                  // System.out.println("select");
+              //                  token = ITerminalSymbols.TokenNameSQLselect;
+              //                  return token;
+              //                } else if (ident.equals("insert")) {
+              //                  // System.out.println("insert");
+              //                  token = ITerminalSymbols.TokenNameSQLinsert;
+              //                  return token;
+              //                } else
+              if (ident.equals("update")) {
+                //                  System.out.println("update");
+                token = ITerminalSymbols.TokenNameSQLupdate;
+                return getSQLTableName(startText, identEnd);
+              }
+              //                else if (ident.equals("values")) {
+              //                  // System.out.println("values");
+              //                  token = ITerminalSymbols.TokenNameSQLvalues;
+              //                  return token;
+              //                }
+              break;
+            }
+          }
+          whiteSpace = false;
+          identEnd = -1;
+        } else if (Character.isWhitespace(ch)) {
+        } else {
+          whiteSpace = false;
+        }
+      }
+    } catch (IndexOutOfBoundsException e) {
+    }
+    return "<!--no-table-->";
+  }
+
   /**
    * Detect the last significant SQL token in the text before the completion
    * 
@@ -277,50 +455,51 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
           if (ident.length() >= 3 && ident.length() <= 6) {
             ident = ident.toLowerCase();
             switch (ident.length()) {
-              case 3 :
-                if (ident.equals("set")) {
-//                  System.out.println("set");
-                  token = ITerminalSymbols.TokenNameSQLset;
-                  return token;
-                }
-                break;
-              case 4 :
-                if (ident.equals("from")) {
-//                  System.out.println("from");
-                  token = ITerminalSymbols.TokenNameSQLfrom;
-                  return token;
-                } else if (ident.equals("into")) {
-//                System.out.println("into");
-                  token = ITerminalSymbols.TokenNameSQLinto;
-                  return token;
-                }
-                break;
-              case 5 :
-                if (ident.equals("where")) {
-//                  System.out.println("where");
-                  token = ITerminalSymbols.TokenNameSQLwhere;
-                  return token;
-                }
-                break;
-              case 6 :
-                if (ident.equals("select")) {
-//                  System.out.println("select");
-                  token = ITerminalSymbols.TokenNameSQLselect;
-                  return token;
-                } else if (ident.equals("insert")) {
-//                  System.out.println("insert");
-                  token = ITerminalSymbols.TokenNameSQLinsert;
-                  return token;
-                } else if (ident.equals("update")) {
-//                  System.out.println("update");
-                  token = ITerminalSymbols.TokenNameSQLupdate;
-                  return token;
-                } else if (ident.equals("values")) {
-//                System.out.println("values");
-                  token = ITerminalSymbols.TokenNameSQLvalues;
-                  return token;
-                }
-                break;
+            case 3:
+              if (ident.equals("set")) {
+                //                  System.out.println("set");
+                token = ITerminalSymbols.TokenNameSQLset;
+                return token;
+              }
+              break;
+            case 4:
+              if (ident.equals("from")) {
+                //                  System.out.println("from");
+                token = ITerminalSymbols.TokenNameSQLfrom;
+                //getSQLTableName();
+                return token;
+              } else if (ident.equals("into")) {
+                //                System.out.println("into");
+                token = ITerminalSymbols.TokenNameSQLinto;
+                return token;
+              }
+              break;
+            case 5:
+              if (ident.equals("where")) {
+                //                  System.out.println("where");
+                token = ITerminalSymbols.TokenNameSQLwhere;
+                return token;
+              }
+              break;
+            case 6:
+              if (ident.equals("select")) {
+                //                  System.out.println("select");
+                token = ITerminalSymbols.TokenNameSQLselect;
+                return token;
+              } else if (ident.equals("insert")) {
+                //                  System.out.println("insert");
+                token = ITerminalSymbols.TokenNameSQLinsert;
+                return token;
+              } else if (ident.equals("update")) {
+                //                  System.out.println("update");
+                token = ITerminalSymbols.TokenNameSQLupdate;
+                return token;
+              } else if (ident.equals("values")) {
+                //                System.out.println("values");
+                token = ITerminalSymbols.TokenNameSQLvalues;
+                return token;
+              }
+              break;
             }
           }
           whiteSpace = false;
@@ -334,56 +513,63 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     }
     return ITerminalSymbols.TokenNameEOF;
   }
-  
+
   private ICompletionProposal[] internalComputeCompletionProposals(
       ITextViewer viewer, int offset, int contextOffset) {
+    ICompilationUnit unit= fManager.getWorkingCopy(fEditor.getEditorInput());
     IDocument document = viewer.getDocument();
     Object[] identifiers = null;
     IFile file = null;
     IProject project = null;
     if (offset > 0) {
       PHPEditor editor = null;
-      //      JavaOutlinePage outlinePage = null;
-      IEditorPart targetEditor = PHPeclipsePlugin.getActiveWorkbenchWindow()
-          .getActivePage().getActiveEditor();
-      if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
-        editor = (PHPEditor) targetEditor;
+      if (fEditor != null && (fEditor instanceof PHPEditor)) {
+        editor = (PHPEditor) fEditor;
         file = ((IFileEditorInput) editor.getEditorInput()).getFile();
         project = file.getProject();
-        //        outlinePage = editor.getfOutlinePage();
-        // TODO: get the identifiers from the new model
-        //        if (outlinePage instanceof PHPContentOutlinePage) {
-        //          identifiers = ((PHPContentOutlinePage) outlinePage).getVariables();
-        //        }
       }
     }
-    ContextType phpContextType = ContextTypeRegistry.getInstance()
-        .getContextType("php"); //$NON-NLS-1$
-    ((CompilationUnitContextType) phpContextType).setContextParameters(
-        document, offset, 0);
-    PHPUnitContext context = (PHPUnitContext) phpContextType.createContext();
+    
+    Point selection= viewer.getSelectedRange();
+
+       // remember selected text
+       String selectedText= null;
+       if (selection.y != 0) {
+               try {
+                       selectedText= document.get(selection.x, selection.y);
+               } catch (BadLocationException e) {}
+       }
+
+    JavaContextType phpContextType = (JavaContextType)PHPeclipsePlugin.getDefault().getTemplateContextRegistry().getContextType(
+    "php"); //$NON-NLS-1$
+//    ((CompilationUnitContextType) phpContextType).setContextParameters(
+//        document, offset, 0);
+    JavaContext context = (JavaContext) phpContextType.createContext(document, offset,selection.y,unit);
+    context.setVariable("selection", selectedText); //$NON-NLS-1$
     String prefix = context.getKey();
-    int lastSignificantToken = getLastToken(viewer, offset, context);
+    TableName sqlTable = new TableName();
+    int lastSignificantToken = getLastToken(viewer, offset, context, sqlTable);
     boolean useClassMembers = (lastSignificantToken == ITerminalSymbols.TokenNameMINUS_GREATER)
         || (lastSignificantToken == ITerminalSymbols.TokenNameVariable)
-        || (lastSignificantToken == ITerminalSymbols.TokenNamenew);
+        || (lastSignificantToken == ITerminalSymbols.TokenNamenew)
+        || (lastSignificantToken == ITerminalSymbols.TokenNamethis_PHP_COMPLETION);
     boolean emptyPrefix = prefix == null || prefix.equals("");
     if (fTemplateEngine != null) {
       IPHPCompletionProposal[] templateResults = new IPHPCompletionProposal[0];
       ICompletionProposal[] results;
       if (!emptyPrefix) {
         fTemplateEngine.reset();
-        fTemplateEngine.complete(viewer, offset); //, unit);
+        fTemplateEngine.complete(viewer, offset, unit);
         templateResults = fTemplateEngine.getResults();
       }
       IPHPCompletionProposal[] identifierResults = new IPHPCompletionProposal[0];
       if ((!useClassMembers) && identifiers != null) {
         IdentifierEngine identifierEngine;
-        ContextType contextType = ContextTypeRegistry.getInstance()
-            .getContextType("php"); //$NON-NLS-1$
+        JavaContextType contextType = (JavaContextType)PHPeclipsePlugin.getDefault().getTemplateContextRegistry().getContextType(
+        "php"); //$NON-NLS-1$
         if (contextType != null) {
           identifierEngine = new IdentifierEngine(contextType);
-          identifierEngine.complete(viewer, offset, identifiers);
+          identifierEngine.complete(viewer, offset, identifiers,unit);
           identifierResults = identifierEngine.getResults();
         }
       }
@@ -391,15 +577,15 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
       IPHPCompletionProposal[] declarationResults = new IPHPCompletionProposal[0];
       if (project != null) {
         DeclarationEngine declarationEngine;
-        ContextType contextType = ContextTypeRegistry.getInstance()
-            .getContextType("php"); //$NON-NLS-1$
+        JavaContextType contextType = (JavaContextType)PHPeclipsePlugin.getDefault().getTemplateContextRegistry().getContextType(
+        "php"); //$NON-NLS-1$
         if (contextType != null) {
           IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
               .getIndexManager(project);
           SortedMap sortedMap = indexManager.getIdentifierMap();
-          declarationEngine = new DeclarationEngine(contextType,
+          declarationEngine = new DeclarationEngine(project, contextType,
               lastSignificantToken, file);
-          declarationEngine.complete(viewer, offset, sortedMap);
+          declarationEngine.complete(viewer, offset, sortedMap,unit);
           declarationResults = declarationEngine.getResults();
         }
       }
@@ -409,11 +595,11 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
       if ((!useClassMembers) && syntaxbuffer != null) {
         BuiltInEngine builtinEngine;
         String proposal;
-        ContextType contextType = ContextTypeRegistry.getInstance()
-            .getContextType("php"); //$NON-NLS-1$
+        JavaContextType contextType = (JavaContextType)PHPeclipsePlugin.getDefault().getTemplateContextRegistry().getContextType(
+        "php"); //$NON-NLS-1$
         if (contextType != null) {
           builtinEngine = new BuiltInEngine(contextType);
-          builtinEngine.complete(viewer, offset, syntaxbuffer);
+          builtinEngine.complete(viewer, offset, syntaxbuffer, unit);
           builtinResults = builtinEngine.getResults();
         }
       }
@@ -426,7 +612,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
               IPreferenceConstants.PHP_BOOKMARK_DEFAULT);
           if (bookmarkString != null && !bookmarkString.equals("")) {
             Bookmark bookmark = sqlBookMarks.find(bookmarkString);
-            ArrayList list = new ArrayList();
+            ArrayList sqlList = new ArrayList();
             if (bookmark != null && !bookmark.isConnected()) {
               new ConnectionUtil().connect(bookmark, null);
             }
@@ -434,43 +620,68 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
               try {
                 Connection connection = bookmark.getConnection();
                 DatabaseMetaData metaData = connection.getMetaData();
+
                 if (metaData != null) {
                   int start = context.getStart();
                   int end = context.getEnd();
+                  String foundSQLTableName = sqlTable.getTableName();
+                  String tableName;
+                  String columnName;
+                  String prefixWithoutDollar = prefix;
+                  boolean isDollarPrefix = false;
+                  if (prefix.length() > 0 && prefix.charAt(0) == '$') {
+                    prefixWithoutDollar = prefix.substring(1);
+                    isDollarPrefix = true;
+                  }
                   IRegion region = new Region(start, end - start);
-                  ResultSet set = metaData.getTables(null, null, prefix + "%",
-                      null);
-                  while (set.next()) {
-                    //                  String tempSchema = set.getString("TABLE_SCHEM");
-                    //                  tempSchema = (tempSchema == null) ? "" :
-                    // tempSchema.trim();
-                    String tableName = set.getString("TABLE_NAME");
-                    tableName = (tableName == null) ? "" : tableName.trim();
-                    if (tableName != null && tableName.length() > 0) {
-                      list.add(tableName);
+                  ResultSet set;
+                  if (!isDollarPrefix) {
+                    set = metaData.getTables(null, null, prefixWithoutDollar
+                        + "%", null);
+                    while (set.next()) {
+                      //                  String tempSchema = set.getString("TABLE_SCHEM");
+                      //                  tempSchema = (tempSchema == null) ? "" :
+                      // tempSchema.trim();
+                      tableName = set.getString("TABLE_NAME");
+                      tableName = (tableName == null) ? "" : tableName.trim();
+                      if (tableName != null && tableName.length() > 0) {
+                        sqlList.add(new SQLProposal(tableName, context, region,
+                            viewer, PHPUiImages.get(PHPUiImages.IMG_TABLE)));
+                      }
                     }
+                    set.close();
                   }
-                  set.close();
-                  set = metaData.getColumns(null, null, "%", prefix + "%");
+                  set = metaData.getColumns(null, null, "%",
+                      prefixWithoutDollar + "%");
+                  SQLProposal sqlProposal;
                   while (set.next()) {
-                    String tableName = set.getString("COLUMN_NAME");
-                    tableName = (tableName == null) ? "" : tableName.trim();
-                    if (tableName != null && tableName.length() > 0) {
-                      list.add(tableName);
-                    }
+                    columnName = set.getString("COLUMN_NAME");
+                    columnName = (columnName == null) ? "" : columnName.trim();
                     tableName = set.getString("TABLE_NAME");
                     tableName = (tableName == null) ? "" : tableName.trim();
-                    if (tableName != null && tableName.length() > 0) {
-                      list.add(tableName);
+                    if (tableName != null && tableName.length() > 0
+                        && columnName != null && columnName.length() > 0) {
+                      if (isDollarPrefix) {
+                        sqlProposal = new SQLProposal(tableName, "$"
+                            + columnName, context, region, viewer, PHPUiImages
+                            .get(PHPUiImages.IMG_COLUMN));
+                      } else {
+                        sqlProposal = new SQLProposal(tableName, columnName,
+                            context, region, viewer, PHPUiImages
+                                .get(PHPUiImages.IMG_COLUMN));
+                      }
+                      if (tableName.equals(foundSQLTableName)) {
+                        sqlProposal.setRelevance(90);
+                      } else if (tableName.indexOf(foundSQLTableName) >= 0) {
+                        sqlProposal.setRelevance(75);
+                      }
+                      sqlList.add(sqlProposal);
                     }
                   }
                   set.close();
-                  sqlResults = new IPHPCompletionProposal[list.size()];
-                  for (int i = 0; i < list.size(); i++) {
-                    sqlResults[i] = new IdentifierProposal(
-                        (String) list.get(i), context, region, viewer,
-                        PHPUiImages.get(PHPUiImages.IMG_FUN), PHPUiImages
-                            .get(PHPUiImages.IMG_VAR));
+                  sqlResults = new IPHPCompletionProposal[sqlList.size()];
+                  for (int i = 0; i < sqlList.size(); i++) {
+                    sqlResults[i] = (SQLProposal) sqlList.get(i);
                   }
                 }
               } catch (NotConnectedException e) {
@@ -508,6 +719,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     }
     return new IPHPCompletionProposal[0];
   }
+
   private int guessContextInformationPosition(ITextViewer viewer, int offset) {
     int contextPosition = offset;
     IDocument document = viewer.getDocument();
@@ -540,6 +752,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     //    }
     return contextPosition;
   }
+
   /*
    * (non-Javadoc) Method declared on IContentAssistProcessor
    */
@@ -567,6 +780,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     return (IContextInformation[]) result
         .toArray(new IContextInformation[result.size()]);
   }
+
   private List addContextInformations(ITextViewer viewer, int offset) {
     ICompletionProposal[] proposals = internalComputeCompletionProposals(
         viewer, offset, -1);
@@ -583,6 +797,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     }
     return result;
   }
+
   /**
    * Order the given proposals.
    */
@@ -590,6 +805,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     Arrays.sort(proposals, fComparator);
     return proposals;
   }
+
   /*
    * (non-Javadoc) Method declared on IContentAssistProcessor
    */
@@ -597,22 +813,25 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     return fProposalAutoActivationSet;
     //    return null; // new char[] { '$' };
   }
+
   /*
    * (non-Javadoc) Method declared on IContentAssistProcessor
    */
   public char[] getContextInformationAutoActivationCharacters() {
-    return new char[]{};
+    return new char[] {};
   }
+
   /*
    * (non-Javadoc) Method declared on IContentAssistProcessor
    */
   public IContextInformationValidator getContextInformationValidator() {
     return fValidator;
   }
+
   /*
    * (non-Javadoc) Method declared on IContentAssistProcessor
    */
   public String getErrorMessage() {
     return null;
   }
-}
+}
\ No newline at end of file