This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Provide multiple IOProvider support, adjust I/O APIs to be extensible.
Created attachment 76621 [details] diff
Please review. Additional info on http://wiki.netbeans.org/IOEnhancements
Could you please tell us against which revision the diff was created (several hunks fail against the current head)?
Against 5147ca0722fb.
Thanks for providing this API, seems to work well in the test runner. Just a couple of comments: EM01: It'd be nice to be able to control what popup actions are available in the provided output tab. For example, in the test runner closing the only tab doesn't make much sense. But not a big deal really (I can bind it to close the whole result window). EM02: Using the API together with extexecution is slightly cumbersome. My use case is that I execute a script and display its output (after filtering) in the output window and in the output panel of the test runner. Now, for extexecution I pass a set of LineConvertors for hyperlinking output. For the IO tab, I need to pass OutputListeners to do the same. And I also need to pass all the lines I want to display both to extexecution and to the IO tab in the test runner. Ideally I'd like use the very same IO tab instance that extexecution uses, but this doesn't seem to be possible at the moment -- IOProvider.getDefault().getIO(String, Action[], IoEmbedder) returns a new instance even if a tab with the given name exists.
PH01: Is there any use case for IOExecution feature class? All other feature classes define attributes of the component (font, color, position...) while IOExecution is defining kind of an action. You can use the extexecution to do the same (on any IO regardless its features). I understand that the IOExecution would be easier to use however it seems to be usable only for really basic commands as the interface does not provide a way how to handle PATH or env. variables. I'm also not sure how I would use the IOExecution - I have to check whether it is supported. If it is not I can't execute the action. It makes perfect sense for other feature classes as a can still do some io even without colors, fonts etc. In case of IOExecution I have to use a different API (extexecution, terminal emulator or my own) and at that point I have no reason to use IOExecution. Am I missing something?
> EM01 I can add one more parameter to IOEmbedder.add() to specify "mask" for common actions (close, clear,...) to control which of them should be enabled (or present). > EM02 If you want to get existing IO with given name you can use IOProvider.getIO(name, false). I am not sure I understand what exactly you need. If you need to duplicate some output in both OW and test runner window you need two instances of IO. > PH01 IOExecution is meant for accessing additional feature of Terminal Emulator. AFAIK Terminal Emulator should be accessible only via its IOProvider implementation in the beginning (no other public API). Or am I wrong? I think it can be useful for execution of commands or programs which requires terminal capabilities e.g. top or mc (which I guess cannot be handled by extexecution on any IO). I put there just executeCommand() method but I ask Ivan to comment it from Terminal Emulator point of view so I expect he will add things he needs.
>> EM01 I meant IOProvider.getIO();
>> PH01: Ok, makes more sense now. Let's wait for terminal emulator requirements (IOExecution seems to be placeholder now). Once finished it would be great to have a usecase/snippet explaining the usage in arch.xml.
>> EM01 > I can add one more parameter to IOEmbedder.add() to specify "mask" for common actions (close, clear,...) to control > which of them should be enabled (or present). That'd be great! >> EM02 > If you want to get existing IO with given name you can use IOProvider.getIO(name, false). I am not sure I understand > what exactly you need. If you need to duplicate some output in both OW and test runner window you need two instances of IO. I want to get an existing IO, namely the one that extexecution creates. If I use IOProvider.getIO(name, false), how do I embed that into the test runner output panel? In other words, I want to the same IO instance to be displayed both in the OW and in the test runner. Of course, I'd also need a way to get rid of the toolbar actions in the embedded mode.
> EM02 > I want to get an existing IO, namely the one that extexecution creates. If I use IOProvider.getIO(name, false), how do > I embed that into the test runner output panel? In other words, I want to the same IO instance to be displayed both in > the OW and in the test runner. Of course, I'd also need a way to get rid of the toolbar actions in the embedded mode. It would be necessary to support multiple views (components) for single IO instance. This is not possible now and implementation would require significant rewrite of output2. Moreover I am not sure if it is really needed - I would say if the content is identical it should be displayed only once and you should decide whether it should be in OW or test runner window.
> It would be necessary to support multiple views (components) for single IO instance. This is not possible now and > implementation would require significant rewrite of output2. I can live with the current API. > Moreover I am not sure if it is really needed - I would say > if the content is identical it should be displayed only once and you should decide whether it should be in OW or test > runner window. On this point I have to disagree. Arguably displaying output next to the test result tree makes sense (instead of displaying it only in the OW), but some users prefer not to use the test runner window at all and rely solely on the OW. Even if I were to display output only in the test runner, I still need to run my scripts using extexecution, meaning I'm still forced to deal both with LineConvertors and OutputListeners. Again, I don't insist this -- the API under review is usable as it is and I'll rather have it now than wait for any rewrite.
[JG01] Token name should be 'org.openide.windows.IOEmbedder$IOEmbedderProvider'. [JG02] IOEmbedder.Provider would be a more natural nested class name anyway. [JG03] You should not create a public package named 'org.netbeans.core.io.ui.api'. In fact the package does not seem to exist anyway, so why is it mentioned in project.xml? [JG04] IOWindowAction could probably be replaced with TopComponent.openAction. [JG05] Shouldn't there be known impls of all these features before we commit them to a public API? None seem to be shown in the patch.
> [JG01] Token name should be 'org.openide.windows.IOEmbedder$IOEmbedderProvider'. OK. > [JG02] IOEmbedder.Provider would be a more natural nested class name anyway. OK. > [JG03] You should not create a public package named 'org.netbeans.core.io.ui.api'. In fact the package does not seem > to exist anyway, so why is it mentioned in project.xml? It somehow remained from "previous" version in project.xml while it was not visible in IDE. I'll remove it. > [JG04] IOWindowAction could probably be replaced with TopComponent.openAction. I can replace it. But then the action would be bound to specific TopComponent right? In current state IOWindow action opens the TopComponent according to default IOEmbedder.Provider from Lookup. > [JG05] Shouldn't there be known impls of all these features before we commit them to a public API? None seem to be > shown in the patch. I tried to put together the features that I expect to be supported by output2 or Terminal Emulator. I can postpone their commit until individual impls are finished. The main reason for putting them on review with other changes is to review the InputOutput extension approach so Ivan Soleimanipour (Terminal Emulator) can code against it.
JG04 - never mind. JG05 - showing feature interfaces as examples is fine, but I would not recommend committing to them until there are concrete working impls.
NOTE: I will refer to some terminal code in the following. The modules and packages are located in lib.terminalemulator/demosrc/*. I implemented an IOPRovider based on o.n.modules.terminal.api.Terminal, which is in project lib.termnalemulator/demosrc/Terminal. It can be found by name, "embedded" and supports some of the "features". I've come away from this experience thinking that maybe we're trying too hard to find commonality between two things which actually may not have that much in common, especially once you get down to the details. I'm not saying that it's impossible but if we want to try for it it'll be a fair amount of work still. Many of the details will become clear in the following comments but there is one theme that winds itself through many of the issues: IS01: Programmatic vs interpretive interaction. [ warning: this gets a bit philosophicsl :-] The main point of this analysis is so that I can refer to "programmatic" vs "interpretive" in what follows. An output device may be directly programmable with methods which add text, move the caret or change text rendering attributes. Or, it may "interpret" to the content sent to it which may include special control sequences to move the cursor or change text rendering attributes. In this case most of the smarts are in the applications that use them: vi, emacs, more, top, mc (midnight commander), readline etc. Now, Term is fundamentally interpretive but as is clear from it's API, especially that of ActiveTerm, it can be used programmatically. In my experience the programmatic mode typically involves: - output-only mode (except for hyperlinks) - no history - programmatic manipulation of the view like in a text editor. - output-to-output filtering of the kind suported by o.n.lib.termsupport.LineFilter. And the interpretive mode involves: - implict shuttling of input and output to and from some external process. IOProvider, in contrast, was developed for programmatic manipulation. I'm saying this because of the early focus on "internal execution" in NetBeans and it's legacy println's and also because of the nature of some of the proposed "features" in this API like IOCoorLines, IOColorPRint, IOCOlors and IOPosition. They makse sense only in a programmatic model. IOProvider can still work in "intepretive" mode but it requires ... - explicit, shuttling of input and output to and from some external process. This becomes implicit through the IOExecution function. - output-to-methodcall filtering, of the kind supported by ExternalExecution. -------------------------- containment -------------------------------------- Nice factoring job, IOEmbdder. IS02: Embedder -> Container One "embeds" journalists with military forces to report on war activities. IMO it would be better to call the class, and it's relatives, IOContainer. IS03: IOEmbedder.CallBacks I'd like to recommend that this class be a nested class of InputOutput and perhaps be called something like IOContained. It really describes the obligations of an InputOutput implementation towards it's container and should be "nearer" InputOutput than IOEmbedder. CallBacks is too generic and non-descriptive a name. IS04: IOTab. This looks to me like an implementation class. It's not referred to or used by any of the other classes. IS05: Multiplexing actions vs multiplexing "Find" The existing IO window implementation multiplexes the actions control area between the selected InputOutput. In my analogous implmentation of o.n.modules.terminal.api.TerminalConatiner I introduced a find control area, similar to the one in the NB editor, which is multiplexed between Terminals. It requires an interface a bit more complicated than passing additionalActions as implemented by o.n.lib.termsupport.FindState. IS06: JPopupMenu.putClientProperty("container", IOEmbedder) Can an IOEmbedder be set as the "container" property of a JPopupMenu? ------------------------ feature classes ------------------------------------ IS07: General comment on "feature classes" There's something unsettling about this design. Before I programmed in C++ I programmed in C like this: Class_method(Class *this, <other params>) { } ... Class * c = Class_new(); Class_method(c, 1); // first parameter analogous to 'this' C++ took the convention and added it to the language: Class::method(<other params>) { } ... Class * c = new Class; c->method(1); // 'this' is 'c'. Now all the impl. methods of the "feature classes" (from the Wiki page) ... - Are static methods. I.e. plain old C function calls. - Take a "this", i.e. InputOutput, as their first parameter. Again, very C-like. - Do lookup for every call which reminds me of MFC event dispatch. This is _still_ "object oriented" but only the way a C programmer would've done it. Otherwise it completely bypasses Java's dynamic dispatch mechanism. Surely there's a more modern way of doing this? IS08: Why no throws of UnsupportedOperationException? The use case is like this: if (IOFontSize.isSupported(io)) { IOFontSize.setSize(io, 10); } But a programmer may forget to call isSupported. IS09: A general comment on colors ANSI Terminals, unlike JDocuments, cannot, in general, accept arbitrary color specifications. The base standard has several codes which map to some basic colors. Some terminals, including Term, have extensions to support more colors but the number of simultaneously displayable colors is limited (e.g. 8) . I've handled IOColorLines and IOColorPrint by allocating colors out of the extension set but if the user sends one Color too many it will get ignored. IS10: IOColorLines and IOColorPrint. Term can implement these. However ... - IOColorPrint seems like a superset of IOColorLines at least as far as color is concerned. - IOColorLines associates a hyperlink with a whole line while Term can do hyperlinks within a line. These featuers have a definite programmatic bent to them. For contrast consider http://wiki.netbeans.org/TerminalEmulatorHyperlinking. IS11: Background colors Terminals, as well as JDocuments, can handle background colors, but we don't have an API for that. IS12: IOColors. A logical interface. However ... - I'd like to point out that attempting to separate output and error color is misguided. It will never work for external execution. Why? Because stdout and stderr are _always_ combined at the src. (In unix terminology fd 2 is a dup of fd 1). If one doesn't do this then stdout and stderr invariably appear out of order. A good example is the output of 'make' ... make echoes what it's doing and compilers might output error messages on stderr. Unless everything goes to one file descriptor the output will be out of order. - Coloring of _input_ is harder than it looks with terminals because the echoing of input is done by the OS, not the terminal. And the OS knows nothing about coloring things. Alternatively, in raw mode, the application manages it's own colors. I can at best make setOutColor() change the foreground color of Term but that's about it. This "feature" can only be effective in a programmatic mode, where some internal thread writes to either an error or an output stream but, paradoxically, the notion of stdout and stderr has to do with _external_ processes. Internal output can just switch colors and do it's own io redirection. IS13: IODocking. I really don't get this feature. I believe it's about moving an IO tab to be a top-level window. But this is similar enough to the ability to drag and drop a tab from one TC to another that there should be some overlap, shouldn't there? There also seems to be no support for undocked containers. Does this mean that an InputOutput is responsible for it's own window when undocked? Can _other_ TC's be docked into it? IS14: IOExecution. This is underpowered. There's more than a 'String command' that governs execution. Generate a javadoc from lib.terminalemulator/demosrc/lib.richexecution and check out classes Command, Shell and Program. At the least you need - Ability to control the run directory. - Explicit argv setting so that you're not at the mercy of shell command parsing and quoting semantics. - Mgmt of environment variables. NOTE: lib.richexecution.Program doesn't do this yet! - Debuggers need to assign pty's directly so IOExecution isn't enough. More specifically ... when you're debugging under a GUI, the gui creates a terminal, and a pty pair. It then passes the name of one end of the pty to the debugger (dbx, gdb). The debugger, when running the debuggee, will fork/exec it and connect it's i/o to the pty. In short, the execution is done by the debugger. NOTE: my terminal stuff doesn't support this yet either, but it's imperative for CND/SunStudio. IS15: IOExecution and additionalActions Suppose one creates an InputOutput with no additionalActions. Suppose then one calls IOExecution.executeCommand(). Shoudn't then the Rerun and Kill actions be _added_? In my implementation of TerminalContainer I have a setActions() as opposed to passing them in a constructor In other words, the set of actions shouldn't have to be "final". IS16: Repeatability/Termination of IOExecution What should happen if you call IOExecution.executeCommand() while a command is already running? How can you programmatically terminate the command which is running? IS17: IOFont and IOFontSize. a) Users have been asking for "font choice". See IZ's 29604, 40033, 43165, 45174, 55455, 87536. b) Both output2 and Term require fixed width fonts. Term requires it "by definition". Term and output2 require it for speed as explained by Tim B. many times over. At the UI level I've been experimenting with giving the users a font-chooser which limits the choice to fixed width fonts. From that experience I conclude that there are three choices available: - FontChoice.MONOSPACED User can only set size and style (bold, italic etc) but they're always stuck with Java "Monospaced" no matter what Font the set. - FontChoice.FIXED Users can set the font family to any "fixed-width" (*) font. This requires a specialized font chooser (which I have in the works) and some kind of agreement with IO that the font it get's in it's setFont() is guaranteed to be fixed. - FontChoice.ANY Any font can be passed in and IO has to manage as best as it can. If it gets a true fixed-width font then it's no problem, otherwise it has to do stuff like finding the widest character and using it as the basic cell-size; an algorithm which is very unlikley to yield good aesthetic results. *: Java fonts do not have an explicit property of being fixed width! The best one can do is measure the width of the first 256 unicode characters and if they are all the same decide that the font is fixed width. In my experience the result will vary if the style is changed and, while I haven't witnessed it, there's no reason to believe that changing the point size will not change the fixed'ness of a Font. .. Ergo ... setting the fontsize while allowing arbitrary fonts is not guaranteed to work. The safest thing to do is to alway use java "Monospaced" and just allow changing it's size. But then even Monospaced isn't always safe. See http://defect.opensolaris.org/bz/show_bug.cgi?id=2024 IS18: IOFont and IOFontSize - Should clarify that they don't change the current font/size but change it globally for all text past and future. IS19: IOPosition. This is incomaptible with ... - The notion of historyLength. If the output window has history what do line numbers mean? There is actually a way out of this. Please see "Coordinate systems" in the javadoc for class Term for an analysis. Also see Term.setAnchored(). - The notion that terminals know about Position. JDocument, and the output2 implementation, use Position as their basic coordinate system. It's a 1-dimensional quantity. Classic terminals use row/col, a 2-dimensional quantity, as their basic coordinate system. Position-based systems like JDocument can "do" lines but 2-D systems cannot. IS20: options How are options to be addressed? Should there be one generic set of options for "IO windows" or should there be per-implementation options panels? I have, for example, o.n.lib.termsupport.TermOptions[Panel] which covers a bunch of stuff that these features don't cover.
> IS01: Programmatic vs interpretive interaction. Yes, API is "programmatic" so the client can control different implementations in the same way. "Interpretive" interaction usually requires no API but the format and/or support of "control sequences" can vary for different impls. > IS02: Embedder -> Container OK, I can rename it to IOContainer. > IS03: IOEmbedder.CallBacks IOEmbedder.CallBacks describes obligations of IOEmbedder to JComponent corresponding to InputOutput. It is nested class so I think its name is descriptive enough within the context (like IOEmbedder.Provider). > IS04: IOTab It provides API for adding icon/tooltip to IO tab (requested by #60862). > IS05: Multiplexing actions vs multiplexing "Find" additionalActions are meant for client actions specific to InputOutput instance a not for IOProvider-specific actions. If you want to expose additional actions it should be available in context menu or toolbar should be present inside IO tab area. > IS06: JPopupMenu.putClientProperty("container", IOEmbedder) Context menu is specific to individual IO tab (JComponent), so I guess you can put any property you need to it. > IS07: General comment on "feature classes" While this can look odd on first look it provides a space for future changes which may be needed. If there would be public abstract methods instead as you are suggesting and clients would get "feature class" instance directly it would be harder (or impossible) to make certain changes. E.g. I/O API now gains control between client calls and IOProvider code so it can redirect calls in static methods to whatever it may need in future. > IS08: Why no throws of UnsupportedOperationException? I think it is better to silently fail in case when feature is not supported. Client can quickly "try and switch" to different IOProvider without care which additional features are supported. I have no strong opinion here, I can change it. > IS09: A general comment on color I think your approach is fine. > IS10: IOColorLines and IOColorPrint Yes, IOColorLines is for IOProviders which can support only colors for whole line. We can add additional methods to IOColorPrint to support hyperlinks within a line. > IS11: Background colors Feel free to introduce new "feature classes" for features you want to support. > IS12: IOColors We can add to Javadoc a note that in certain implementations out/err may not be separated and/or add method to query if it is true for specified IO. > IS13: IODocking OK, maybe programmatic support for docking/undocking is not needed. Let's ignore it. > IS14: IOExecution As I already wrote in "> PH01" it is up to you to decide what you want in this class. It was meant directly for TE "command execution" feature. Feel free to add anything you need. > IS15: IOExecution and additionalActions As I wrote in "> IS05" I think IOProvider specific actions should not be mixed with "client actions". You can add your actions either to context menu or to some toolbar inside tab. If you meant that "client actions" (additionalActions) should be adjustable during life of IO tab it can be done but there is no such request. > IS16: Repeatability/Termination of IOExecution As I wrote in "> IS14" - add methods you need (e.g. for termination, for query about running command) or add to Javadoc contract details - e.g. exception will be thrown if command was not finished. > IS17: IOFont and IOFontSize. I would leave it on implementation to choose best possible match or we can add method which will query impl. about supported fonts. You can support only IOFontSize in TE if you wish. > IS18: IOFont and IOFontSize OK, I will add it to Javadoc. > IS19: IOPosition. I am not sure what incompatibility you mean. The line number is what you call Absolute coordinates, each line printed is identified by its unique line number (0, 1, ...). IOHistoryLength controls how many lines are held in history. If you want you can support other coordinate systems. > IS20: options I think the options should be per-implementation (the feature set and therefore options will be different).
Created attachment 77148 [details] updated diff
Requested changes are included in updated patch. If there are no objections I will integrate tomorrow (patch includes "feature classes" but they will be integrated separately with corresponding implementations as recommended).
Thanks for review. core-main #3234c129f8ca
I was on vacation so I couldn't respond earlier. > IS03: IOEmbedder.CallBacks Perhaps I'm misunderstanding but it looks like whoever add's themselves to an IOEmbedder can (has to?) provide an implementation of Callbacks. I would expect that 'comp' and 'cb' would be the same object. that is why I said that Callbacks describes the obligation of an InputOutput implementation. > IS05: Multiplexing actions vs multiplexing "Find" Let me clarify my comment. The IOEmbedder has a generic area for containing action buttons. I'm proposing that it should also contain a generic area for containing "Find" controls and an APi for interacting with find state. See following attached screenshot. > IS06: JPopupMenu.putClientProperty("container", IOEmbedder) Please take a look at output2/.../Controller: Controller.java: popup.putClientProperty ("container", win); //NOI18N Controller.java: popup.putClientProperty ("component", tab); //NOI18N The "container" property doesn't refer to the owner of the menu but has some specific output2-related semantics. What I'm asking is whether things will continue to work if an IOEmbedder is set as the "container" property. > IS07: General comment on "feature classes" I understand the rationale, but .... a) Each individual feature is still an abstract class and if a new abstract method is added to it, it will break compatibility. What do we gain here? b) A lookup() per method call seems inefficient. At the moment the current set of features seems unlikley to be called often, but that may change. If I were using this API I wouldn't touch the static feature methods. Instead I'd create a wrapper class per IO type do the lookups at constructor time and cache the "cookies" and delegate through them. > IS19: IOPosition. Yes, absolute line coordinates will work with IOPOsitions line attribute. However, The IOPosition feature also requires tracking of Position and that is not supportable by the TE. First ... do we need Position granularity? If we're scrolling line shold be enough. In any case, a more genric approach may be to use an opaque Mark object.
Created attachment 77272 [details] screenshot of Find functionality
>> IS03: IOEmbedder.CallBacks Callbacks provides some optional (cb may be null) notifications from IOContainer to JComponent corresponding to IO. It may be the same object as comp. Also these notifications are UI specific so I think it belongs to IOContainer and not InputOutput as you suggested. >> IS05: Multiplexing actions vs multiplexing "Find" Maybe. I am not sure if such panel should not be rather implemented by individual IOProviders. I would say there will be more IOContainer impls than IOProvider impls. >> IS06: JPopupMenu.putClientProperty("container", IOEmbedder) It seems you are referring to "old" output2 implementation before it was refactored to "new version". There is nothing like it in output2 now. >> IS07: General comment on "feature classes" a) You can add method with default implementation instead of abstract method. If 100% compatibility would be needed new feature class can be introduced (and you can forward calls from "version 1" feature class to "version 2" feature class). b) Caching can be added if Lookup performance would be a problem. >> IS19: IOPosition The position granularity was meant to support also horizontal scrolling (if wrapping is disabled). Maybe it is better to use opaque marker as you suggested and let the implementation decide: public abstract class IOPosition { ... public interface Position { void scrollTo(); } public static Position currentPosition(InputOutput io) { ... } ... }
Integrated into 'main-golden', will be available in build *200902241401* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress) Changeset: http://hg.netbeans.org/main/rev/3234c129f8ca User: Tomas Holy <t_h@netbeans.org> Log: #157911: IO enhancements
> >> IS07: General comment on "feature classes" > a) You can add method with default implementation instead of abstract method. If 100% compatibility would be needed new > feature class can be introduced (and you can forward calls from "version 1" fe ature class to "version 2" feature class). > b) Caching can be added if Lookup performance would be a problem. Cacheing in this context is crazy talk... Isn't something like this a bit more efficient wrt cacheing? Each user would implement their "favorite" front-end. This is like the old "cookie" approach. class MyInputOutput implements InputOutput, IOPosition, IOFont ... { private InputOutput delegate; IOPosition ioPosition; IOFont ioFont; MyInputOutput(InputOutput delegate) { this.delegate = delegate; ioPosition = delegate.lookup(IOPosition.class); ioFont = delegate.lookup(IOFont.class); } // Delegations of regular InputOutput to delegate public OutputWriter getOut() { return delegate.getOut(); } ... // Delegations of IOPosition to ioPosition public long currentPos() { return ioPosition.currentPos(); } ... } But this can't be done because IOPosition's methods are protected and IOPosition isn't an interface. > > >> IS19: IOPosition > The position granularity was meant to support also horizontal scrolling (if wr apping is disabled). Maybe it is better to > use opaque marker as you suggested and let the implementation decide: > public abstract class IOPosition { > ... > public interface Position { > void scrollTo(); > } > public static Position currentPosition(InputOutput io) { > ... > } > ... > } Note that we'll still need scrollToPos(Mark) and scrollToLine(mark) where the first one pays attention to column and the second one doesn't. > On PH01, IS14: IOExecution. I'm voting to postpone this one ... As I've written in personal communication one needs to separate the following: - Program: specification of what and how is to be executed. Includes args, working dir env, host? etc. - Executor(): Program -> Process - Process - IOShuttle: Machinery for moving IO between process and "IO device" Filtering, of the kind implemented in ExtExecution would go here for example. I'm kicking myself for not paying attention to ExtExecution earlier and for exmaple insisting that execution and filtering at least go into different packages. Sometimes the IOShuttling is hidden or implicit like for example in NativeExecutions's external terminal and some of my terminal code. - IODevice: Internal termulator, external termulator, IO window etc. So, I would've liked to have IOExecution.executeCommand() take a Program as input. However the trend seems to be towards factory-like things like ExternalProcessBuilder and NativeprocessBuilder which are _combinations_ of Program (because of addArgument()) and Executor (because of call()).
[JG06] Constants in IOColors should probably be an enum OutputType. Also Javadoc is missing @param type.
> [JG06] core-main #c43c7be6d18a
Integrated into 'main-golden', will be available in build *200903101401* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress) Changeset: http://hg.netbeans.org/main/rev/b846993e69a9 User: Tomas Holy <t_h@netbeans.org> Log: #157911: implementation of some 'feature' classes
Integrated into 'main-golden', will be available in build *200903111543* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress) Changeset: http://hg.netbeans.org/main/rev/c43c7be6d18a User: Tomas Holy <t_h@netbeans.org> Log: #157911: Changing IOColors constants to enum