Eclipse RCP: 自定义控制台

5
我正在尝试创建一个控制台,它将作为自定义编程语言的 shell。它将非常类似于 pydev 交互式控制台。
目前,我的 RCP 使用基本的 TextConsole,并通过管道连接到 shell,因此它只显示 shell 显示的内容,如果用户在 RCP 控制台中输入任何内容,则会写入 shell 中。
我想能够做更多的事情,如移动插入符位置,添加向上和向下箭头键的事件等。我相信要做到这一点,我需要在控制台中添加 StyledText 小部件,这可以通过 ConsoleViewer 完成。
所以我的问题是,是否有任何方法可以覆盖 TextConsole 的 ConsoleViewer,或者如果我扩展 TextConsole 并创建自己的 ConsoleViewer,则如何将其与启动配置链接(连接 shell 通过管道)?
另外,要获取当前默认控制台,我使用 DebugUITools.getConsole(process)。
抱歉如果我没有提供所有必要的信息;解释有点困难。我很乐意添加更多信息。
一个想法...... 从我理解的来看,我可以使用 createPage(ConsoleView) 从 TextConsole 创建一个 TextConsolePage。一旦我拥有页面,我就可以通过 setViewer(viewer) 设置查看器。在这里,我认为如果我创建自己的查看器(将具有适当的样式小部件),那可能是一个线索。唯一的问题是查看器需要一个复合材料,我似乎无法弄清楚从哪里获取它。
2个回答

2

我一直在查看他们的代码,它比我所需的要详细得多,而且他们似乎已经覆盖了所有内容,并几乎从头开始完成了所有工作。 - nbz
2
是的,我不得不模拟很多东西才能使它正常工作(不幸的是,这不是Eclipse开发人员在创建抽象时考虑的事情之一)。 - Fabio Zadrozny

2
所以我想自己回答这个问题,因为我终于能够完成控制台了。它仍然是一个工作原型,但我想随着你不断添加东西,你可以越来越清理代码。对于我目前的目的,这就是它的工作方式。
如果你想要简短的版本,那么我基本上模仿了Eclipse提供的ProcessConsole,因为这就是我需要的:一个可以连接进程的控制台,但由于ProcessConsole是内部的,所以我喜欢避免扩展那些类。
以下是我用来实现与我的控制台交互的类的概述。我不会给出创建MyConsole的前置条件。基本上,我使用自己的myProcess.getConsole()方法代替了DebugUITools.getConsole(myProcess)MyProcess扩展了RuntimeProcess
class MyConsole extends IOConsole {
 private IOConsoleInputStream fInput;
 private IOConsoleOutputStream fOutput;
 private IStreamsProxy fStreamsProxy;
 private ConsoleHistory history;
 //This is to remember the caret position after the prompt 
 private int caretAtPrompt;
     /* in the console so when you need to replace the command on up and down 
      * arrow keys you have the position. 
      * I just did a caretAtPrompt += String.Length wherever string was 
      * appended to the console. Mainly in the streamlistener and 
      * InputJob unless you specifically output something to the output 
      * stream.
      */
 //In the constructor you assign all the above fields. Below are some 
 //to point out.
 //fInput = getInputStream();
 // fStreamsProxy = process.getStreamsProxy();
 // fOutput = newOutputStream();

 //We must override the following method to get access to the caret
 @Override
 public IPageBookViewPage createPage(IConsoleView view) {
    return new MyConsolePage(this, view);
    }
 //After this I followed the ProcessConsole and added the 
 //InputJob and StreamListener
 //defined in there. 
 }

class MyConsolePage extends TextConsolePage {
 //Not much in this class, just override the createViewer
 // to return MyConsoleViewer
 }

class MyConsoleViewer extends TextConsoleViewer {
 //This is the most important class and most of the work is done here
 //Again I basically copied everything from IOConsoleViewer and then
 //updated whatever I needed
 //I added a VerifyKeyListener for the up and down arrow 
 //keys for the console history

 MyConsoleViewer (Composite parent, MyConsole console) {
  //I have omitted a lot of code as it was too much to put up, 
  //just highlighted a few
  getTextWidget().addVerifyKeyListener(new MyKeyChecker());
  }

 class MyKeyChecker implements VerifyKeyListener {...}

 }

这是ProcessConsole的代码。这里有相关代码。
这是IOConsoleViewer的代码。这里有相关代码。
我创建的ConsoleHistory类只是一个双向字符串列表,用于保存用户输入的所有命令。创建这个类非常简单。
一旦您查看了Eclipse类(ProcessConsoleIOConsoleViewer),实际上就很容易理解了。我在这里没有放太多代码,因为代码量很大。但希望这能给出一些方向,因为当我开始时完全迷失了方向。
如果有人提问,我很乐意回答问题并添加更具体的代码。

你解决了如何在控制台窗口中移动到特定行的问题吗? - Blub
@Blub 你是指将光标移动到特定位置吗? - nbz
是的,不一定,我只希望新位置能够在视图中。假设控制台有多个页面和滚动条。 - Blub
1
@Blub 如果您知道插入符偏移量,您可以在MyConsoleViewer类中使用 getTextWidget().setCaretOffset(<value>)。要将其设置为最后一个位置,您可以使用 - getTextWidget.setCaretOffset(getDocument().getLength()); - nbz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接