src/Tools/jEdit/src/completion_popup.scala
changeset 66158 ad83d4971dfe
parent 66157 cb57fcdbaf70
child 66180 201d42f67bba
equal deleted inserted replaced
66157:cb57fcdbaf70 66158:ad83d4971dfe
    10 import isabelle._
    10 import isabelle._
    11 
    11 
    12 import java.awt.{Color, Font, Point, BorderLayout, Dimension}
    12 import java.awt.{Color, Font, Point, BorderLayout, Dimension}
    13 import java.awt.event.{KeyEvent, MouseEvent, MouseAdapter, FocusAdapter, FocusEvent}
    13 import java.awt.event.{KeyEvent, MouseEvent, MouseAdapter, FocusAdapter, FocusEvent}
    14 import java.io.{File => JFile}
    14 import java.io.{File => JFile}
    15 import java.util.regex.Pattern
       
    16 import javax.swing.{JPanel, JComponent, JLayeredPane, SwingUtilities}
    15 import javax.swing.{JPanel, JComponent, JLayeredPane, SwingUtilities}
    17 import javax.swing.border.LineBorder
    16 import javax.swing.border.LineBorder
    18 import javax.swing.text.DefaultCaret
    17 import javax.swing.text.DefaultCaret
    19 
    18 
    20 import scala.swing.{ListView, ScrollPane}
    19 import scala.swing.{ListView, ScrollPane}
   130             rendering.before_caret_range(caret).try_restrict(line_range) match {
   129             rendering.before_caret_range(caret).try_restrict(line_range) match {
   131               case Some(range) if !range.is_singularity =>
   130               case Some(range) if !range.is_singularity =>
   132                 val range0 =
   131                 val range0 =
   133                   Completion.Result.merge(Completion.History.empty,
   132                   Completion.Result.merge(Completion.History.empty,
   134                     syntax_completion(Completion.History.empty, true, Some(rendering)),
   133                     syntax_completion(Completion.History.empty, true, Some(rendering)),
   135                     path_completion(rendering),
   134                     rendering.path_completion(caret),
   136                     Document_Model.bibtex_completion(Completion.History.empty, rendering, caret))
   135                     Document_Model.bibtex_completion(Completion.History.empty, rendering, caret))
   137                   .map(_.range)
   136                   .map(_.range)
   138                 rendering.semantic_completion(range0, range) match {
   137                 rendering.semantic_completion(range0, range) match {
   139                   case None => range0
   138                   case None => range0
   140                   case Some(Text.Info(_, Completion.No_Completion)) => None
   139                   case Some(Text.Info(_, Completion.No_Completion)) => None
   178                 history, unicode, explicit, line_start, line_text, caret - line_start, context)
   177                 history, unicode, explicit, line_start, line_text, caret - line_start, context)
   179           } yield result
   178           } yield result
   180 
   179 
   181         case None => None
   180         case None => None
   182       }
   181       }
   183     }
       
   184 
       
   185 
       
   186     /* path completion */
       
   187 
       
   188     def path_completion(rendering: JEdit_Rendering): Option[Completion.Result] =
       
   189     {
       
   190       def complete(text: String): List[(String, List[String])] =
       
   191       {
       
   192         try {
       
   193           val path = Path.explode(text)
       
   194           val (dir, base_name) =
       
   195             if (text == "" || text.endsWith("/")) (path, "")
       
   196             else (path.dir, path.base_name)
       
   197 
       
   198           val directory = new JFile(PIDE.resources.append(rendering.snapshot.node_name, dir))
       
   199           val files = directory.listFiles
       
   200           if (files == null) Nil
       
   201           else {
       
   202             val ignore =
       
   203               Library.space_explode(':', PIDE.options.string("jedit_completion_path_ignore")).
       
   204                 map(s => Pattern.compile(StandardUtilities.globToRE(s)))
       
   205             (for {
       
   206               file <- files.iterator
       
   207 
       
   208               name = file.getName
       
   209               if name.startsWith(base_name)
       
   210               if !ignore.exists(pat => pat.matcher(name).matches)
       
   211 
       
   212               text1 = (dir + Path.basic(name)).implode_short
       
   213               if text != text1
       
   214 
       
   215               is_dir = new JFile(directory, name).isDirectory
       
   216               replacement = text1 + (if (is_dir) "/" else "")
       
   217               descr = List(text1, if (is_dir) "(directory)" else "(file)")
       
   218             } yield (replacement, descr)).take(PIDE.options.int("completion_limit")).toList
       
   219           }
       
   220         }
       
   221         catch { case ERROR(_) => Nil }
       
   222       }
       
   223 
       
   224       def is_wrapped(s: String): Boolean =
       
   225         s.startsWith("\"") && s.endsWith("\"") ||
       
   226         s.startsWith(Symbol.open_decoded) && s.endsWith(Symbol.close_decoded)
       
   227 
       
   228       for {
       
   229         r1 <- rendering.language_path(rendering.before_caret_range(text_area.getCaretPosition))
       
   230         s1 <- JEdit_Lib.try_get_text(text_area.getBuffer, r1)
       
   231         if is_wrapped(s1)
       
   232         r2 = Text.Range(r1.start + 1, r1.stop - 1)
       
   233         s2 = s1.substring(1, s1.length - 1)
       
   234         if Path.is_valid(s2)
       
   235         paths = complete(s2)
       
   236         if paths.nonEmpty
       
   237         items = paths.map(p => Completion.Item(r2, s2, "", p._2, p._1, 0, false))
       
   238       } yield Completion.Result(r2, s2, false, items)
       
   239     }
   182     }
   240 
   183 
   241 
   184 
   242     /* completion action: text area */
   185     /* completion action: text area */
   243 
   186 
   372               case None => result1
   315               case None => result1
   373               case Some(rendering) =>
   316               case Some(rendering) =>
   374                 Completion.Result.merge(history,
   317                 Completion.Result.merge(history,
   375                   result1,
   318                   result1,
   376                   JEdit_Spell_Checker.completion(rendering, explicit, caret),
   319                   JEdit_Spell_Checker.completion(rendering, explicit, caret),
   377                   path_completion(rendering),
   320                   rendering.path_completion(caret),
   378                   Document_Model.bibtex_completion(history, rendering, caret))
   321                   Document_Model.bibtex_completion(history, rendering, caret))
   379             }
   322             }
   380           }
   323           }
   381           result match {
   324           result match {
   382             case Some(result) =>
   325             case Some(result) =>