diff options
author | Tor Norbye <tnorbye@google.com> | 2013-11-12 10:41:52 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-11-12 10:42:01 -0800 |
commit | 9c6f3112ffe942e4bb0b5d5d8476ce7014499650 (patch) | |
tree | a0a1a2817c17cddc428e1faf8dd7754ab593c0dc /plugins/terminal | |
parent | f88d3e15cd8228cba4070811da68d8ad54d81fd7 (diff) | |
download | idea-9c6f3112ffe942e4bb0b5d5d8476ce7014499650.tar.gz |
Snapshot 205707dc11cdd6508ae84db85d104f834028fd65 from idea/132.1045 of git://git.jetbrains.org/idea/community.git
205707d: support abbreviations in Search Everywhere
9eeb98a: NPE fix
f701598: AA painting for shortcuts
9636e23: add abbreviations
d1f7c58: IDEA-116296 Search match looks terrible under Retina
8bc5adc: AIOOBE
f92fa41: IDEA-116194 "Generate equals() and hashcode()" for final classes should disable "accept subclasses" variant
ec773fc: CCE
9a208ab: selected completion item should be the first or second visible (IDEA-115199)
be542d6: linear-time filterByDumbAwareness
83273e5: faster next/prev occurrence action in the console (IDEA-115163)
d684469: LanguageConsole: shutdown printXXX fiesta. Everyone is advised to use ConsoleView API the right way.
480215a: Merge branch 'master' of git.labs.intellij.net:idea/community
c85aae4: https://android-review.googlesource.com/69716
76daf2e: Heroku integration - show log on redeploy
c567431: Jediterm updated (PY-11368).
5d325de: Accept only terminal tabs on DnD.
a1d5cd4: Merge remote-tracking branch 'origin/master'
0a3bcdb: Jediterm updated.
218607a8: Terminal: support presentation mode.
ea6fd6f: switch on console-content-type highlighting in all language consoles
e824117: Quick fix for RefParserTest
450ecea: suggest scrambled classes on second completion
7ba82d9: NPE fixed
525a30d: cleanup
2fa314d: don't display "Loading spellchecker dictionaries" in status bar (IDEA-115130)
276a47a: don't suggest scrambled classes in autopopup (IDEA-115199)
b4a4b99: temporary fix for layouts of small IDEs
02e07e1: [log] Move SimpleHash from vcs-log-graph to vcs-log-impl
f7b1796: [log] Hash -> int in Graph
0c4d0bb: [log] Don't call new VcsRefImpl() directly, use the factory
4c1c1c2: [log] Memory consumption: Hash -> int. Take 1
2e36939: Improvement from Roman Shevchenko to be compatible with Ubuntu 13.10.
b6edb35: Show pin icon in pinned Find Usages tabs
c143cee: IDEA-110064 JSF 2.2: Pass-through elements: if upper-case symbols are used instead of default 'jsf' namespace prefix, attributes are red-highlihted
3a69458: added actions 'mark/unmark as generated sources root' to popup menu
bdfc48c: Use maven3 importer by default.
d9417b6: Merge remote-tracking branch 'origin/master'
5b526fc: Add pty libs to pycharm community build.
c912c67: add HowTo
6d940b1: depend on PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT if the file cannot be resolved yet
7c63c25: platform: jayatana patched to support Ubuntu 13.10 (sources only)
59622ee: IDEA-116276 Console font is small in Presentation mode
6863abc: IDEA-115889 Framework toolwindows: support scope-based file colors for items
ac0f8ab: obtaining framework libraries from app server: download libraries list asynchronously from server
185804e: refactor supported root type checking according to CR-IC-3056
6b085fe: formatter removes spaces in import statement parentheses (PY-11359)
b04030e: Show pin icon in pinned Find Usages tabs
90ea6d7: do not disable empty frameworks page if no templates available
bb55e29: platform: jayatana sources attached
d1911f7: platform: Ubuntu app menu loading code extracted and corrected
897738a: Cleanup (deprecated code)
56e41fb: Check Grails SDK in background thread, not in the AWT. +review CR-IU @gromopert
fd2b6b3: IDEA-115074 New Project Wizard: Grails: grails-specific settings are missing
a69a88a: spi: decline abstract classes, suggest all available inheritors (IDEA-115502)
eeaee1e: SIOOBE
6cd3cb9: Fix spelling
5f4c814: IDEA-102413 (pointless assertion dropped)
dc455bd: Cleanup (arrangement, formatting)
44590dc: IDEA-25934 Maven: Webapp resources filtering store web resources configuration.
6e65f2b: IDEA-25934 Maven: Webapp resources filtering store web resources configuration.
df137ae: DOM stubs: namespace key index
046e455: Merge remote-tracking branch 'origin/master'
0681517: testdata fixed
dd63221: IDEA-116168 Action creation does not escape special chars in plugin.xml
48fa01e: restore plugin description
d34d829: new project wizard: remote templates
389db71: methods renamed
b07e674: prefer non-qualified xml completion variants (IDEA-115355)
add165a: IDEA-116144 Opening build.gradle of android project fails
d524a84: refixed IDEA-111753 to remove unnecessary dependency on debugger
b8df146: show usages from generated code in separate group (IDEA-97579)
034f42b: removed obsolete 'remote-server-util' module from installation, added new module to git plugin installation
c8deccf: download libraries in parallel (IDEA-88561)
674de91: our LinkedHashMap: added methods to obtain last added key/value
43aced8: Restore context menu after DnD back to Terminal View.
b6987d3: Merge remote-tracking branch 'origin/master'
c147027: Fix: terminal tab doesn't save name change after DnD.
495bda4: JediTerm update to version 1.0
46667e2: Fix closing tab on session end. Fix popup for editor terminal tabs.
fdd3e70: Fix potential NPE.
9ea940a: [git] Fix refresh notification after changing non-active branch hashes
34b357c: more console folding by default
d21cf01: Fix memory leak.
1dcfd64: Fix removing terminal tabs on drag'n'drop.
29a4f60: add accessOrder parameter to our LinkedHashMap
e0ff96d: DockableEditorTabbedContainer shouldn't return root pane as accept area as it makes impossible to add any other dockable container. It is better to return root pane in the special fallback method after we checked all containers.
4b22045: Terminal tabs: drag'n'drop to editor and back implemented.
6ac9ae9: DockableEditor doesn't need EditorWindow reference.
73f7ab5: [log] IDEA-115980 Don't show Git actions if there are no Git roots
7964385: [log] "Go To Commit" action
c647083: [log] Extract the popup text field used for user completion
7e9497a: Merge remote-tracking branch 'origin/master'
0eb8a6f: [log] Fix hidden graph because of the date filter existance
95d5d5b: [log] IDEA-116022 Implement Structure filter for VCS Log & Git
4989fa1: [vcs] VcsStructureChooser: remove dependency on the AbstractVcs.
278cd62: [log] move structure filter implementation to vcs-log-impl
9b5b1c2: Github: change search request parameter
a543347: IDEA-115330 Incorrect "condition is always false"
0b85cc1: trying to make project opening progress information more meaningful (IDEA-115130)
35af155: Don't display empty panel if there are no moreMessage in the dialog
41592ca: [vcs] IDEA-116036 Pressing Escape in Commit/TODO dialog performs commit
7c5ba53: [log] Fix IDEA-115676 once again
8fb8d34: [log] IDEA-116056 Display commit time in details if different from author time
9b6d291: [log] IDEA-116022 Add filter by date
c49b45b: only suppress eager psi creation when there were stubs in the file
f815aa9: our LinkedHashMap clients aren't necessarily aware that it updates its ordering on every get. Let clients specify if they need this feature (IDEA-116222)
6fcd19c: return not-null MODULE_CONTEXT data only for single content roots (IDEA-115422)
0af49e6: fix two psi elements per one ast element in stub-ast switch: psi1 is taken from stub psi2 is eagerly created during chameleon parsing another thread gets the ast when some psi1 parent is already switched and psi1 is not, it walks down the ast and gets psi2
fcfef16: remove big JI sign
2ad7bd2: support for <shortcut>
cd74ff8: IDEA-116206
59b556f: set transparency 20%
152e772: fix missing help button
b8f59ef: add getLanguage() method
25dece1: IDEA-110540 ("String concat (+) and super.toString()" template adds "+ super.toString()" even if no super)
35c07da: new inference: reject isExact for no constructor parameterized class
5fafbd5: EA-51725 - NPE: IntroduceVariableBase.replace
22cf8de: ignore anonymous classes when generating constructors EA-51713 - assert: CreateConstructorMatchingSuperFix$.run
1735391: getWidget method
fcb4970: attempt to fix IDEA-116128 LiveEdit doesn't work correctly for JSP files
36e4932: continue "ability to return list of URLs" — isConfigurationFromContext
d67f88c: Cleanup (formatting)
3112d12: reliably check if a task for debugger manager thread was interrupted
201c7b5: IDEA-75717 ("Referenced checked for null not used inside if" false positive)
795357c: do not suppress file-level inspections
4745efc: continue "ability to return list of URLs" IDEA-115787
43216f8: IDEA-115787 Better resolvement for JSF page URLs
2e6db86: IDEA-100279 ChooseComponentsToExportDialog
72ee12c: fix warning "mac file equals"
19576b2: overrides, cleanup
0a15306: IDEA-100279 git init
b596340: IDEA-100279 xml editor location dialog
3c0f6cd: IDEA-100279 copyright plugin
b7c6e4c: overrides
e9e6eb2: 'Download library' refactored a little
946216e: IDEA-116197 (filter improvements)
9439744: EA-51425 - ISE: MavenUtil.resolveSuperPomFile add assertion.
9c38499: EA-51325 - assert: MavenIndices.createNewDir
9346755: don't log Connection reset by peer
cfb11fa: cleanup
038e39d: IDEA-114461 Structure tool window: Jump to Source (F4) does not move focus to Editor
ed4794e: VcsRootDetector and RootErrorsFinder tests updated
c196ab3: Remove unnecessary check and param from HgRepositoryImpl
b486fcb: template actions are now injection aware
773f5f0: IDEA-102454 Parameter Info: TAB/Shift-TAB and editing does not work in language injected fragment
3b34a0b: IDEA-49273 Injected language: parameter info tooltip disappears on moving caret
7afa57d: move indexer to indexing-impl
4ab17a0: don't shift text range if the element has no last child (PY-11344)
9e3bbe9: don't show "inspect test source" checkbox in PyCharm (PY-1187)
ac7f1b2: IDEA-113483 (action fixed to select directories too)
7bd9931: Emmet: extract SurroundWithEmmetAction
625e81b: don't show "production" and "test" scopes in predefined scopes if current product doesn't support test source roots (PY-7324)
f01a713: grouping by directory uses project-relative paths (PY-11176); rename the action from "Group by package" to "Group by directory" in platform-based IDEs
be45c85: move GeneralFormatterTest to platform-tests; fix NPE in DocumentImpl when running standalone GeneralFormatterTest
4d22f5e: DirectoryIndex: don't include roots from content to projectExcludeRoots set, update projectExcludeRoots on VFS change
02f7305: Merge branch 'master' of git.labs.intellij.net:idea/community
7994da2: External System: test fix Related task: IDEA-79466 gradle support should generate web module configuration
e3cfba1: IDEA-116126 - NoClassDefFound on attempt to deploy to heroku
630eacf: Merge remote-tracking branch 'origin/master'
a902c4e: testdata fixed
db0433c: fix NPE — final class variable is not yet initialized — we must not open connection until debug process class is not constructed.
dd2d5f6: platform: ensure event file validity on dropping symlink target
eaeed33: platform: better pairing of before/after VFS events
97aec30: Cleanup (formatting)
017646f: remove dead code, cleanup
2181005: more templates
ab315c8: new project wizard: template description & count
e789a57: External system: adding TEST_GENERATED source type to ExternalSystemSourceType
62eeca9: new project wizard: adding project templates
25e633c: SimpleColoredComponent: builder style
84c2eb6: ColoredListCellRenderer parameterized
3c567ba: cleanup
ab15886: cleanup
aaad70d: cleanup
81c7d30: update Key.findKeyByName usages due to API changes
41ca0a4: CCE aware API
fe3700f: java call hierarchy extension
51c76a3: Make view meta model extendable
e17daa4: unused methods with strange names deprecated
4910498: service replaced by utility methods
d0fd16f: faster for simple cases
3dd6919: fix CSS completion tests: if the reference starts at completion start location, we do need to overwrite it when Tab is pressed
22c1ef9: Gradle: update to Gradle 1.9-rc-3
7a38323: Pty4j updated.
29ac873: IDEA-97390 Java Debugger: View Text action shows white on white [2]
1c329ac: Merge branch 'master' of git.labs.intellij.net:idea/community
0c60dd9: IDEA-86998 Evaluate expression mixes colorschemas when displaying injected code
ce6fbd9: IDEA-97390 Java Debugger: View Text action shows white on white
a50bd7e: Merge branch 'master' of git.labs.intellij.net:idea/community
8de20e2: remote servers - headers cleanup
c5e1cf7: don't reformat mock variable during control flow building
8e11281: don't walk module src roots in search for .class file source (IDEA-116085)
992d740: cache expected names (IDEA-116085)
10976b3: walk library src roots once when searching for class sources (IDEA-116085)
dfc71fc: fix java pull up refactoring!
4af2a83: Merge remote-tracking branch 'origin/master'
a818922: javadoc: include in classpath only libraries from modules which participate in the scope (IDEA-116083)
38e2991: new inference: do not use nested call args to infer on the top level
465762a: new inference: reject multiple eq bounds
d84a0a0: Darcula eats almost all EDT cpu time
fe23143: IDEA-94922 (Report negatively named boolean variables and suggest to perform 'Invert Boolean' for them)
f637ac6: fix description
9005acd: common "invert boolean" quickfix
9a5bfa9: add #loc's
dd94fc6: fix "No dependencies provided which causes CachedValue to be never recalculated again."
e4cce36: java.lang.IllegalThreadStateException additional handling
1249362: disposed check
0495c47: cleanup
25fc653: extra inspections
8850957: IDEA-101405 Call hierarchy support for Groovy
3026341: hierarchy package
deb52f5: Flat & round stripe buttons (Internal Mode only) v.3, colors improvement
d903511: IDEA-116139 Workaround NPE fix
8fccc30: avoid assertion on file path completion (EA-51068)
fdb9f6e: ctrl+w shouldn't choke on unclosed argument lists (EA-51589)
1de20e6: don't inc modification counter on first load of gant/gradle settings
8a9c177: IDEA-25934 Maven: Webapp resources filtering store web resource configuration.
9553c1a: catch all exceptions that may influence VM attach process
aa8a8e8: IDEA-116146 Search everywhere has small font in Presentation mode
9c7d5d5: #WEB-8915 fixed
5d96196: dfa: flush resource variables when leaving try block
15c0fd6: jsr166e.jar included into standalone jps distribution
edbde43: generics: bounds check should stop expanding nested wildcards up to 2nd level
d991c73: fix invalid file assertion
aae4c5a: IDEA-116049 Mercurial log problem with Mac default locale (x_MacRoman)
08a6b0c: Unnecessary encoding argument in new hg log removed.
5cd75d1: style
5a365fd: fix BooleanParameterInspectionTest
4e2e6ca: [log] IDEA-115966 Show HAND cursor over branch arrows
7793ca6: [log] Collect user information from the whole log
4e8c466: [log] Completion in filter by user
bc4c9f8: [log] intern VcsUsers.
0505705: [log] Encapsulate author & committer into VcsUser
1fb280e: [log] Let VcsLogObjectsFactory be project service & depend on VcsLogManager
2f2f008: Gradle: add Tooling API extra models support. Related task: IDEA-79466 gradle support should generate web module configuration
3c9aa6d: convert EventLogCategory to abstract class
0804cb1: html5 char entities for fragments
0e50db9: #IDEA-116106 fixed
483a5d1: enable entities validation for html5 #WEB-7053 fixed
962e050: generated entities for html 5 chars, use it in resolve and completion
b57823a: Merge remote-tracking branch 'origin/master'
da8e5d0: we must add "http://" prefix if specified path is not absolute
6bb2810: small lens mode fix
88caaf7: Merge remote-tracking branch 'origin/master'
4268072: IDEA-116125 extra gutter in presentation mode
6d03a86: Eliminated dependencies on pthread, glib rec mutex synchronization. A crash fixed.
b5f05f4: Quick fix for not Unity window managers. Should be moved into linux-specific code.
fe27876: WI-14476 When hovering over variable, Expression Evaluation tooltip disappears before I can click the + icon (cherry picked from commit 3034e98)
202e2ae: Cleanup (test)
a5960af: java: no need to check package prefix for annotations on ref adjustment
ab262e2: Cleanup (test)
5b2a86b: IDEA-89720 Preview usages: "select usages to preview" should be shown at the center of panel
7b82bf1: IDEA-116119 Darcula: links are hardly visible on warnings
d2a2cd9: don't hide run configuration type if there are only one irrelevant type (IDEA-116046)
15e08d4: javadoc corrected
5575eb1: hide 'deploy to cloud' run configurations if corresponding cloud isn't configured (IDEA-116046)
3b3c221: WEB-9876 Fuzzy search is still colliding with completion
50bd840: Spock method should be a GrMethod.
5364513: exception-safe rendering
544a580: thread assertion fix
bc4c101: fix NPEs
56940f1: a way to increase dismiss delay
9aee54e: framework version from existing library
37f430f: removing borders automatically
19a21fd: new "Non-varargs method overrides varargs method" inspection
e82e54d: improve description
31fedec: New in 13
0fbffa1: fixed downloading client libraries from modal dialog (IDEA-115975)
5db09f5: CCE from android step fixed
cded14f: IDEA-115064 New Project Wizard: Spring page looks bad: preselected frameworks
e6b1f8e: fix NPE (request status)
8bba7c9: IDEA-115076 Groovy: New Project Wizard: IAE at DialogWrapperPeerFactoryImpl.createPeer() on 'Create Groovy Library'
5a47ef8: app server editor: don't show 'change version' button for app server library
f510156: IDEA-115398 New Project Wizard: libraries downloading doesn't work
3d251be: event log category EP
7d76939: Take shortcuts for next tab and prev tabs from keymap.
be19e2e: Next tab and Previous tab actions.
67310ba: Null class name tolerated
db170d7: Fixed text shaking on tab name editing.
bd3c4bc: Some cleanup.
b27ba6e: IDEA-112596 SQL: MySQL uncomment doesn't work with "--"
a67dac8: IDEA-115954 lens mode warning annotation bubbles overlap text on retina
b6c179c: IDEA-93733 Double line above editor tabs
2c91f79: EA-51491 - assert: DocumentImpl.createRangeMarker
1743e7b: EA-51650 - assert: JavaDocInfoGenerator.getDocComment
16712b8: Todo
f9d2c43: Cleanup (formatting)
38f058d: failing test for PY-10319
dd3f3fa: rename some methods and cleanup code to make logic clearer
aa885ea: report missing identifier after 'as' (PY-9853)
52efcb5: only allow single expression after 'in'; tweak error recovery when waiting for colon (PY-9561)
7f8dc3d: change default match-from-start to false
bfb1819: EA-51669 (unneeded augmentation avoided)
b27e492: platform: extension point declaration moved to correct .xml
4d9e686: sourcemaps: ability to resolve sources relative to generated file
40e08dc: Fix the size changing of text field for terminal tabs.
62223eb: Merge remote-tracking branch 'origin/master'
6c84d33: take synchronized statements into account when mapping local variable names to slots
4e560b6: allow to view hidden items in 'New Run Configuration' popup (IDEA-116046)
37caefe: IDEA-72889 (CodeStyle inspection to check tabs instead of spaces in file)
f345cfd: EA-51469: do not call GemManager.updateGemset(Module) with null
e27287d: ShowSettingUtil: selecting configurable by class is fixed
b9f0e95: new inference: infer recursively for conditional expression
646aea3: new inference: avoid self bounds when possible
a2ad6fd: new inference: accept captured wildcard opening during subtype constraint reduction
66462d0: remove incorrect copyright messages
c3c03a0: don't set default cursor if empty text is invisible
4f009e8: IDEA-115398 New Project Wizard: libraries downloading doesn't work
3607191: Merge remote-tracking branch 'origin/master'
a95509a: extracted method to get/set 'for generated source' option via API
7b00b8f: hide Groovy run configuration if there are no groovy files in project (IDEA-116046)
89f2a76: Minor VFS optimization (cleanup)
0defb40: less spam in the logs when there's PSI/document inconsistency during reference search (IDEA-115950)
29427e7: added service to quickly find modules by module type; hide DevKit and J2ME run configurations if there are no corresponding modules (IDEA-116046)
d031ebc: hide Python run configurations if they are irrelevant (IDEA-116046)
75ca45a: IDEA-116000 Error message shown if hg root marked as git
e9b3a8c: style
24f91c2: IDEA-115474 Maven Dependency template broken in latest Idea Cardea
26b5659: added API to hide irrelevant run configuration types from 'New' popup in 'Edit Configurations' dialog (IDEA-116046)
5b6b259: Merge remote-tracking branch 'origin/master'
0525b10: Revert the change.
4f9d3f0: Disable formatter ranges in formatter off/on tags [CR-IC-2916]
f760c44: IDEA-36685: Provide better 'no matching constructor' warnings where possible
915fb35a: new overload resolution: testdata
3546317: new overload resolution
971909a: method refs: exact tweaks
f6932ac: Merge remote-tracking branch 'origin/master'
c22e14c: JediTerm jar updated.
08eed1d: Merge remote-tracking branch 'origin/master'
5ff6e1a: Merge remote-tracking branch 'origin/master'
feec183: Pty4j with debug info.
08c90e8: Minor VFS optimization
53a81a0: Cleanup (formatting)
dc52633: EA-50578 - assert: TextRange.<init>
b532d92: Merge remote-tracking branch 'origin/master'
aa20e7d: status bar should have a height at least of an icon, even before any icons appear, to prevent unnecessary blinking (IDEA-114453)
1e0e31e: IDEA-112982 Status bar starts with bad layout before project is fully loaded default min height was 1 which made BoxLayout center-align everything along the top border resulting in 2x less memory indicator height
5fdc8f8: Merge branch 'svn_18_2'
cc6dd17: svn: Fixed destroy for process under terminal
9826ae7: external system: EA-51656, check for disposable project components added
7337a62: external system: EA-51656, check for disposable project components added
ea5159b: IDEA-116001 Incorrect behavior of root scanner in case non hg project marked as hg fixed
2186112: Merge remote-tracking branch 'origin/master'
9f02f7e: don't generate icons for IntelliJ laf
0f252a9: IDEA-90751 Scope tabs coloring does not affect hidden tabs pop-up
ab0e88a: cleanup dead code
79bf40e: IDEA-114608 breakpoints dialog: add panel must be at top
d9b94c5: new icons: vendors & sql structure view
5b4b9a7: svn: Do not read from error stream for process under terminal
ca6a8ac: drop command wrapper
5617a42: use correct date format in command to fix reverting changes on file with a sticky date
afbef4d: new inference: mark List::get as inexact
4fde439: EA-51621 - IOE: CheckUtil.checkWritable
eb79b67: EA-51643 - assert: DataManagerImpl$MyDataContext.getData
e1b69a4: new inference: exact method reference: decline constructor with parameter with type parameter of class
664ee85: improve parser recovery if keyword is used as function or class name (PY-8319)
5d6bac5: improve parser recovery if keyword is used as named parameter (PY-8318)
ce1ff5d: if we have only one import candidate, show its name instead of "import this name" (PY-8067)
27c5fbb: Visual Studio keymap maps Shift+F1 to both QuickJavaDoc and ExternalJavaDoc (PY-7291)
baaf551: rename file when renaming class if file name equals lowercased class name (PY-7155)
f52709b: tweak decorator parsing so that following line comment is outside the text range of PyDecorator (PY-5912)
a61112a: don't overwrite reference by Tab if it starts exactly after reference being completed (PY-6095)
12249d1: tab completion for keyword arguments overwrites the = sign (PY-1337(
a351f53: highlight only the last line of string literal when triple quotes are unclosed (PY-1780); allow running StringLiteralQuotesAnnotator in dumb mode
1bf4336: consistent behavior of PyFunction.getContainingClass() in stub-based and non-stub-based cases (PY-1448)
36c20c2: fix caret position after pressing Enter in Python line comment
e55c85f: fix HtmlCompletionTest.testDotTypeWhileActiveLookupInFileReference
a3e89bc: IntelliLang PatternValidator: class parsing errors should not fail the build if the class is not going to be instrumented by the validator. Covered 2 more cases when this check was not performed (IDEA-115189 IntelliLang Pattern Validator: Class not found)
6f7b23e: Merge remote-tracking branch 'origin/master'
c5d7ccd: Merge remote-tracking branch 'origin/master'
946d9ab: svn: terminal: Implemented handling of "unknown host" prompt for ssh
f1e1ceb: IDEA-113191 Used "write" access to sqlite db and try to access db several times if failed
b95367c: svn: Do not handle auth errors when command is finished if in terminal mode
e306801: svn: terminal: Added separate logging for status command output (as there are some issues with terminal output parsing)
f22a4ed: svn: terminal: Implemented cancelling authentication prompts
4e7c774: svn: terminal: Treat stdout lines with svn errors as stderr lines
a48733d: svn: Fixed default focused element for credentials dialog opening (password is focused if username is disabled)
aac45e5: svn: Implemented password prompts for ssh authentication through terminal
b8768d1: svn: Implemented basic svn+ssh authentication using terminal (under svn.use.terminal registry key)
13a217b: svn: Refactored CommandExecutor - ability to write to process input stream, small changes for inheritors
e9ccca6: svn: Moved setting "non-interactive" mode when command executor is created
4092ffa: svn: Added command logging in for non-zero exit code
8441324: Tab name length is limited by 50 in jediterm library.
1c63154: Use JB tabs in terminal(PY-10609). Pass disposable to terminal widget.
2ba2163: Extract method that sets content to the holder.
9c5a392: NPE (IDEA-115607).
Change-Id: I83d19d7826b59dbc1d782247b78553b4632e7635
Diffstat (limited to 'plugins/terminal')
18 files changed, 1100 insertions, 111 deletions
diff --git a/plugins/terminal/lib/jediterm-pty-0.08.jar b/plugins/terminal/lib/jediterm-pty-0.08.jar Binary files differdeleted file mode 100644 index a801f8863790..000000000000 --- a/plugins/terminal/lib/jediterm-pty-0.08.jar +++ /dev/null diff --git a/plugins/terminal/lib/jediterm-pty-1.0.jar b/plugins/terminal/lib/jediterm-pty-1.0.jar Binary files differnew file mode 100644 index 000000000000..bb04f222113f --- /dev/null +++ b/plugins/terminal/lib/jediterm-pty-1.0.jar diff --git a/plugins/terminal/lib/readme.txt b/plugins/terminal/lib/jediterm.txt index d7a8c1fa3353..d7a8c1fa3353 100644 --- a/plugins/terminal/lib/readme.txt +++ b/plugins/terminal/lib/jediterm.txt diff --git a/plugins/terminal/resources/META-INF/terminal.xml b/plugins/terminal/resources/META-INF/terminal.xml index 36500b84045e..ed2a2b56ec64 100644 --- a/plugins/terminal/resources/META-INF/terminal.xml +++ b/plugins/terminal/resources/META-INF/terminal.xml @@ -12,6 +12,8 @@ factoryClass="org.jetbrains.plugins.terminal.TerminalToolWindowFactory" secondary="false"/> <projectConfigurable instance="org.jetbrains.plugins.terminal.TerminalOptionsConfigurable"/> + + <fileEditorProvider implementation="org.jetbrains.plugins.terminal.vfs.TerminalSessionEditorProvider"/> </extensions> <project-components> diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java index 5a3b60727232..121958b849db 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java @@ -7,6 +7,7 @@ import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.actions.CloseAction; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; @@ -82,15 +83,16 @@ public abstract class AbstractTerminalRunner<T extends Process> { protected abstract ProcessHandler createProcessHandler(T process); - public JBTabbedTerminalWidget createTerminalWidget() { + @NotNull + public JBTabbedTerminalWidget createTerminalWidget(@NotNull Disposable parent) { final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider(); - JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() { + JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(myProject, provider, new Predicate<TerminalWidget>() { @Override public boolean apply(TerminalWidget widget) { openSession(widget); return true; } - }); + }, parent); openSession(terminalWidget); return terminalWidget; } @@ -100,21 +102,12 @@ public abstract class AbstractTerminalRunner<T extends Process> { final DefaultActionGroup toolbarActions = new DefaultActionGroup(); final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false); - final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider(); - TerminalWidget widget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() { - @Override - public boolean apply(TerminalWidget widget) { - openSession(widget); - return true; - } - }); - - openSession(widget, createTtyConnector(process)); + final JPanel panel = new JPanel(new BorderLayout()); panel.add(actionToolbar.getComponent(), BorderLayout.WEST); - panel.add(widget.getComponent(), BorderLayout.CENTER); + actionToolbar.setTargetComponent(panel); @@ -127,6 +120,19 @@ public abstract class AbstractTerminalRunner<T extends Process> { toolbarActions.add(createCloseAction(defaultExecutor, contentDescriptor)); + final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider(); + TerminalWidget widget = new JBTabbedTerminalWidget(myProject, provider, new Predicate<TerminalWidget>() { + @Override + public boolean apply(TerminalWidget widget) { + openSession(widget); + return true; + } + }, contentDescriptor); + + openSession(widget, createTtyConnector(process)); + + panel.add(widget.getComponent(), BorderLayout.CENTER); + showConsole(defaultExecutor, contentDescriptor, widget.getComponent()); processHandler.startNotify(); diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java index d46e85868055..f714c38bc3da 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java @@ -1,34 +1,60 @@ package org.jetbrains.plugins.terminal; import com.google.common.base.Predicate; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.fileEditor.impl.EditorTabbedContainer; +import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.project.DumbAwareAction; -import com.jediterm.terminal.ui.JediTermWidget; -import com.jediterm.terminal.ui.TabbedTerminalWidget; -import com.jediterm.terminal.ui.TerminalAction; -import com.jediterm.terminal.ui.TerminalWidget; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.components.JBTextField; +import com.intellij.ui.docking.DockManager; +import com.intellij.ui.docking.DragSession; +import com.intellij.ui.tabs.TabInfo; +import com.intellij.ui.tabs.TabsListener; +import com.intellij.ui.tabs.impl.JBEditorTabs; +import com.intellij.ui.tabs.impl.JBTabsImpl; +import com.intellij.ui.tabs.impl.TabLabel; +import com.jediterm.terminal.ui.*; import com.jediterm.terminal.ui.settings.SettingsProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.terminal.vfs.TerminalSessionVirtualFileImpl; import javax.swing.*; -import java.awt.event.KeyEvent; +import java.awt.*; +import java.awt.event.*; import java.util.List; +import java.util.concurrent.CopyOnWriteArraySet; /** * @author traff */ -public class JBTabbedTerminalWidget extends TabbedTerminalWidget { +public class JBTabbedTerminalWidget extends TabbedTerminalWidget implements Disposable{ + private Project myProject; private final JBTerminalSystemSettingsProvider mySettingsProvider; + private Disposable myParent; - public JBTabbedTerminalWidget(@NotNull JBTerminalSystemSettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) { + public JBTabbedTerminalWidget(@NotNull Project project, + @NotNull JBTerminalSystemSettingsProvider settingsProvider, + @NotNull Predicate<TerminalWidget> createNewSessionAction, @NotNull Disposable parent) { super(settingsProvider, createNewSessionAction); - + myProject = project; + mySettingsProvider = settingsProvider; + myParent = parent; convertActions(this, getActions()); + + Disposer.register(parent, this); + Disposer.register(this, settingsProvider); } public static void convertActions(@NotNull JComponent component, @@ -57,6 +83,300 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget { @Override protected JediTermWidget createInnerTerminalWidget(SettingsProvider settingsProvider) { - return new JBTerminalWidget(mySettingsProvider); + return new JBTerminalWidget(mySettingsProvider, myParent); + } + + @Override + protected TerminalTabs createTabbedPane() { + return new JBTerminalTabs(myProject, myParent); + } + + public class JBTerminalTabs implements TerminalTabs { + private final JBEditorTabs myTabs; + + private TabInfo.DragOutDelegate myDragDelegate = new MyDragOutDelegate(); + + private final CopyOnWriteArraySet<TabChangeListener> myListeners = new CopyOnWriteArraySet<TabChangeListener>(); + + public JBTerminalTabs(@NotNull Project project, @NotNull Disposable parent) { + final ActionManager actionManager = ActionManager.getInstance(); + myTabs = new JBEditorTabs(project, actionManager, IdeFocusManager.getInstance(project), parent) { + @Override + protected TabLabel createTabLabel(TabInfo info) { + return new TerminalTabLabel(this, info); + } + }; + + myTabs.addListener(new TabsListener.Adapter() { + @Override + public void selectionChanged(TabInfo oldSelection, TabInfo newSelection) { + for (TabChangeListener each : myListeners) { + each.selectionChanged(); + } + } + + @Override + public void tabRemoved(TabInfo tabInfo) { + for (TabChangeListener each : myListeners) { + each.tabRemoved(); + } + } + }); + + myTabs.setTabDraggingEnabled(true); + } + + @Override + public int getSelectedIndex() { + return myTabs.getIndexOf(myTabs.getSelectedInfo()); + } + + @Override + public void setSelectedIndex(int index) { + myTabs.select(myTabs.getTabAt(index), true); + } + + @Override + public void setTabComponentAt(int index, Component component) { + //nop + } + + @Override + public int indexOfTabComponent(Component component) { + return 0; //nop + } + + + private TabInfo getTabAt(int index) { + checkIndex(index); + return myTabs.getTabAt(index); + } + + private void checkIndex(int index) { + if (index < 0 || index >= getTabCount()) { + throw new ArrayIndexOutOfBoundsException("tabCount=" + getTabCount() + " index=" + index); + } + } + + + @Override + public JediTermWidget getComponentAt(int i) { + return (JediTermWidget)getTabAt(i).getComponent(); + } + + @Override + public void addChangeListener(TabChangeListener listener) { + myListeners.add(listener); + } + + @Override + public void setTitleAt(int index, String title) { + getTabAt(index).setText(title); + } + + @Override + public void setSelectedComponent(JediTermWidget terminal) { + TabInfo info = myTabs.findInfo(terminal); + if (info != null) { + myTabs.select(info, true); + } + } + + @Override + public JComponent getComponent() { + return myTabs.getComponent(); + } + + @Override + public int getTabCount() { + return myTabs.getTabCount(); + } + + @Override + public void addTab(String name, JediTermWidget terminal) { + myTabs.addTab(createTabInfo(name, terminal)); + } + + private TabInfo createTabInfo(String name, JediTermWidget terminal) { + TabInfo tabInfo = new TabInfo(terminal).setText(name).setDragOutDelegate(myDragDelegate); + return tabInfo + .setObject(new TerminalSessionVirtualFileImpl(tabInfo, terminal, mySettingsProvider)); + } + + public String getTitleAt(int i) { + return getTabAt(i).getText(); + } + + public void removeAll() { + myTabs.removeAllTabs(); + } + + @Override + public void remove(JediTermWidget terminal) { + TabInfo info = myTabs.findInfo(terminal); + if (info != null) { + myTabs.removeTab(info); + } + } + + private class TerminalTabLabel extends TabLabel { + public TerminalTabLabel(final JBTabsImpl tabs, TabInfo info) { + super(tabs, info); + + setOpaque(false); + + setFocusable(false); + + SimpleColoredComponent label = myLabel; + + //add more space between the label and the button + label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + + label.addMouseListener(new MouseAdapter() { + + @Override + public void mouseReleased(MouseEvent event) { + handleMouse(event); + } + + @Override + public void mousePressed(MouseEvent event) { + handleMouse(event); + } + + private void handleMouse(MouseEvent event) { + if (event.isPopupTrigger()) { + JPopupMenu menu = createPopup(); + menu.show(event.getComponent(), event.getX(), event.getY()); + } + else { + myTabs.select(getInfo(), true); + + if (event.getClickCount() == 2 && !event.isConsumed()) { + event.consume(); + renameTab(); + } + } + } + }); + } + + protected JPopupMenu createPopup() { + JPopupMenu popupMenu = new JPopupMenu(); + + TerminalAction.addToMenu(popupMenu, JBTabbedTerminalWidget.this); + + JMenuItem rename = new JMenuItem("Rename Tab"); + + rename.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + renameTab(); + } + }); + + popupMenu.add(rename); + + return popupMenu; + } + + private void renameTab() { + new TabRenamer() { + @Override + protected JTextField createTextField() { + JBTextField textField = new JBTextField() { + private int myMinimalWidth; + + @Override + public Dimension getPreferredSize() { + Dimension size = super.getPreferredSize(); + if (size.width > myMinimalWidth) { + myMinimalWidth = size.width; + } + + return wider(size, myMinimalWidth); + } + + private Dimension wider(Dimension size, int minimalWidth) { + return new Dimension(minimalWidth + 10, size.height); + } + }; + textField.setOpaque(true); + return textField; + } + }.install(getSelectedIndex(), getInfo().getText(), myLabel, new TabRenamer.RenameCallBack() { + @Override + public void setComponent(Component c) { + myTabs.setTabDraggingEnabled(!(c instanceof JBTextField)); + + setPlaceholderContent(true, (JComponent)c); + } + + @Override + public void setNewName(int index, String name) { + setTitleAt(index, name); + } + }); + } + } + + class MyDragOutDelegate implements TabInfo.DragOutDelegate { + + private TerminalSessionVirtualFileImpl myFile; + private DragSession mySession; + + @Override + public void dragOutStarted(MouseEvent mouseEvent, TabInfo info) { + final TabInfo previousSelection = info.getPreviousSelection(); + final Image img = JBTabsImpl.getComponentImage(info); + info.setHidden(true); + if (previousSelection != null) { + myTabs.select(previousSelection, true); + } + + myFile = (TerminalSessionVirtualFileImpl)info.getObject(); + Presentation presentation = new Presentation(info.getText()); + presentation.setIcon(info.getIcon()); + mySession = getDockManager() + .createDragSession(mouseEvent, new EditorTabbedContainer.DockableEditor(myProject, img, myFile, presentation, + info.getComponent().getPreferredSize(), false)); + } + + private DockManager getDockManager() { + return DockManager.getInstance(myProject); + } + + @Override + public void processDragOut(MouseEvent event, TabInfo source) { + mySession.process(event); + } + + @Override + public void dragOutFinished(MouseEvent event, TabInfo source) { + myFile.putUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN, Boolean.TRUE); + + + myTabs.removeTab(source); + + mySession.process(event); + + myFile.putUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN, null); + + + myFile = null; + mySession = null; + } + + @Override + public void dragOutCancelled(TabInfo source) { + source.setHidden(false); + if (mySession != null) { + mySession.cancel(); + } + + myFile = null; + mySession = null; + } + } } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java index 1ae988d6c7b9..767df1e3612c 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java @@ -22,6 +22,7 @@ package org.jetbrains.plugins.terminal; import com.google.common.base.Predicate; import com.intellij.ide.GeneralSettings; import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry; import com.intellij.openapi.editor.impl.FontInfo; @@ -52,7 +53,7 @@ import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.io.IOException; -public class JBTerminalPanel extends TerminalPanel implements FocusListener { +public class JBTerminalPanel extends TerminalPanel implements FocusListener, TerminalSettingsListener, Disposable { private final JBTerminalSystemSettingsProvider mySettingsProvider; public JBTerminalPanel(@NotNull JBTerminalSystemSettingsProvider settingsProvider, @@ -73,6 +74,8 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener { registerKeymapActions(this); addFocusListener(this); + + mySettingsProvider.addListener(this); } private static void registerKeymapActions(final TerminalPanel terminalPanel) { @@ -200,5 +203,15 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener { public FontInfo fontForChar(final char c, @JdkConstants.FontStyle int style) { return ComplementaryFontsRegistry.getFontAbleToDisplay(c, style, mySettingsProvider.getColorScheme().getConsoleFontPreferences()); } + + @Override + public void fontChanged() { + reinitFontAndResize(); + } + + @Override + public void dispose() { + mySettingsProvider.removeListener(this); + } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java index f2fe5dd28061..4adeb3cab133 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java @@ -1,8 +1,10 @@ package org.jetbrains.plugins.terminal; -import com.intellij.application.options.OptionsConstants; +import com.google.common.collect.Sets; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.editor.colors.*; @@ -25,20 +27,37 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; -import java.util.EnumMap; +import java.util.*; import java.util.List; -import java.util.Map; /** * @author traff */ -class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { - - private final EditorColorsScheme myColorScheme; +class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider implements Disposable { + private Set<TerminalSettingsListener> myListeners = Sets.newHashSet(); + + private final MyColorSchemeDelegate myColorScheme; JBTerminalSystemSettingsProvider() { myColorScheme = createBoundColorSchemeDelegate(null); + + UISettings.getInstance().addUISettingsListener(new UISettingsListener() { + @Override + public void uiSettingsChanged(UISettings source) { + int size; + if (UISettings.getInstance().PRESENTATION_MODE) { + size = UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE; + } + else { + size = myColorScheme.getGlobal().getConsoleFontSize(); + } + + if (myColorScheme.getConsoleFontSize() != size) { + myColorScheme.setConsoleFontSize(size); + fireFontChanged(); + } + } + }, this); } @Override @@ -52,6 +71,16 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { } @Override + public KeyStroke[] getNextTabKeyStrokes() { + return getKeyStrokesByActionId("NextTab"); + } + + @Override + public KeyStroke[] getPreviousTabKeyStrokes() { + return getKeyStrokesByActionId("PreviousTab"); + } + + @Override public ColorPalette getTerminalColorPalette() { return new JBTerminalSchemeColorPalette(myColorScheme); } @@ -181,10 +210,15 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { } @NotNull - public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) { + private static MyColorSchemeDelegate createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) { return new MyColorSchemeDelegate(customGlobalScheme); } + @Override + public void dispose() { + + } + private static class MyColorSchemeDelegate implements EditorColorsScheme { private final FontPreferences myFontPreferences = new FontPreferences(); @@ -192,14 +226,15 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { private final HashMap<ColorKey, Color> myOwnColors = new HashMap<ColorKey, Color>(); private final EditorColorsScheme myCustomGlobalScheme; private Map<EditorFontType, Font> myFontsMap = null; - private int myMaxFontSize = OptionsConstants.MAX_EDITOR_FONT_SIZE; - private int myFontSize = -1; private String myFaceName = null; private EditorColorsScheme myGlobalScheme; + private int myConsoleFontSize = -1; + private MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) { myCustomGlobalScheme = globalScheme; updateGlobalScheme(); + initFonts(); } private EditorColorsScheme getGlobal() { @@ -213,17 +248,17 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { protected void initFonts() { - String editorFontName = getEditorFontName(); - int editorFontSize = getEditorFontSize(); + String consoleFontName = getConsoleFontName(); + int consoleFontSize = getConsoleFontSize(); myFontPreferences.clear(); - myFontPreferences.register(editorFontName, editorFontSize); + myFontPreferences.register(consoleFontName, consoleFontSize); myFontsMap = new EnumMap<EditorFontType, Font>(EditorFontType.class); - Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize); - Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize); - Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize); - Font boldItalicFont = new Font(editorFontName, Font.BOLD | Font.ITALIC, editorFontSize); + Font plainFont = new Font(consoleFontName, Font.PLAIN, consoleFontSize); + Font boldFont = new Font(consoleFontName, Font.BOLD, consoleFontSize); + Font italicFont = new Font(consoleFontName, Font.ITALIC, consoleFontSize); + Font boldItalicFont = new Font(consoleFontName, Font.BOLD | Font.ITALIC, consoleFontSize); myFontsMap.put(EditorFontType.PLAIN, plainFont); myFontsMap.put(EditorFontType.BOLD, boldFont); @@ -274,29 +309,22 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { @NotNull @Override public FontPreferences getFontPreferences() { - return myFontPreferences; + return myGlobalScheme.getFontPreferences(); } @Override public void setFontPreferences(@NotNull FontPreferences preferences) { - preferences.copyTo(myFontPreferences); - initFonts(); + throw new IllegalStateException(); } @Override public int getEditorFontSize() { - if (myFontSize == -1) { - return getGlobal().getEditorFontSize(); - } - return myFontSize; + return getGlobal().getEditorFontSize(); } @Override public void setEditorFontSize(int fontSize) { - if (fontSize < 8) fontSize = 8; - if (fontSize > myMaxFontSize) fontSize = myMaxFontSize; - myFontSize = fontSize; - initFonts(); + } @Override @@ -311,16 +339,12 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { @Override public String getEditorFontName() { - if (myFaceName == null) { - return getGlobal().getEditorFontName(); - } - return myFaceName; + return getGlobal().getEditorFontName(); } @Override public void setEditorFontName(String fontName) { - myFaceName = fontName; - initFonts(); + throw new IllegalStateException(); } @Override @@ -366,39 +390,50 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { public void updateGlobalScheme() { myGlobalScheme = myCustomGlobalScheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : myCustomGlobalScheme; - int globalFontSize = getGlobal().getEditorFontSize(); - myMaxFontSize = Math.max(OptionsConstants.MAX_EDITOR_FONT_SIZE, globalFontSize); } @NotNull @Override public FontPreferences getConsoleFontPreferences() { - return getGlobal().getConsoleFontPreferences(); + return myFontPreferences; } @Override public void setConsoleFontPreferences(@NotNull FontPreferences preferences) { - getGlobal().setConsoleFontPreferences(preferences); + preferences.copyTo(myFontPreferences); + initFonts(); } @Override public String getConsoleFontName() { - return getGlobal().getConsoleFontName(); + if (myFaceName == null) { + return getGlobal().getConsoleFontName(); + } + else { + return myFaceName; + } } @Override public void setConsoleFontName(String fontName) { - getGlobal().setConsoleFontName(fontName); + myFaceName = fontName; + initFonts(); } @Override public int getConsoleFontSize() { - return getGlobal().getConsoleFontSize(); + if (myConsoleFontSize == -1) { + return getGlobal().getConsoleFontSize(); + } + else { + return myConsoleFontSize; + } } @Override public void setConsoleFontSize(int fontSize) { - getGlobal().setConsoleFontSize(fontSize); + myConsoleFontSize = fontSize; + initFonts(); } @Override @@ -411,4 +446,18 @@ class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider { getGlobal().setConsoleLineSpacing(lineSpacing); } } + + public void addListener(TerminalSettingsListener listener) { + myListeners.add(listener); + } + + public void removeListener(TerminalSettingsListener listener) { + myListeners.remove(listener); + } + + public void fireFontChanged() { + for (TerminalSettingsListener l : myListeners) { + l.fontChanged(); + } + } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java index 3150cc9582ca..79d8bfe3361f 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java @@ -1,5 +1,7 @@ package org.jetbrains.plugins.terminal; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import com.intellij.ui.components.JBScrollBar; import com.jediterm.terminal.TerminalStarter; import com.jediterm.terminal.TtyConnector; @@ -12,19 +14,23 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; -public class JBTerminalWidget extends JediTermWidget { +public class JBTerminalWidget extends JediTermWidget implements Disposable{ - public JBTerminalWidget(JBTerminalSystemSettingsProvider settingsProvider) { + public JBTerminalWidget(JBTerminalSystemSettingsProvider settingsProvider, Disposable parent) { super(settingsProvider); JBTabbedTerminalWidget.convertActions(this, getActions()); + + Disposer.register(parent, this); } @Override protected JBTerminalPanel createTerminalPanel(@NotNull SettingsProvider settingsProvider, @NotNull StyleState styleState, @NotNull BackBuffer backBuffer) { - return new JBTerminalPanel((JBTerminalSystemSettingsProvider)settingsProvider, backBuffer, styleState); + JBTerminalPanel panel = new JBTerminalPanel((JBTerminalSystemSettingsProvider)settingsProvider, backBuffer, styleState); + Disposer.register(this, panel); + return panel; } @Override @@ -36,4 +42,8 @@ public class JBTerminalWidget extends JediTermWidget { protected JScrollBar createScrollBar() { return new JBScrollBar(); } + + @Override + public void dispose() { + } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java index 36596348d998..4d93dd9fc46e 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java @@ -3,14 +3,12 @@ package org.jetbrains.plugins.terminal; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import icons.TerminalIcons; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; /** * @author traff @@ -48,16 +46,8 @@ public class OpenLocalTerminalAction extends AnAction implements DumbAware { }, true); } - @Nullable + @NotNull public static LocalTerminalDirectRunner createTerminalRunner(Project project) { - String[] terminalCommand; - if (SystemInfo.isWindows) { - terminalCommand = new String[]{"cmd.exe"}; - } - else { - terminalCommand = new String[]{"/bin/bash", "--login"}; - } - return new LocalTerminalDirectRunner(project); } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsListener.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsListener.java new file mode 100644 index 000000000000..75698809d7f5 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsListener.java @@ -0,0 +1,8 @@ +package org.jetbrains.plugins.terminal; + +/** + * @author traff + */ +public interface TerminalSettingsListener { + void fontChanged(); +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java index c3f49f958ed8..14b992a7c143 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java @@ -4,7 +4,6 @@ import com.intellij.icons.AllIcons; import com.intellij.notification.EventLog; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.SimpleToolWindowPanel; @@ -13,8 +12,13 @@ import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.openapi.wm.ex.ToolWindowManagerListener; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.awt.RelativeRectangle; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.docking.DockContainer; +import com.intellij.ui.docking.DockManager; +import com.intellij.ui.docking.DockableContent; import com.intellij.util.ui.UIUtil; import com.jediterm.terminal.ui.JediTermWidget; import com.jediterm.terminal.ui.TabbedTerminalWidget; @@ -22,6 +26,7 @@ import com.jediterm.terminal.ui.TerminalWidget; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.terminal.vfs.TerminalSessionVirtualFileImpl; import javax.swing.*; import java.awt.*; @@ -37,6 +42,8 @@ public class TerminalView { private final Project myProject; + private TerminalDockContainer myDockContainer; + public TerminalView(Project project) { myProject = project; } @@ -52,22 +59,7 @@ public class TerminalView { toolWindow.setToHideOnEmptyContent(true); if (terminalRunner != null) { - myTerminalWidget = terminalRunner.createTerminalWidget(); - myTerminalWidget.addTabListener(new TabbedTerminalWidget.TabListener() { - @Override - public void tabClosed(JediTermWidget terminal) { - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - hideIfNoActiveSessions(toolWindow, myTerminalWidget); - } - }); - } - }); - } - - if (myTerminalWidget != null) { - Content content = createToolWindowContentPanel(terminalRunner, myTerminalWidget, toolWindow); + Content content = createTerminalInContentPanel(terminalRunner, toolWindow); toolWindow.getContentManager().addContent(content); @@ -98,11 +90,17 @@ public class TerminalView { } }); } + + if (myDockContainer == null) { + myDockContainer = new TerminalDockContainer(toolWindow); + + Disposer.register(myProject, myDockContainer); + DockManager.getInstance(myProject).register(myDockContainer); + } } - private Content createToolWindowContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner, - @NotNull JBTabbedTerminalWidget terminalWidget, - @NotNull ToolWindow toolWindow) { + private Content createTerminalInContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner, + final @NotNull ToolWindow toolWindow) { SimpleToolWindowPanel panel = new SimpleToolWindowPanel(false, true) { @Override public Object getData(@NonNls String dataId) { @@ -110,18 +108,34 @@ public class TerminalView { } }; - panel.setContent(terminalWidget.getComponent()); + final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false); + content.setCloseable(true); + + myTerminalWidget = terminalRunner.createTerminalWidget(content); + myTerminalWidget.addTabListener(new TabbedTerminalWidget.TabListener() { + @Override + public void tabClosed(JediTermWidget terminal) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (myTerminalWidget != null) { + hideIfNoActiveSessions(toolWindow, myTerminalWidget); + } + } + }); + } + }); + + panel.setContent(myTerminalWidget.getComponent()); panel.addFocusListener(createFocusListener()); - ActionToolbar toolbar = createToolbar(terminalRunner, terminalWidget, toolWindow); + ActionToolbar toolbar = createToolbar(terminalRunner, myTerminalWidget, toolWindow); toolbar.getComponent().addFocusListener(createFocusListener()); toolbar.setTargetComponent(panel); panel.setToolbar(toolbar.getComponent()); - final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false); - content.setCloseable(true); - content.setPreferredFocusableComponent(terminalWidget.getComponent()); + content.setPreferredFocusableComponent(myTerminalWidget.getComponent()); return content; } @@ -152,11 +166,10 @@ public class TerminalView { openSession(terminal, terminalRunner); } - private void openSession(ToolWindow toolWindow, AbstractTerminalRunner terminalRunner) { + private void openSession(@NotNull ToolWindow toolWindow, @NotNull AbstractTerminalRunner terminalRunner) { if (myTerminalWidget == null) { - myTerminalWidget = terminalRunner.createTerminalWidget(); toolWindow.getContentManager().removeAllContents(true); - final Content content = createToolWindowContentPanel(null, myTerminalWidget, toolWindow); + final Content content = createTerminalInContentPanel(null, toolWindow); toolWindow.getContentManager().addContent(content); } else { @@ -194,7 +207,7 @@ public class TerminalView { }, true); } - private static void hideIfNoActiveSessions(final ToolWindow toolWindow, JBTabbedTerminalWidget terminal) { + private static void hideIfNoActiveSessions(@NotNull final ToolWindow toolWindow, @NotNull JBTabbedTerminalWidget terminal) { if (terminal.isNoActiveSessions()) { toolWindow.getContentManager().removeAllContents(true); } @@ -234,4 +247,101 @@ public class TerminalView { hideIfNoActiveSessions(myToolWindow, myTerminal); } } + + /** + * @author traff + */ + public class TerminalDockContainer implements DockContainer { + private ToolWindow myTerminalToolWindow; + + public TerminalDockContainer(ToolWindow toolWindow) { + myTerminalToolWindow = toolWindow; + } + + @Override + public RelativeRectangle getAcceptArea() { + return new RelativeRectangle(myTerminalToolWindow.getComponent()); + } + + @Override + public RelativeRectangle getAcceptAreaFallback() { + return getAcceptArea(); + } + + @NotNull + @Override + public ContentResponse getContentResponse(@NotNull DockableContent content, RelativePoint point) { + return isTerminalSessionContent(content) ? ContentResponse.ACCEPT_MOVE : ContentResponse.DENY; + } + + @Override + public JComponent getContainerComponent() { + return myTerminalToolWindow.getComponent(); + } + + @Override + public void add(@NotNull DockableContent content, RelativePoint dropTarget) { + if (isTerminalSessionContent(content)) { + TerminalSessionVirtualFileImpl terminalFile = (TerminalSessionVirtualFileImpl)content.getKey(); + myTerminalWidget.addTab(terminalFile.getName(), terminalFile.getTerminal()); + terminalFile.getTerminal().setNextProvider(myTerminalWidget); + } + } + + private boolean isTerminalSessionContent(DockableContent content) { + return content.getKey() instanceof TerminalSessionVirtualFileImpl; + } + + @Override + public void closeAll() { + + } + + @Override + public void addListener(Listener listener, Disposable parent) { + + } + + @Override + public boolean isEmpty() { + return false; + } + + @Nullable + @Override + public Image startDropOver(@NotNull DockableContent content, RelativePoint point) { + return null; + } + + @Nullable + @Override + public Image processDropOver(@NotNull DockableContent content, RelativePoint point) { + return null; + } + + @Override + public void resetDropOver(@NotNull DockableContent content) { + + } + + @Override + public boolean isDisposeWhenEmpty() { + return false; + } + + @Override + public void showNotify() { + + } + + @Override + public void hideNotify() { + + } + + @Override + public void dispose() { + + } + } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java new file mode 100644 index 000000000000..5dc7b629af57 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditor.java @@ -0,0 +1,181 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.terminal.vfs; + +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import com.intellij.codeHighlighting.BackgroundEditorHighlighter; +import com.intellij.ide.structureView.StructureViewBuilder; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorLocation; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.fileEditor.FileEditorStateLevel; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.UserDataHolderBase; +import com.jediterm.terminal.TtyConnectorWaitFor; +import com.jediterm.terminal.ui.TerminalAction; +import com.jediterm.terminal.ui.TerminalActionProviderBase; +import com.jediterm.terminal.ui.settings.TabbedSettingsProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeListener; +import java.util.List; +import java.util.concurrent.Executors; + +/** + * @author traff + */ +public class TerminalSessionEditor extends UserDataHolderBase implements FileEditor { + + private Project myProject; + private final TerminalSessionVirtualFileImpl myFile; + private final TtyConnectorWaitFor myWaitFor; + + public TerminalSessionEditor(Project project, @NotNull TerminalSessionVirtualFileImpl terminalFile) { + myProject = project; + myFile = terminalFile; + + final TabbedSettingsProvider settings = myFile.getSettingsProvider(); + + myFile.getTerminal().setNextProvider(new TerminalActionProviderBase() { + @Override + public List<TerminalAction> getActions() { + return Lists.newArrayList( + new TerminalAction("Close Session", settings.getCloseSessionKeyStrokes(), new Predicate<KeyEvent>() { + @Override + public boolean apply(KeyEvent input) { + handleCloseSession(); + return true; + } + }).withMnemonicKey(KeyEvent.VK_S) + ); + } + }); + + myWaitFor = new TtyConnectorWaitFor(myFile.getTerminal().getTtyConnector(), Executors.newSingleThreadExecutor()); + + myWaitFor + .setTerminationCallback(new Predicate<Integer>() { + @Override + public boolean apply(Integer integer) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + FileEditorManagerEx.getInstanceEx(myProject).closeFile(myFile); + } + }); + + return true; + } + }); + } + + private void handleCloseSession() { + myFile.getTerminal().close(); + } + + @NotNull + @Override + public JComponent getComponent() { + return myFile.getTerminal(); + } + + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return myFile.getTerminal(); + } + + @NotNull + @Override + public String getName() { + return myFile.getName(); + } + + @NotNull + @Override + public FileEditorState getState(@NotNull FileEditorStateLevel level) { + return FileEditorState.INSTANCE; + } + + @Override + public void setState(@NotNull FileEditorState state) { + + } + + @Override + public boolean isModified() { + return false; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public void selectNotify() { + + } + + @Override + public void deselectNotify() { + + } + + @Override + public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) { + + } + + @Override + public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) { + + } + + @Nullable + @Override + public BackgroundEditorHighlighter getBackgroundHighlighter() { + return null; + } + + @Nullable + @Override + public FileEditorLocation getCurrentLocation() { + return null; + } + + @Nullable + @Override + public StructureViewBuilder getStructureViewBuilder() { + return null; + } + + @Override + public void dispose() { + Boolean closingToReopen = myFile.getUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN); + myWaitFor.detach(); + if (closingToReopen == null || !closingToReopen) { + myFile.getTerminal().close(); + } + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java new file mode 100644 index 000000000000..cf1fd5978f5e --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionEditorProvider.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.terminal.vfs; + +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorPolicy; +import com.intellij.openapi.fileEditor.FileEditorProvider; +import com.intellij.openapi.fileEditor.FileEditorState; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +/** + * @author traff + */ +public class TerminalSessionEditorProvider implements FileEditorProvider, DumbAware { + @Override + public boolean accept(@NotNull Project project, @NotNull VirtualFile file) { + return file instanceof TerminalSessionVirtualFileImpl; + } + + @NotNull + @Override + public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) { + return new TerminalSessionEditor(project, (TerminalSessionVirtualFileImpl)file); + } + + @Override + public void disposeEditor(@NotNull FileEditor editor) { + Disposer.dispose(editor); + } + + @NotNull + @Override + public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) { + return FileEditorState.INSTANCE; + } + + @Override + public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) { + + } + + @NotNull + @Override + public String getEditorTypeId() { + return "terminal-session-editor"; + } + + @NotNull + @Override + public FileEditorPolicy getPolicy() { + return FileEditorPolicy.HIDE_DEFAULT_EDITOR; + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java new file mode 100644 index 000000000000..bb545a18504c --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionFileType.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.terminal.vfs; + +import com.intellij.openapi.fileTypes.ex.FakeFileType; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author traff + */ +public class TerminalSessionFileType extends FakeFileType { + + public final static TerminalSessionFileType INSTANCE = new TerminalSessionFileType(); + + @NotNull + public String getName() { + return "Terminal Session"; + } + + @NotNull + public String getDescription() { + return getName() + " Fake File Type"; + } + + public boolean isMyFileType(VirtualFile file) { + return file instanceof TerminalSessionVirtualFileImpl; + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java new file mode 100644 index 000000000000..b642f7fbd349 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionVirtualFileImpl.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author cdr + */ +package org.jetbrains.plugins.terminal.vfs; + +import com.intellij.testFramework.LightVirtualFile; +import com.intellij.ui.tabs.TabInfo; +import com.jediterm.terminal.ui.JediTermWidget; +import com.jediterm.terminal.ui.settings.TabbedSettingsProvider; +import org.jetbrains.annotations.NotNull; + +/** + * @author traff + */ +public class TerminalSessionVirtualFileImpl extends LightVirtualFile { + private final JediTermWidget myTerminal; + private TabbedSettingsProvider mySettingsProvider; + + private final TabInfo myTabInfo; + + public TerminalSessionVirtualFileImpl(@NotNull TabInfo tabInfo, + @NotNull JediTermWidget terminal, + @NotNull TabbedSettingsProvider settingsProvider) { + myTabInfo = tabInfo; + myTerminal = terminal; + mySettingsProvider = settingsProvider; + setFileType(TerminalSessionFileType.INSTANCE); + setWritable(true); + } + + public JediTermWidget getTerminal() { + return myTerminal; + } + + @NotNull + public String getName() { + return myTabInfo.getText(); + } + + public TabbedSettingsProvider getSettingsProvider() { + return mySettingsProvider; + } +} diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java new file mode 100644 index 000000000000..b1439ccd069c --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/vfs/TerminalSessionsVFS.java @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.terminal.vfs; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem; +import com.intellij.util.containers.BidirectionalMap; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.Map; + +/** + * @author traff + */ +public class TerminalSessionsVFS extends DummyFileSystem { + @NonNls private static final String PROTOCOL = "terminalDummy"; + @NonNls private static final String PATH_PREFIX = "terminal"; + @NonNls private static final String PROTOCOL_SEPARATOR = ":/"; + + private final BidirectionalMap<Project, String> myProject2Id = new BidirectionalMap<Project, String>(); + private final Map<String, VirtualFile> myCachedFiles = new HashMap<String, VirtualFile>(); + + private ProjectManagerAdapter myProjectManagerListener; + + public static TerminalSessionsVFS getTerminalSessionVFS() { + return (TerminalSessionsVFS)VirtualFileManager.getInstance().getFileSystem(PROTOCOL); + } + + @Override + @Nullable + public VirtualFile createRoot(String name) { + return null; + } + + public void initListener() { + if (myProjectManagerListener == null || ApplicationManager.getApplication().isUnitTestMode()) { + myCachedFiles.clear(); + myProject2Id.clear(); + for (Project project : ProjectManager.getInstance().getOpenProjects()) { + onProjectOpened(project); + } + } + if (myProjectManagerListener == null) { + myProjectManagerListener = new ProjectManagerAdapter() { + @Override + public void projectOpened(final Project project) { + onProjectOpened(project); + } + + @Override + public void projectClosed(final Project project) { + onProjectClosed(project); + } + }; + ProjectManager.getInstance().addProjectManagerListener(myProjectManagerListener); + } + } + + public void onProjectClosed(final Project project) { + myCachedFiles.clear(); + myProject2Id.remove(project); + } + + public void onProjectOpened(final Project project) { + myProject2Id.put(project, project.getLocationHash()); + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + @Override + public void run() { +// DatabaseEditorHelper.installEditorFactoryListener(project); TODO:? + } + }); + } + + @Override + public VirtualFile findFileByPath(@NotNull String path) { + throw new UnsupportedOperationException("not implemented yet"); //TODO: implement TerminalSessionManager and store there terminal sessions by handle ID + } + + public static String getPath(Project project, final String dataSourceId, final String tableName, String typeName) { + return PATH_PREFIX + typeName + PROTOCOL_SEPARATOR + project.getLocationHash() + "/" + dataSourceId + "/" + tableName; + } + + @Override + @NotNull + public String getProtocol() { + return PROTOCOL; + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException { + throw new UnsupportedOperationException("renameFile not supported"); + } + + @Override + @NotNull + public String extractPresentableUrl(@NotNull String path) { + VirtualFile file = findFileByPath(path); + return file != null ? file.getPresentableName() : super.extractPresentableUrl(path); + } +} diff --git a/plugins/terminal/terminal.iml b/plugins/terminal/terminal.iml index ce9ede14fcf9..f2d64268fe8f 100644 --- a/plugins/terminal/terminal.iml +++ b/plugins/terminal/terminal.iml @@ -13,7 +13,7 @@ <orderEntry type="module-library"> <library name="jediterm-pty"> <CLASSES> - <root url="jar://$MODULE_DIR$/lib/jediterm-pty-0.08.jar!/" /> + <root url="jar://$MODULE_DIR$/lib/jediterm-pty-1.0.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES /> |