runned cargo fmt on crate code

This commit is contained in:
TimonPost 2018-07-01 22:43:43 +02:00
parent 4a943c124e
commit 223b353101
50 changed files with 1157 additions and 1260 deletions

View File

@ -2,39 +2,56 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="310aeab2-4737-4e8e-b7eb-0aac10d104a3" name="Default" comment="">
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/first_depth_search/map.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/first_depth_search/mod.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/first_depth_search/variables.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/mod.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/shared/environment.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/color/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/color/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/raw_mode.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/raw_mode.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/terminal.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/cursor/ansi_cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/ansi_cursor.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/cursor/cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/cursor.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/cursor/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/cursor/winapi_cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/winapi_cursor.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/unix_kernel/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/unix_kernel/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/manager/ansi_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/ansi_manager.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/manager/manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/manager.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/manager/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/manager/win_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/win_manager.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/environment.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/environment.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/functions.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/functions.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/macros.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/macros.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/raw.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/raw.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/screen.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/screen.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/traits.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/traits.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/command_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/command_manager.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/commands/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/commands/shared_commands.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/shared_commands.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/commands/unix_command.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/unix_command.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/commands/win_commands.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/win_commands.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/context.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/context.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/state/state_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/state_manager.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/color/ansi_color.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/ansi_color.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/color/color.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/color.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/color/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/color/winapi_color.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/winapi_color.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/styles/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/styles/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/styles/objectstyle.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/styles/objectstyle.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style/styles/styledobject.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/styles/styledobject.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/terminal/ansi_terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/ansi_terminal.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/terminal/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/terminal/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/terminal.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/terminal/winapi_terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/winapi_terminal.rs" afterDir="false" />
</list>
@ -47,88 +64,11 @@
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="cursor.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cursor/cursor.rs">
<file leaf-file-name="raw.rs" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/shared/raw.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408">
<caret line="313" column="11" selection-start-line="313" selection-start-column="11" selection-end-line="313" selection-end-column="11" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="bin.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="459">
<caret line="27" column="61" selection-start-line="27" selection-start-column="61" selection-end-line="27" selection-end-column="61" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="winapi_cursor.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/cursor/winapi_cursor.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="498">
<caret line="66" column="25" selection-start-line="66" selection-start-column="25" selection-end-line="66" selection-end-column="25" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="alternate_screen.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="screen.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/shared/screen.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="340">
<caret line="26" column="11" selection-start-line="26" selection-start-column="11" selection-end-line="26" selection-end-column="11" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="terminal.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/terminal/terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="742">
<caret line="197" column="11" selection-start-line="197" selection-start-column="11" selection-end-line="197" selection-end-column="11" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="kernel.rs" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="540">
<caret line="203" column="5" selection-start-line="203" selection-start-column="5" selection-end-line="203" selection-end-column="5" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="mod.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/kernel/mod.rs">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file leaf-file-name="winapi_color.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/style/color/winapi_color.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="158">
<caret line="64" column="69" selection-start-line="64" selection-start-column="69" selection-end-line="64" selection-end-column="69" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="ansi_terminal.rs" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/terminal/ansi_terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="391">
<caret line="45" column="66" selection-start-line="45" selection-start-column="66" selection-end-line="45" selection-end-column="66" />
<state relative-caret-position="357">
<caret line="53" lean-forward="true" selection-start-line="53" selection-end-line="53" />
</state>
</provider>
</entry>
@ -209,7 +149,6 @@
<option value="$PROJECT_DIR$/src/terminal/mod.rs" />
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/terminal.rs" />
<option value="$PROJECT_DIR$/src/style/styles/styledobject.rs" />
<option value="$PROJECT_DIR$/src/shared/raw.rs" />
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs" />
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/color/mod.rs" />
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs" />
@ -248,6 +187,7 @@
<option value="$PROJECT_DIR$/src/terminal/ansi_terminal.rs" />
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs" />
<option value="$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs" />
<option value="$PROJECT_DIR$/src/shared/raw.rs" />
</list>
</option>
</component>
@ -622,12 +562,12 @@
<workItem from="1530289442537" duration="10502000" />
<workItem from="1530344478032" duration="18289000" />
<workItem from="1530446561530" duration="7222000" />
<workItem from="1530473645162" duration="3874000" />
<workItem from="1530473645162" duration="4134000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="681698000" />
<option name="totallyTimeSpent" value="681958000" />
</component>
<component name="ToolWindowManager">
<frame x="-8" y="-8" width="2576" height="1056" extended-state="6" />
@ -699,27 +639,6 @@
<option name="myLimit" value="2678400000" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="114" selection-start-line="1" selection-start-column="114" selection-end-line="1" selection-end-column="114" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/manager/mod.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408">
<caret line="24" column="47" selection-start-line="24" selection-start-column="47" selection-end-line="24" selection-end-column="47" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-msvc/lib/rustlib/src/rust/src/libcore/ops/drop.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="94" column="10" selection-start-line="94" selection-start-column="10" selection-end-line="94" selection-end-column="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/state/state_manager.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="442">
@ -862,13 +781,6 @@
<state relative-caret-position="-255" />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="187">
<caret line="11" column="31" selection-start-line="11" selection-start-column="31" selection-end-line="11" selection-end-column="31" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-msvc/lib/rustlib/src/rust/src/liballoc/rc.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="275">
@ -918,17 +830,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="7" selection-start-line="1" selection-start-column="7" selection-end-line="1" selection-end-column="7" />
<folding>
<element signature="e#346#347#0" expanded="true" />
<element signature="e#379#380#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/terminal/winapi_terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="424">
@ -936,13 +837,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="297">
<caret line="43" column="7" selection-start-line="43" selection-start-column="7" selection-end-line="43" selection-end-column="7" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/shared/functions.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="228">
@ -950,13 +844,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="544">
<caret line="32" column="23" selection-start-line="32" selection-start-column="23" selection-end-line="32" selection-end-column="23" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/manager/manager.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408">
@ -973,25 +860,22 @@
</entry>
<entry file="file://$PROJECT_DIR$/src/style/color/winapi_color.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="158">
<caret line="64" column="69" selection-start-line="64" selection-start-column="69" selection-end-line="64" selection-end-column="69" />
<state relative-caret-position="141">
<caret line="63" column="69" selection-start-line="63" selection-start-column="69" selection-end-line="63" selection-end-column="69" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/terminal/ansi_terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="391">
<caret line="45" column="66" selection-start-line="45" selection-start-column="66" selection-end-line="45" selection-end-column="66" />
<state relative-caret-position="357">
<caret line="43" column="66" selection-start-line="43" selection-start-column="66" selection-end-line="43" selection-end-column="66" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/mod.rs">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="459">
<caret line="27" column="61" selection-start-line="27" selection-start-column="61" selection-end-line="27" selection-end-column="61" />
<state relative-caret-position="442">
<caret line="26" column="61" selection-start-line="26" selection-start-column="61" selection-end-line="26" selection-end-column="61" />
</state>
</provider>
</entry>
@ -1004,36 +888,80 @@
</entry>
<entry file="file://$PROJECT_DIR$/src/terminal/terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="742">
<caret line="197" column="11" selection-start-line="197" selection-start-column="11" selection-end-line="197" selection-end-column="11" />
<state relative-caret-position="844">
<caret line="200" column="11" selection-start-line="200" selection-start-column="11" selection-end-line="200" selection-end-column="11" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" />
<state relative-caret-position="187">
<caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cursor/cursor.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408">
<caret line="313" column="11" selection-start-line="313" selection-start-column="11" selection-end-line="313" selection-end-column="11" />
<state relative-caret-position="459">
<caret line="316" column="11" selection-start-line="316" selection-start-column="11" selection-end-line="316" selection-end-column="11" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/cursor/winapi_cursor.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="498">
<caret line="66" column="25" selection-start-line="66" selection-start-column="25" selection-end-line="66" selection-end-column="25" />
<state relative-caret-position="566">
<caret line="60" column="25" selection-start-line="60" selection-start-column="25" selection-end-line="60" selection-end-column="25" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="246">
<caret line="79" column="13" lean-forward="true" selection-start-line="79" selection-start-column="13" selection-end-line="79" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/mod.rs">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="1" column="7" selection-start-line="1" selection-start-column="7" selection-end-line="1" selection-end-column="7" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="540">
<caret line="203" column="5" selection-start-line="203" selection-start-column="5" selection-end-line="203" selection-end-column="5" />
<state relative-caret-position="98">
<caret line="204" column="18" selection-start-line="204" selection-start-column="18" selection-end-line="204" selection-end-column="18" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="544">
<caret line="32" column="23" selection-start-line="32" selection-start-column="23" selection-end-line="32" selection-end-column="23" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="187">
<caret line="11" column="31" selection-start-line="11" selection-start-column="31" selection-end-line="11" selection-end-column="31" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/src/shared/macros.rs">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/src/shared/raw.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="357">
<caret line="53" lean-forward="true" selection-start-line="53" selection-end-line="53" />
</state>
</provider>
</entry>

View File

@ -1,7 +1,7 @@
//! This bin folder can be used to try the examples out located in the examples directory.
//!
//! All you need to do is:
//!
//!
//! - Download the crossterm source code.
//! - Add this in the Cargo.toml file:
//! ``` [[bin]]
@ -13,13 +13,12 @@
extern crate crossterm;
mod terminal;
mod cursor;
mod color;
mod cursor;
mod program_examples;
mod terminal;
fn main() {
use crossterm::Context;
{
@ -29,4 +28,4 @@ fn main() {
println!("count: {}", std::rc::Rc::strong_count(&context));
}
}
}

View File

@ -1,25 +1,24 @@
//!
//!
//! Examples of coloring the terminal.
//!
extern crate crossterm;
use self::crossterm::style::{ Color };
use self::crossterm::style::Color;
use self::crossterm::terminal;
use self::crossterm::Context;
/// print some red font | demonstration.
pub fn paint_foreground()
{
pub fn paint_foreground() {
let context = Context::new();
let terminal = terminal::terminal(context.clone());
// Pass an string to the `paint()` method with you want to paint.
// Pass an string to the `paint()` method with you want to paint.
// This will give you an object back wits can be styled and displayed.
let mut styledobject = terminal.paint("Red font");
// Call the method `with()` on the object given by `paint()` and pass in any Color from the Color enum.
styledobject = styledobject.with(Color::Red);
// Print the object to the console and see the result.
// Print the object to the console and see the result.
println!("{}", styledobject);
// Crossterm provides method chaining so that the above points can be inlined.
@ -27,17 +26,16 @@ pub fn paint_foreground()
}
/// print some font on red background | demonstration.
pub fn paint_background()
{
pub fn paint_background() {
let context = Context::new();
let terminal = terminal::terminal(context.clone());
// Pass an string to the `paint()` method with you want to paint.
// Pass an string to the `paint()` method with you want to paint.
// This will give you an object back wits can be styled and displayed.
let mut styledobject = terminal.paint("Red background color");
// Call the method `on()` on the object given by `paint()` and pass in an Color from the Color enum.
styledobject = styledobject.on(Color::Red);
// Print the object to the console and check see the result
// Print the object to the console and check see the result
println!("{}", styledobject);
// Crossterm provides method chaining so that the above points can be inlined.
@ -45,12 +43,11 @@ pub fn paint_background()
}
/// print font with fore- background color | demonstration.
pub fn paint_foreground_and_background()
{
pub fn paint_foreground_and_background() {
let context = Context::new();
let terminal = terminal::terminal(context.clone());
// Pass an string to the `paint()` method with you want to paint.
// Pass an string to the `paint()` method with you want to paint.
// This will give you an object back wits can be styled and displayed.
let mut styledobject = terminal.paint("Red font on blue background color");
/* Foreground color:
@ -67,35 +64,60 @@ pub fn paint_foreground_and_background()
println!("{}", styledobject);
// Crossterm provides method chaining so that the above points can be inlined.
println!("{}", terminal.paint("Red font on blue background color").with(Color::Red).on(Color::Blue));
println!(
"{}",
terminal
.paint("Red font on blue background color")
.with(Color::Red)
.on(Color::Blue)
);
}
/// Print all available foreground colors | demonstration.
pub fn print_all_foreground_colors()
{
pub fn print_all_foreground_colors() {
let context = Context::new();
let terminal = terminal::terminal(context.clone());
println!("Black : \t {}", terminal.paint("").with(Color::Black));
println!("Red : \t\t {}", terminal.paint("").with(Color::Red));
println!("Dark Red: \t {}", terminal.paint("").with(Color::DarkRed));
println!(
"Dark Red: \t {}",
terminal.paint("").with(Color::DarkRed)
);
println!("Green : \t {}", terminal.paint("").with(Color::Green));
println!("Dark Green : \t {}", terminal.paint("").with(Color::DarkGreen));
println!(
"Dark Green : \t {}",
terminal.paint("").with(Color::DarkGreen)
);
println!("Yellow : \t {}", terminal.paint("").with(Color::Yellow));
println!("Dark Yellow : \t {}", terminal.paint("").with(Color::DarkYellow));
println!(
"Dark Yellow : \t {}",
terminal.paint("").with(Color::DarkYellow)
);
println!("Blue : \t\t {}", terminal.paint("").with(Color::Blue));
println!("Dark Blue : \t {}", terminal.paint("").with(Color::DarkBlue));
println!("Magenta : \t {}", terminal.paint("").with(Color::Magenta));
println!("Dark Magenta : \t {}", terminal.paint("").with(Color::DarkMagenta));
println!(
"Dark Blue : \t {}",
terminal.paint("").with(Color::DarkBlue)
);
println!(
"Magenta : \t {}",
terminal.paint("").with(Color::Magenta)
);
println!(
"Dark Magenta : \t {}",
terminal.paint("").with(Color::DarkMagenta)
);
println!("Cyan : \t\t {}", terminal.paint("").with(Color::Cyan));
println!("Dark Cyan : \t {}", terminal.paint("").with(Color::DarkCyan));
println!(
"Dark Cyan : \t {}",
terminal.paint("").with(Color::DarkCyan)
);
println!("Grey : \t\t {}", terminal.paint("").with(Color::Grey));
println!("White : \t {}", terminal.paint("").with(Color::White));
}
/// Print all available foreground colors | demonstration.
pub fn print_all_background_colors()
{
pub fn print_all_background_colors() {
let context = Context::new();
let terminal = terminal::terminal(context.clone());
@ -103,27 +125,51 @@ pub fn print_all_background_colors()
println!("Red : \t\t {}", terminal.paint(" ").on(Color::Red));
println!("Dark Red: \t {}", terminal.paint(" ").on(Color::DarkRed));
println!("Green : \t {}", terminal.paint(" ").on(Color::Green));
println!("Dark Green : \t {}", terminal.paint(" ").on(Color::DarkGreen));
println!(
"Dark Green : \t {}",
terminal.paint(" ").on(Color::DarkGreen)
);
println!("Yellow : \t {}", terminal.paint(" ").on(Color::Yellow));
println!("Dark Yellow : \t {}", terminal.paint(" ").on(Color::DarkYellow));
println!(
"Dark Yellow : \t {}",
terminal.paint(" ").on(Color::DarkYellow)
);
println!("Blue : \t\t {}", terminal.paint(" ").on(Color::Blue));
println!("Dark Blue : \t {}", terminal.paint(" ").on(Color::DarkBlue));
println!(
"Dark Blue : \t {}",
terminal.paint(" ").on(Color::DarkBlue)
);
println!("Magenta : \t {}", terminal.paint(" ").on(Color::Magenta));
println!("Dark Magenta : \t {}", terminal.paint(" ").on(Color::DarkMagenta));
println!(
"Dark Magenta : \t {}",
terminal.paint(" ").on(Color::DarkMagenta)
);
println!("Cyan : \t\t {}", terminal.paint(" ").on(Color::Cyan));
println!("Dark Cyan : \t {}", terminal.paint(" ").on(Color::DarkCyan));
println!(
"Dark Cyan : \t {}",
terminal.paint(" ").on(Color::DarkCyan)
);
println!("Grey : \t\t {}", terminal.paint(" ").on(Color::Grey));
println!("White : \t {}", terminal.paint(" ").on(Color::White));
#[cfg(unix)]
println!("RGB (10,10,10): \t {}", terminal.paint(" ").on(Color::Rgb {r: 10, g: 10, b: 10}));
println!(
"RGB (10,10,10): \t {}",
terminal.paint(" ").on(Color::Rgb {
r: 10,
g: 10,
b: 10
})
);
#[cfg(unix)]
println!("RGB (10,10,10): \t {}", terminal.paint(" ").on(Color::AnsiValue(50)));
println!(
"RGB (10,10,10): \t {}",
terminal.paint(" ").on(Color::AnsiValue(50))
);
}
/// Print font with all available attributes. Note that this can only be used at unix systems and that some are not supported widely | demonstration..
#[cfg(unix)]
pub fn print_font_with_attributes()
{
pub fn print_font_with_attributes() {
let context = Context::new();
let terminal = terminal::terminal(context.clone());
@ -141,15 +187,20 @@ pub fn print_font_with_attributes()
/// Print all supported rgb colors | demonstration.
#[cfg(unix)]
pub fn print_supported_colors()
{
pub fn print_supported_colors() {
let context = Context::new();
let terminal = terminal::terminal(context.clone());
let count = crossterm::style::color(context.clone()).get_available_color_count().unwrap();
let count = crossterm::style::color(context.clone())
.get_available_color_count()
.unwrap();
for i in 0..count
{
println!("{}", terminal.paint(format!("Color: {}",i)).with(Color::AnsiValue(i as u8)));
for i in 0..count {
println!(
"{}",
terminal
.paint(format!("Color: {}", i))
.with(Color::AnsiValue(i as u8))
);
}
}
}

View File

@ -1,4 +1,4 @@
//!
//!
//! Examples of actions that could be performed with te cursor.
//!
@ -7,30 +7,27 @@ use self::crossterm::cursor::{cursor, TerminalCursor};
use self::crossterm::Context;
/// Set the cursor to position X: 10, Y: 5 in the terminal.
pub fn goto()
{
pub fn goto() {
let context = Context::new();
// Get the cursor
let mut cursor = cursor(context.clone());
// Set the cursor to position X: 10, Y: 5 in the terminal
cursor.goto(10,5);
cursor.goto(10, 5);
}
/// get the cursor position
pub fn pos()
{
pub fn pos() {
let context = Context::new();
// Get the cursor
let mut cursor = cursor(context.clone());
// get the cursor position.
let (x,y) = cursor.pos();
let (x, y) = cursor.pos();
}
/// Move the cursor 3 up | demonstration.
pub fn move_up()
{
pub fn move_up() {
let context = Context::new();
// Get the cursor
@ -40,8 +37,7 @@ pub fn move_up()
}
/// Move the cursor 3 to the right | demonstration.
pub fn move_right()
{
pub fn move_right() {
let context = Context::new();
// Get the cursor
@ -51,8 +47,7 @@ pub fn move_right()
}
/// Move the cursor 3 down | demonstration.
pub fn move_down()
{
pub fn move_down() {
let context = Context::new();
// Get the cursor
@ -62,8 +57,7 @@ pub fn move_down()
}
/// Move the cursor 3 to the left | demonstration.
pub fn move_left()
{
pub fn move_left() {
let context = Context::new();
// Get the cursor
@ -73,45 +67,43 @@ pub fn move_left()
}
/// Print character at X: 10 Y: 5 | demonstration.
pub fn print()
{
pub fn print() {
let context = Context::new();
// To print an some displayable content on an certain position.
// To print an some displayable content on an certain position.
// Get the cursor
let mut cursor = cursor(context.clone());
// Set the cursor to position X: 10, Y: 5 in the terminal
cursor.goto(10,5);
cursor.goto(10, 5);
// Print the @ symbol at position X: 10, Y: 5 in the terminal
print!("@");
// Rust is line buffered inorder to print at an certain position we need to clear the buffer first.
// Rust is line buffered inorder to print at an certain position we need to clear the buffer first.
use std;
use std::io::Write;
std::io::stdout().flush();
/* Because the above method is a little to much code,
you can use the `print()` method for printing an value at an certain position in the terminal.
Crossterm provides method chaining so that the above points can be inlined.
*/
cursor.goto(10,5).print("@");
cursor.goto(10, 5).print("@");
}
/// Save and reset cursor position | demonstration..
pub fn safe_and_reset_position()
{
pub fn safe_and_reset_position() {
let context = Context::new();
let mut cursor = cursor(context.clone());
// Goto X: 5 Y: 5
cursor.goto(5,5);
cursor.goto(5, 5);
// Safe cursor position: X: 5 Y: 5
cursor.save_position();
// Goto X: 5 Y: 20
cursor.goto(5,20);
cursor.goto(5, 20);
// Print at X: 5 Y: 20.
println!("Yea!");
// Reset back to X: 5 Y: 5.
@ -123,8 +115,7 @@ pub fn safe_and_reset_position()
}
/// Hide cursor display | demonstration.
pub fn hide_cursor()
{
pub fn hide_cursor() {
let context = Context::new();
let cursor = cursor(context.clone());
@ -132,8 +123,7 @@ pub fn hide_cursor()
}
/// Show cursor display | demonstration.
pub fn show_cursor()
{
pub fn show_cursor() {
let context = Context::new();
let cursor = cursor(context.clone());
@ -141,32 +131,10 @@ pub fn show_cursor()
}
/// Show cursor display, only works on certain terminals.| demonstration
pub fn blink_cursor()
{
pub fn blink_cursor() {
let context = Context::new();
let cursor = cursor(context.clone());
cursor.blink(false);
cursor.blink(false);
}

View File

@ -1,42 +1,42 @@
extern crate crossterm;
use crossterm::Context;
use crossterm::screen::AlternateScreen;
use crossterm::cursor::cursor;
use crossterm::screen::AlternateScreen;
use crossterm::terminal::{self, ClearType};
use crossterm::Context;
use std::io::{Write, stdout};
use std::{time, thread};
use std::io::{stdout, Write};
use std::rc::Rc;
use std::{thread, time};
fn print_wait_screen(context: Rc<Context>)
{
fn print_wait_screen(context: Rc<Context>) {
let mut terminal = terminal::terminal(context.clone());
terminal.clear(ClearType::All);
let mut cursor = cursor(context.clone());
cursor.goto(0,0);
cursor.goto(0, 0);
cursor.hide();
terminal.write("Welcome to the wait screen.\n\
Please wait a few seconds until we arrive back at the main screen.\n\
Progress: ");
terminal.write(
"Welcome to the wait screen.\n\
Please wait a few seconds until we arrive back at the main screen.\n\
Progress: ",
);
// print some progress example.
for i in 1..5
{
for i in 1..5 {
// print the current counter at the line of `Seconds to Go: {counter}`
cursor.goto(10,2).print(format!("{} of the 5 items processed", i));
cursor
.goto(10, 2)
.print(format!("{} of the 5 items processed", i));
// 1 second delay
thread::sleep(time::Duration::from_secs(1));
}
}
/// print wait screen on alternate screen, then swich back.
pub fn print_wait_screen_on_alternate_window(context: Rc<Context>)
{
pub fn print_wait_screen_on_alternate_window(context: Rc<Context>) {
// create scope. If this scope ends the screen will be switched back to mainscreen.
// because `AlternateScreen` switches back to main screen when switching back.
{
@ -49,15 +49,14 @@ pub fn print_wait_screen_on_alternate_window(context: Rc<Context>)
}
/// some stress test switch from and to alternate screen.
pub fn switch_between_main_and_alternate_screen()
{
pub fn switch_between_main_and_alternate_screen() {
let context = Context::new();
let mut cursor = cursor(context.clone());
{
// create new alternate screen instance and switch to the alternate screen.
let mut screen = AlternateScreen::from(context.clone());
cursor.goto(0,0);
cursor.goto(0, 0);
write!(screen, "we are at the alternate screen!");
screen.flush();
thread::sleep(time::Duration::from_secs(3));
@ -74,4 +73,4 @@ pub fn switch_between_main_and_alternate_screen()
}
println!("Whe are back at the main screen");
}
}

View File

@ -1,39 +1,40 @@
extern crate crossterm;
use crossterm::Context;
use crossterm::screen::AlternateScreen;
use crossterm::cursor::cursor;
use crossterm::screen::AlternateScreen;
use crossterm::terminal::{self, ClearType};
use crossterm::Context;
use std::io::{Write, stdout};
use std::{time, thread};
use std::io::{stdout, Write};
use std::rc::Rc;
use std::{thread, time};
use crossterm::raw::IntoRawMode;
// raw screen is not working correctly currently
fn print_wait_screen(context: Rc<Context>)
{
fn print_wait_screen(context: Rc<Context>) {
terminal::terminal(context.clone()).clear(ClearType::All);
let mut cursor = cursor(context.clone());
cursor.goto(0,0).print("Welcome to the wait screen.");
cursor.goto(0,1).print("Please wait a few seconds until we arrive back at the main screen.");
cursor.goto(0,2).print("Progress: ");
cursor.goto(0, 0).print("Welcome to the wait screen.");
cursor
.goto(0, 1)
.print("Please wait a few seconds until we arrive back at the main screen.");
cursor.goto(0, 2).print("Progress: ");
// print some progress example.
for i in 1..5
{
for i in 1..5 {
// print the current counter at the line of `Seconds to Go: {counter}`
cursor.goto(10,2).print(format!("{} of the 5 items processed", i));
cursor
.goto(10, 2)
.print(format!("{} of the 5 items processed", i));
// 1 second delay
thread::sleep(time::Duration::from_secs(1));
}
}
pub fn print_wait_screen_on_alternate_window()
{
pub fn print_wait_screen_on_alternate_window() {
let context = Context::new();
// create scope. If this scope ends the screen will be switched back to mainscreen.
@ -52,4 +53,4 @@ pub fn print_wait_screen_on_alternate_window()
}
println!("Whe are back at the main screen");
}
}

View File

@ -4,20 +4,18 @@
extern crate crossterm;
use crossterm::Context;
use crossterm::terminal::{ ClearType, terminal };
use crossterm::cursor;
use crossterm::terminal::{terminal, ClearType};
use crossterm::Context;
fn print_test_data()
{
fn print_test_data() {
for i in 0..100 {
println!("Test data to test terminal: {}",i);
println!("Test data to test terminal: {}", i);
}
}
/// Clear all lines in terminal | demonstration
pub fn clear_all_lines()
{
pub fn clear_all_lines() {
let context = Context::new();
// Get terminal
@ -30,8 +28,7 @@ pub fn clear_all_lines()
}
/// Clear all lines from cursor position X:4, Y:4 down | demonstration
pub fn clear_from_cursor_down()
{
pub fn clear_from_cursor_down() {
let context = Context::new();
// Get terminal
@ -40,15 +37,14 @@ pub fn clear_from_cursor_down()
print_test_data();
// Set terminal cursor position (see example for more info).
cursor::cursor(context.clone()).goto(4,8);
cursor::cursor(context.clone()).goto(4, 8);
// Clear all cells from current cursor position down.
terminal.clear(ClearType::FromCursorDown);
}
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
pub fn clear_from_cursor_up()
{
pub fn clear_from_cursor_up() {
let context = Context::new();
// Get terminal
@ -57,15 +53,14 @@ pub fn clear_from_cursor_up()
print_test_data();
// Set terminal cursor position (see example for more info).
cursor::cursor(context.clone()).goto(4,4);
cursor::cursor(context.clone()).goto(4, 4);
// Clear all cells from current cursor position down.
terminal.clear(ClearType::FromCursorUp);
}
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
pub fn clear_current_line()
{
pub fn clear_current_line() {
let context = Context::new();
// Get terminal
@ -74,15 +69,14 @@ pub fn clear_current_line()
print_test_data();
// Set terminal cursor position (see example for more info).
cursor::cursor(context.clone()).goto(4,4);
cursor::cursor(context.clone()).goto(4, 4);
// Clear current line cells.
terminal.clear(ClearType::CurrentLine);
}
/// Clear all lines from cursor position X:4, Y:7 up | demonstration
pub fn clear_until_new_line()
{
pub fn clear_until_new_line() {
let context = Context::new();
// Get terminal
@ -91,15 +85,14 @@ pub fn clear_until_new_line()
print_test_data();
// Set terminal cursor position (see example for more info).
cursor::cursor(context.clone()).goto(4,20);
cursor::cursor(context.clone()).goto(4, 20);
// Clear all the cells until next line.
terminal.clear(ClearType::UntilNewLine);
}
/// Print the the current terminal size | demonstration.
pub fn print_terminal_size()
{
pub fn print_terminal_size() {
let context = Context::new();
// Get terminal
@ -111,18 +104,16 @@ pub fn print_terminal_size()
}
/// Set the terminal size to width 10, height: 10 | demonstration.
pub fn set_terminal_size()
{
pub fn set_terminal_size() {
let context = Context::new();
let mut terminal = terminal(context);
terminal.set_size(10,10);
terminal.set_size(10, 10);
}
/// Scroll down 10 lines | demonstration.
pub fn scroll_down()
{
pub fn scroll_down() {
let context = Context::new();
print_test_data();
@ -133,8 +124,7 @@ pub fn scroll_down()
}
/// Scroll down 10 lines | demonstration.
pub fn scroll_up()
{
pub fn scroll_up() {
let context = Context::new();
print_test_data();
@ -146,19 +136,17 @@ pub fn scroll_up()
}
/// Resize the terminal to X: 10, Y: 10 | demonstration.
pub fn resize_terminal()
{
pub fn resize_terminal() {
let context = Context::new();
// Get terminal
let mut terminal = terminal(context.clone());
// Get terminal size
terminal.set_size(10,10);
terminal.set_size(10, 10);
}
/// exit the current proccess.
pub fn exit()
{
pub fn exit() {
let context = Context::new();
// Get terminal

View File

@ -2,14 +2,13 @@
//! This module is used for windows 10 terminals and unix terminals by default.
//! Note that the cursor position is 0 based. This means that we start counting at 0 when setting the cursor position ect.
use Context;
use shared::functions;
use super::*;
use shared::functions;
use Context;
/// This struct is an ansi implementation for cursor related actions.
pub struct AnsiCursor
{
context: Rc<Context>
pub struct AnsiCursor {
context: Rc<Context>,
}
impl AnsiCursor {
@ -19,8 +18,7 @@ impl AnsiCursor {
}
impl ITerminalCursor for AnsiCursor {
fn goto(&self, x: u16, y: u16)
{
fn goto(&self, x: u16, y: u16) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_ansi(format!(csi!("{};{}H"), y + 1, x + 1));
@ -59,47 +57,40 @@ impl ITerminalCursor for AnsiCursor {
}
}
fn save_position(&mut self)
{
fn save_position(&mut self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_ansi_str(csi!("s"));
}
}
fn reset_position(&self)
{
fn reset_position(&self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_ansi_str(csi!("u"));
}
}
fn hide(&self)
{
fn hide(&self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_ansi_str(csi!("?25l"));
}
}
fn show(&self)
{
fn show(&self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_ansi_str(csi!("?25h"));
}
}
fn blink(&self, blink: bool)
{
fn blink(&self, blink: bool) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
if blink
{
if blink {
screen.write_ansi_str(csi!("?12h"));
}
else {
} else {
screen.write_ansi_str(csi!("?12l"));
}
}

View File

@ -3,10 +3,10 @@
//!
//! Note that positions of the cursor are 0 -based witch means that the coordinates (cells) starts counting from 0
use super::*;
use Context;
use super::super::shared::functions;
use super::*;
use std::io::Write;
use Context;
use std::fmt::Display;
use std::rc::Rc;
@ -17,17 +17,22 @@ pub struct TerminalCursor {
terminal_cursor: Option<Box<ITerminalCursor>>,
}
impl TerminalCursor
{
impl TerminalCursor {
/// Create new cursor instance whereon cursor related actions can be performed.
pub fn new(context: Rc<Context>) -> TerminalCursor {
#[cfg(target_os = "windows")]
let cursor = functions::get_module::<Box<ITerminalCursor>>(WinApiCursor::new(context.screen_manager.clone()), AnsiCursor::new(context.clone()));
let cursor = functions::get_module::<Box<ITerminalCursor>>(
WinApiCursor::new(context.screen_manager.clone()),
AnsiCursor::new(context.clone()),
);
#[cfg(not(target_os = "windows"))]
let cursor = Some(AnsiCursor::new(context.clone()) as Box<ITerminalCursor>);
TerminalCursor { terminal_cursor: cursor, context}
TerminalCursor {
terminal_cursor: cursor,
context,
}
}
/// Goto some position (x,y) in the terminal.
@ -199,9 +204,9 @@ impl TerminalCursor
/// Print an value at the current cursor position.
///
/// This method prints an value with `print!()` and clears the buffer afterwards.
/// This method prints an value with `print!()` and clears the buffer afterwards.
/// Rust's standard output is line-buffered. So your text gets sent to the console one line at a time.
/// If you set the curosr position and try to `print!()` at that position and do not clear the buffer, than the character will not be printed at that position.
/// If you set the curosr position and try to `print!()` at that position and do not clear the buffer, than the character will not be printed at that position.
/// But will be printed when the next `println()` will be done.
///
/// With this method you can print any displayable value at a certain position and the output buffer will be cleared afterwards.
@ -226,12 +231,12 @@ impl TerminalCursor
/// cursor::cursor(&context).goto(10,10);
/// print!("@");
/// std::io::stdout().flush();
///
///
/// // but now we can chain the methods so it looks cleaner and it automatically flushes the buffer.
/// cursor::cursor(&context)
/// .goto(10,10)
/// .print("@");
///
///
/// ```
pub fn print<D: Display>(&mut self, value: D) -> &mut TerminalCursor {
{
@ -267,8 +272,7 @@ impl TerminalCursor
/// cursor::cursor(&context).safe_position();
///
/// ```
pub fn save_position(&mut self)
{
pub fn save_position(&mut self) {
if let Some(ref mut terminal_cursor) = self.terminal_cursor {
terminal_cursor.save_position();
}
@ -290,8 +294,7 @@ impl TerminalCursor
/// cursor(&context).reset_position();
///
/// ```
pub fn reset_position(&mut self)
{
pub fn reset_position(&mut self) {
if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.reset_position();
}
@ -311,8 +314,7 @@ impl TerminalCursor
/// cursor(&context).hide();
///
/// ```
pub fn hide(&self)
{
pub fn hide(&self) {
if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.hide();
}
@ -332,8 +334,7 @@ impl TerminalCursor
/// cursor(&context).show();
///
/// ```
pub fn show(&self)
{
pub fn show(&self) {
if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.show();
}
@ -357,8 +358,7 @@ impl TerminalCursor
/// cursor.blink(false);
///
/// ```
pub fn blink(&self, blink: bool)
{
pub fn blink(&self, blink: bool) {
if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.blink(blink);
}
@ -368,7 +368,7 @@ impl TerminalCursor
/// Get an TerminalCursor implementation whereon cursor related actions can be performed.
///
/// Check `/examples/version/cursor` in the libary for more spesific examples.
///
///
/// #Example
///
/// ```rust

View File

@ -10,15 +10,15 @@
pub mod cursor;
mod ansi_cursor;
#[cfg(target_os = "windows")]
mod winapi_cursor;
mod ansi_cursor;
use self::ansi_cursor::AnsiCursor;
#[cfg(target_os = "windows")]
use self::winapi_cursor::WinApiCursor;
use self::ansi_cursor::AnsiCursor;
pub use self::cursor::{ cursor, TerminalCursor };
pub use self::cursor::{cursor, TerminalCursor};
use std::rc::Rc;
@ -53,4 +53,4 @@ pub trait ITerminalCursor {
fn show(&self);
/// enable or disable the blinking of the cursor.
fn blink(&self, blink: bool);
}
}

View File

@ -1,18 +1,17 @@
//! This is an WINAPI specific implementation for cursor related action.
//! This module is used for windows terminals that do not support ANSI escape codes.
//! Note that the cursor position is 0 based. This means that we start counting at 0 when setting the cursor position ect.
use super::super::manager::{IScreenManager, ScreenManager, WinApiScreenManager};
use super::ITerminalCursor;
use super::super::manager::{IScreenManager, ScreenManager, WinApiScreenManager };
use kernel::windows_kernel::{kernel, cursor};
use kernel::windows_kernel::{cursor, kernel};
use std::rc::Rc;
use std::sync::Mutex;
/// This struct is an windows implementation for cursor related actions.
pub struct WinApiCursor
{
screen_manager: Rc<Mutex<ScreenManager>>
pub struct WinApiCursor {
screen_manager: Rc<Mutex<ScreenManager>>,
}
impl WinApiCursor {
@ -21,10 +20,8 @@ impl WinApiCursor {
}
}
impl ITerminalCursor for WinApiCursor
{
impl ITerminalCursor for WinApiCursor {
fn goto(&self, x: u16, y: u16) {
kernel::set_console_cursor_position(x as i16, y as i16, &self.screen_manager);
}
@ -33,47 +30,40 @@ impl ITerminalCursor for WinApiCursor
}
fn move_up(&self, count: u16) {
let (xpos,ypos) = self.pos();
let (xpos, ypos) = self.pos();
self.goto(xpos, ypos - count);
}
fn move_right(&self, count: u16) {
let (xpos,ypos) = self.pos();
let (xpos, ypos) = self.pos();
self.goto(xpos + count, ypos);
}
fn move_down(&self, count: u16) {
let (xpos,ypos) = self.pos();
let (xpos, ypos) = self.pos();
self.goto(xpos, ypos + count);
}
fn move_left(&self, count: u16) {
let (xpos,ypos) = self.pos();
let (xpos, ypos) = self.pos();
self.goto(xpos - count, ypos);
}
fn save_position(&mut self)
{
fn save_position(&mut self) {
cursor::save_cursor_pos(&self.screen_manager);
}
fn reset_position(&self)
{
fn reset_position(&self) {
cursor::reset_to_saved_position(&self.screen_manager);
}
fn hide(&self)
{
fn hide(&self) {
kernel::cursor_visibility(false, &self.screen_manager);
}
fn show(&self)
{
fn show(&self) {
kernel::cursor_visibility(true, &self.screen_manager);
}
fn blink(&self, blink: bool)
{
}
fn blink(&self, blink: bool) {}
}

View File

@ -4,4 +4,3 @@
pub mod unix_kernel;
#[cfg(windows)]
pub mod windows_kernel;

View File

@ -1,4 +1,3 @@
//! This module contains all the specific `unix` code.
pub mod terminal;

View File

@ -1,14 +1,14 @@
//! This module contains all `unix` specific terminal related logic.
use {libc, StateManager, Context, CommandManager};
pub use self::libc::termios;
use self::libc::{c_int, c_ushort, ioctl, STDOUT_FILENO, TIOCGWINSZ};
use state::commands::{IStateCommand, NoncanonicalModeCommand};
use termios::Termios;
pub use self::libc::{termios};
use self::libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl, c_int};
use state::commands::{ NoncanonicalModeCommand, IStateCommand} ;
use {libc, CommandManager, Context, StateManager};
use std::io::Error;
use std::{ io, mem };
use std::rc::Rc;
use std::{io, mem};
/// A representation of the size of the current terminal.
#[repr(C)]
@ -23,7 +23,7 @@ pub struct UnixSize {
}
/// Get the current terminal size.
pub fn terminal_size() -> (u16,u16) {
pub fn terminal_size() -> (u16, u16) {
// http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
let us = UnixSize {
rows: 0,
@ -34,16 +34,15 @@ pub fn terminal_size() -> (u16,u16) {
let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
if r == 0 {
// because crossterm works starts counting at 0 and unix terminal starts at cell 1 you have subtract one to get 0-based results.
(us.cols -1, us.rows -1)
(us.cols - 1, us.rows - 1)
} else {
(0,0)
(0, 0)
}
}
/// Get the current cursor position.
pub fn pos(context: Rc<Context>) -> (u16, u16)
{
use std::io::{ Write,Read };
pub fn pos(context: Rc<Context>) -> (u16, u16) {
use std::io::{Read, Write};
let mut command_id = NoncanonicalModeCommand::new(&context.state_manager);
@ -95,7 +94,11 @@ pub fn pos(context: Rc<Context>) -> (u16, u16)
let (cols, c) = read_num();
// Expect `R`
let res = if c == 'R' { (cols as u16, rows as u16) } else { return (0, 0) };
let res = if c == 'R' {
(cols as u16, rows as u16)
} else {
return (0, 0);
};
CommandManager::undo(context.clone(), command_id);
@ -103,8 +106,7 @@ pub fn pos(context: Rc<Context>) -> (u16, u16)
}
/// Set the terminal mode to the given mode.
pub fn set_terminal_mode(termios: &Termios) -> io::Result<()>
{
pub fn set_terminal_mode(termios: &Termios) -> io::Result<()> {
extern "C" {
pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int;
}
@ -120,8 +122,7 @@ pub fn make_raw(termios: &mut Termios) {
}
/// Get the current terminal mode.
pub fn get_terminal_mode() -> io::Result<Termios>
{
pub fn get_terminal_mode() -> io::Result<Termios> {
extern "C" {
pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int;
}
@ -132,18 +133,15 @@ pub fn get_terminal_mode() -> io::Result<Termios>
}
}
pub fn exit()
{
pub fn exit() {
::std::process::exit(0);
}
/// Is the return value true?
fn is_true(value: i32) -> Result<(), Error>
{
match value
{
fn is_true(value: i32) -> Result<(), Error> {
match value {
-1 => Err(io::Error::last_os_error()),
0 => Ok(()),
_ => Err(io::Error::last_os_error()),
}
}
}

View File

@ -1,16 +1,15 @@
//! This module handles the enabling `ANSI escape codes` for windows terminals.
use IStateCommand;
use std::sync::{Once, ONCE_INIT};
use IStateCommand;
static mut HAS_BEEN_TRYED_TO_ENABLE: bool = false;
static mut IS_ANSI_ON_WINDOWS_ENABLED: Option<bool> = None;
static mut DOES_WINDOWS_SUPPORT_ANSI: Option<bool> = None;
static mut DOES_WINDOWS_SUPPORT_ANSI: Option<bool> = None;
static START: Once = ONCE_INIT;
/// Try enable `ANSI escape codes` and return the result.
pub fn try_enable_ansi_support() -> bool
{
pub fn try_enable_ansi_support() -> bool {
START.call_once(|| {
use state::commands::win_commands::EnableAnsiCommand;
let mut command = EnableAnsiCommand::new();
@ -21,53 +20,43 @@ pub fn try_enable_ansi_support() -> bool
has_been_tried_to_enable(true);
});
windows_supportable()
windows_supportable()
}
/// Get whether ansi has been enabled.
pub fn ansi_enabled() -> bool
{
unsafe { IS_ANSI_ON_WINDOWS_ENABLED.unwrap_or_else(| | false) }
pub fn ansi_enabled() -> bool {
unsafe { IS_ANSI_ON_WINDOWS_ENABLED.unwrap_or_else(|| false) }
}
/// Get whether windows supports ansi
pub fn windows_supportable() -> bool
{
unsafe { DOES_WINDOWS_SUPPORT_ANSI.unwrap_or_else(| | false)}
pub fn windows_supportable() -> bool {
unsafe { DOES_WINDOWS_SUPPORT_ANSI.unwrap_or_else(|| false) }
}
/// Get whether ansi has been tried to enable before.
pub fn has_been_tried_to_enable_ansi() -> bool
{
unsafe
{
pub fn has_been_tried_to_enable_ansi() -> bool {
unsafe {
return HAS_BEEN_TRYED_TO_ENABLE;
}
}
/// Set the is ansi escape property enabled or disabled. So whe can determine if the ansi escape codes are enabled.
pub fn set_ansi_enabled(is_enabled :bool)
{
unsafe
{
pub fn set_ansi_enabled(is_enabled: bool) {
unsafe {
IS_ANSI_ON_WINDOWS_ENABLED = Some(is_enabled);
}
}
/// Set the is_windows_ansi_supportable property. So whe can determine whether windows supports ansi.
fn set_is_windows_ansi_supportable(is_enabled :bool)
{
unsafe
{
fn set_is_windows_ansi_supportable(is_enabled: bool) {
unsafe {
DOES_WINDOWS_SUPPORT_ANSI = Some(is_enabled);
}
}
/// Set the has_been_tried_to_enable property. So we can determine whether ansi has been tried to enable before.
fn has_been_tried_to_enable(has_been_tried: bool)
{
unsafe
{
fn has_been_tried_to_enable(has_been_tried: bool) {
unsafe {
HAS_BEEN_TRYED_TO_ENABLE = has_been_tried;
}
}
}

View File

@ -1,25 +1,27 @@
//! This module handles some logic for cursor interaction in the windows console.
use super::kernel;
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
use super::kernel;
use std::rc::Rc;
use std::sync::Mutex;
/// This stores the cursor pos, at program level. So it can be recalled later.
static mut SAVED_CURSOR_POS:(u16,u16) = (0,0);
static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0);
/// Reset to saved cursor position
pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>)
{
pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>) {
unsafe {
kernel::set_console_cursor_position(SAVED_CURSOR_POS.0 as i16, SAVED_CURSOR_POS.1 as i16, screen_manager);
kernel::set_console_cursor_position(
SAVED_CURSOR_POS.0 as i16,
SAVED_CURSOR_POS.1 as i16,
screen_manager,
);
}
}
/// Save current cursor position to recall later.
pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>)
{
pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) {
let position = pos(screen_manager);
unsafe {
@ -28,8 +30,10 @@ pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>)
}
/// get the current cursor position.
pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16,u16)
{
pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
let csbi = kernel::get_console_screen_buffer_info(screen_manager);
( csbi.dwCursorPosition.X as u16, csbi.dwCursorPosition.Y as u16 )
}
(
csbi.dwCursorPosition.X as u16,
csbi.dwCursorPosition.Y as u16,
)
}

View File

@ -1,29 +1,27 @@
//! This module is the core of all the `WINAPI` actions. All unsafe `WINAPI` function call are done here.
use Context;
use std::rc::Rc;
use Context;
use winapi::um::winnt::HANDLE;
use winapi::um::winbase::{STD_OUTPUT_HANDLE, STD_INPUT_HANDLE };
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
use winapi::um::processenv::{GetStdHandle};
use winapi::um::consoleapi::{SetConsoleMode,GetConsoleMode, };
use winapi::shared::ntdef::{NULL};
use winapi::shared::minwindef::{TRUE, FALSE};
use winapi::um::wincon;
use winapi::shared::minwindef::{FALSE, TRUE};
use winapi::shared::ntdef::NULL;
use winapi::um::consoleapi::WriteConsoleW;
use winapi::um::wincon::
{
ENABLE_PROCESSED_INPUT,
WriteConsoleOutputW,
WriteConsoleOutputCharacterA,
WriteConsoleOutputCharacterW,
SetConsoleWindowInfo, SetConsoleCursorPosition, SetConsoleTextAttribute, SetConsoleScreenBufferSize, CreateConsoleScreenBuffer,SetConsoleActiveScreenBuffer, SetConsoleCursorInfo,
GetLargestConsoleWindowSize, GetConsoleScreenBufferInfo,
FillConsoleOutputCharacterA, FillConsoleOutputAttribute,WriteConsoleOutputAttribute,
CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD, CHAR_INFO, PSMALL_RECT, CONSOLE_CURSOR_INFO
use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode};
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
use winapi::um::processenv::GetStdHandle;
use winapi::um::winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
use winapi::um::wincon;
use winapi::um::wincon::{
CreateConsoleScreenBuffer, FillConsoleOutputAttribute, FillConsoleOutputCharacterA,
GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize, SetConsoleActiveScreenBuffer,
SetConsoleCursorInfo, SetConsoleCursorPosition, SetConsoleScreenBufferSize,
SetConsoleTextAttribute, SetConsoleWindowInfo, WriteConsoleOutputAttribute,
WriteConsoleOutputCharacterA, WriteConsoleOutputCharacterW, WriteConsoleOutputW, CHAR_INFO,
CONSOLE_CURSOR_INFO, CONSOLE_SCREEN_BUFFER_INFO, COORD, ENABLE_PROCESSED_INPUT, PSMALL_RECT,
SMALL_RECT,
};
use winapi::um::winnt::HANDLE;
use super::{Empty};
use super::Empty;
static mut CONSOLE_OUTPUT_HANDLE: Option<HANDLE> = None;
static mut CONSOLE_INPUT_HANDLE: Option<HANDLE> = None;
@ -31,8 +29,7 @@ use super::super::super::manager::{ScreenManager, WinApiScreenManager};
use std::sync::Mutex;
/// Get the global stored handle.
pub fn get_current_handle(screen_manager: &mut WinApiScreenManager) -> &HANDLE
{
pub fn get_current_handle(screen_manager: &mut WinApiScreenManager) -> &HANDLE {
return screen_manager.get_handle();
}
@ -44,8 +41,7 @@ pub fn get_output_handle() -> HANDLE {
} else {
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
if !is_valid_handle(&handle)
{
if !is_valid_handle(&handle) {
panic!("Cannot get output handle")
}
@ -63,8 +59,7 @@ pub fn get_input_handle() -> HANDLE {
} else {
let handle = GetStdHandle(STD_INPUT_HANDLE);
if !is_valid_handle(&handle)
{
if !is_valid_handle(&handle) {
panic!("Cannot get input handle")
}
@ -83,12 +78,16 @@ fn is_valid_handle(handle: &HANDLE) -> bool {
}
}
/// Create a new console screen buffer info struct.
pub fn get_console_screen_buffer_info(screen_manager: &Rc<Mutex<ScreenManager>>) -> CONSOLE_SCREEN_BUFFER_INFO {
pub fn get_console_screen_buffer_info(
screen_manager: &Rc<Mutex<ScreenManager>>,
) -> CONSOLE_SCREEN_BUFFER_INFO {
let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(win_api) => { win_api },
None => panic!("")
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
};
let output_handle = get_current_handle(winapi_screen_manager);
@ -106,7 +105,6 @@ pub fn get_console_screen_buffer_info(screen_manager: &Rc<Mutex<ScreenManager>>)
/// Create a new console screen buffer info struct.
pub fn get_console_screen_buffer_info_from_handle(handle: &HANDLE) -> CONSOLE_SCREEN_BUFFER_INFO {
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
let success;
@ -120,13 +118,10 @@ pub fn get_console_screen_buffer_info_from_handle(handle: &HANDLE) -> CONSOLE_SC
}
/// Get the larged console window size posible.
pub fn get_largest_console_window_size() -> COORD
{
pub fn get_largest_console_window_size() -> COORD {
let output_handle = get_output_handle();
unsafe {
GetLargestConsoleWindowSize(output_handle)
}
unsafe { GetLargestConsoleWindowSize(output_handle) }
}
/// Get the original color of the terminal.
@ -136,8 +131,7 @@ pub fn get_original_console_color(screen_manager: &Rc<Mutex<ScreenManager>>) ->
}
/// Set the console mode to the given console mode.
pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool
{
pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool {
unsafe {
let success = SetConsoleMode(*handle, console_mode);
return is_true(success);
@ -145,8 +139,7 @@ pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool
}
/// Get the console mode.
pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool
{
pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool {
unsafe {
let success = GetConsoleMode(*handle, &mut *current_mode);
return is_true(success);
@ -154,8 +147,7 @@ pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool
}
/// Set the cursor position to the given x and y. Note that this is 0 based.
pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<ScreenManager>>)
{
pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<ScreenManager>>) {
if x < 0 || x >= <i16>::max_value() {
panic!("X: {}, Argument Out of Range Exception", x);
}
@ -165,9 +157,12 @@ pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<Scr
}
let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(win_api) => { win_api },
None => panic!("")
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
};
let handle = get_current_handle(winapi_screen_manager);
@ -184,31 +179,30 @@ pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<Scr
}
/// change the cursor visibility.
pub fn cursor_visibility(visable: bool, screen_manager: &Rc<Mutex<ScreenManager>>)
{
pub fn cursor_visibility(visable: bool, screen_manager: &Rc<Mutex<ScreenManager>>) {
let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(win_api) => { win_api },
None => panic!("")
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
};
let handle = get_current_handle(winapi_screen_manager);
let cursor_info = CONSOLE_CURSOR_INFO
{
let cursor_info = CONSOLE_CURSOR_INFO {
dwSize: 100,
bVisible: if visable { TRUE } else {FALSE}
bVisible: if visable { TRUE } else { FALSE },
};
unsafe
{
unsafe {
SetConsoleCursorInfo(*handle, &cursor_info);
}
}
/// Change the console text attribute.
pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenManager>>)
{
pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenManager>>) {
let output_handle = get_output_handle();
unsafe {
@ -217,56 +211,75 @@ pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenMa
}
/// Change console info.
pub fn set_console_info(absolute: bool, rect: &SMALL_RECT, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
{
pub fn set_console_info(
absolute: bool,
rect: &SMALL_RECT,
screen_manager: &Rc<Mutex<ScreenManager>>,
) -> bool {
let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(win_api) => { win_api },
None => panic!("")
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
};
let handle = get_current_handle(winapi_screen_manager);
let absolute = match absolute { true => 1, false => 0, };
unsafe
{
let success = SetConsoleWindowInfo(*handle,absolute ,rect);
let absolute = match absolute {
true => 1,
false => 0,
};
unsafe {
let success = SetConsoleWindowInfo(*handle, absolute, rect);
is_true(success)
}
}
/// Set the console screen buffer size
pub fn set_console_screen_buffer_size( size: COORD, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
{
pub fn set_console_screen_buffer_size(
size: COORD,
screen_manager: &Rc<Mutex<ScreenManager>>,
) -> bool {
let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(win_api) => { win_api },
None => panic!("")
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
};
let handle = get_current_handle(winapi_screen_manager);
unsafe
{
unsafe {
let success = SetConsoleScreenBufferSize(*handle, size);
is_true(success)
}
}
/// Fill a certain block with characters.
pub fn fill_console_output_character(cells_written: &mut u32, start_location: COORD, cells_to_write: u32, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
{
pub fn fill_console_output_character(
cells_written: &mut u32,
start_location: COORD,
cells_to_write: u32,
screen_manager: &Rc<Mutex<ScreenManager>>,
) -> bool {
let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(win_api) => { win_api },
None => panic!("")
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
};
let handle = get_current_handle(winapi_screen_manager);
unsafe {
// fill the cells in console with blanks
let success = FillConsoleOutputCharacterA (
let success = FillConsoleOutputCharacterA(
*handle,
' ' as i8,
cells_to_write,
@ -278,16 +291,22 @@ pub fn fill_console_output_character(cells_written: &mut u32, start_location: CO
}
/// Set console ouput attribute for certain block.
pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: COORD, cells_to_write: u32,screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
{
pub fn fill_console_output_attribute(
cells_written: &mut u32,
start_location: COORD,
cells_to_write: u32,
screen_manager: &Rc<Mutex<ScreenManager>>,
) -> bool {
// Get the position of the current console window
let csbi = get_console_screen_buffer_info(screen_manager);
let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(win_api) => { win_api },
None => panic!("")
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
};
let handle = get_current_handle(winapi_screen_manager);
@ -295,7 +314,7 @@ pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: CO
let success;
unsafe {
success = FillConsoleOutputAttribute (
success = FillConsoleOutputAttribute(
*handle,
csbi.wAttributes,
cells_to_write,
@ -308,110 +327,111 @@ pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: CO
}
/// Create new console screen buffer. This can be used for alternate screen.
pub fn create_console_screen_buffer() -> HANDLE
{
use winapi::shared::ntdef::NULL;
use winapi::um::wincon::CONSOLE_TEXTMODE_BUFFER;
use winapi::um::winnt::{GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE};
use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
pub fn create_console_screen_buffer() -> HANDLE {
use std::mem::size_of;
use winapi::shared::ntdef::NULL;
use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
use winapi::um::wincon::CONSOLE_TEXTMODE_BUFFER;
use winapi::um::winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE};
unsafe
{
let mut security_attr: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES
{
unsafe {
let mut security_attr: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES {
nLength: size_of::<SECURITY_ATTRIBUTES>() as u32,
lpSecurityDescriptor: NULL,
bInheritHandle: TRUE
bInheritHandle: TRUE,
};
let new_screen_buffer = CreateConsoleScreenBuffer(
GENERIC_READ | // read/write access
GENERIC_WRITE,
FILE_SHARE_READ |
FILE_SHARE_WRITE, // shared
&mut security_attr, // default security attributes
CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
NULL
FILE_SHARE_READ | FILE_SHARE_WRITE, // shared
&mut security_attr, // default security attributes
CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
NULL,
);
new_screen_buffer
}
}
/// Set the active screen buffer to the given handle. This can be used for alternate screen.
pub fn set_active_screen_buffer(new_buffer: HANDLE)
{
unsafe
{
if !is_true(SetConsoleActiveScreenBuffer(new_buffer))
{
pub fn set_active_screen_buffer(new_buffer: HANDLE) {
unsafe {
if !is_true(SetConsoleActiveScreenBuffer(new_buffer)) {
panic!("Cannot set active screen buffer");
}
}
}
/// Read the console outptut.
pub fn read_console_output(read_buffer: &HANDLE, copy_buffer: &mut [CHAR_INFO;160], buffer_size: COORD, buffer_coord: COORD, source_buffer: PSMALL_RECT)
{
pub fn read_console_output(
read_buffer: &HANDLE,
copy_buffer: &mut [CHAR_INFO; 160],
buffer_size: COORD,
buffer_coord: COORD,
source_buffer: PSMALL_RECT,
) {
use self::wincon::ReadConsoleOutputA;
unsafe
{
if !is_true(ReadConsoleOutputA(
*read_buffer, // screen buffer to read from
copy_buffer.as_mut_ptr(), // buffer to copy into
buffer_size, // col-row size of chiBuffer
buffer_coord, // top left dest. cell in chiBuffer
source_buffer) // screen buffer source rectangle
){
unsafe {
if !is_true(
ReadConsoleOutputA(
*read_buffer, // screen buffer to read from
copy_buffer.as_mut_ptr(), // buffer to copy into
buffer_size, // col-row size of chiBuffer
buffer_coord, // top left dest. cell in chiBuffer
source_buffer,
), // screen buffer source rectangle
) {
panic!("Cannot read console output");
}
}
}
/// Write console output.
pub fn write_console_output(write_buffer: &HANDLE, copy_buffer: &mut [CHAR_INFO;160], buffer_size: COORD, buffer_coord: COORD, source_buffer: PSMALL_RECT)
{
pub fn write_console_output(
write_buffer: &HANDLE,
copy_buffer: &mut [CHAR_INFO; 160],
buffer_size: COORD,
buffer_coord: COORD,
source_buffer: PSMALL_RECT,
) {
use self::wincon::WriteConsoleOutputA;
unsafe
{
if !is_true(WriteConsoleOutputA(
*write_buffer, // screen buffer to write to
copy_buffer.as_mut_ptr(), // buffer to copy into
buffer_size, // col-row size of chiBuffer
buffer_coord, // top left dest. cell in chiBuffer
source_buffer)// screen buffer source rectangle
){
panic!("Cannot write to console output");
}
unsafe {
if !is_true(
WriteConsoleOutputA(
*write_buffer, // screen buffer to write to
copy_buffer.as_mut_ptr(), // buffer to copy into
buffer_size, // col-row size of chiBuffer
buffer_coord, // top left dest. cell in chiBuffer
source_buffer,
), // screen buffer source rectangle
) {
panic!("Cannot write to console output");
}
}
}
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;
fn win32_string( value : &str ) -> Vec<u16> {
OsStr::new( value ).encode_wide().chain( once( 0 ) ).collect()
fn win32_string(value: &str) -> Vec<u16> {
OsStr::new(value).encode_wide().chain(once(0)).collect()
}
//use std::os::raw::c_void;
use winapi::ctypes::c_void;
use std::mem::transmute;
use std::str;
use winapi::ctypes::c_void;
/// Write utf8 buffer to console.
pub fn write_char_buffer(handle: HANDLE, buf: &[u8])
{
pub fn write_char_buffer(handle: HANDLE, buf: &[u8]) {
// get string from u8[] and parse it to an c_str
let mut utf8 = match str::from_utf8(buf)
{
Ok(string) => string,
Err(_) => "123",
};
let mut utf8 = match str::from_utf8(buf) {
Ok(string) => string,
Err(_) => "123",
};
let utf16: Vec<u16> = utf8.encode_utf16().collect();
let utf16_ptr: *const c_void = utf16.as_ptr() as *const _ as *const c_void;
@ -420,24 +440,30 @@ pub fn write_char_buffer(handle: HANDLE, buf: &[u8])
let csbi = get_console_screen_buffer_info_from_handle(&handle);
// get current position
let current_pos = COORD {X: csbi.dwCursorPosition.X, Y: csbi.dwCursorPosition.Y};
let current_pos = COORD {
X: csbi.dwCursorPosition.X,
Y: csbi.dwCursorPosition.Y,
};
let mut cells_written: u32 = 0;
// write to console
unsafe
{
WriteConsoleW(handle, utf16_ptr, utf16.len() as u32, &mut cells_written, NULL);
unsafe {
WriteConsoleW(
handle,
utf16_ptr,
utf16.len() as u32,
&mut cells_written,
NULL,
);
}
}
/// Parse integer to an bool
fn is_true(value: i32) -> bool
{
if value == 0{
fn is_true(value: i32) -> bool {
if value == 0 {
return false;
}
else{
} else {
return true;
}
}

View File

@ -1,13 +1,13 @@
//! This module contains the `windows` specific logic.
pub mod kernel;
pub mod cursor;
pub mod terminal;
pub mod ansi_support;
pub mod cursor;
pub mod kernel;
pub mod terminal;
use winapi;
use self::winapi::um::wincon::{CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT};
use shared::traits::Empty;
use self::winapi::um::wincon::{COORD, CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT};
use winapi;
impl Empty for COORD {
fn empty() -> COORD {
@ -36,4 +36,4 @@ impl Empty for CONSOLE_SCREEN_BUFFER_INFO {
dwMaximumWindowSize: COORD::empty(),
}
}
}
}

View File

@ -1,7 +1,6 @@
use ScreenManager;
use std::sync::Mutex;
use std::rc::Rc;
use std::sync::Mutex;
use ScreenManager;
/// Get the terminal size
pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
@ -13,7 +12,6 @@ pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
}
/// Exit the current process.
pub fn exit()
{
pub fn exit() {
::std::process::exit(256);
}
}

View File

@ -9,22 +9,22 @@ mod kernel;
mod state;
pub mod cursor;
pub mod manager;
pub mod style;
pub mod terminal;
pub mod manager;
pub use shared::{screen};
pub use shared::environment::Environment;
pub use shared::screen;
pub use state::context::Context;
use state::commands::IStateCommand;
use state::command_manager::CommandManager;
use state::state_manager::StateManager;
use manager::ScreenManager;
use state::command_manager::CommandManager;
use state::commands::IStateCommand;
use state::state_manager::StateManager;
#[cfg(windows)]
extern crate winapi;
#[cfg(unix)]
extern crate libc;
#[cfg(unix)]
extern crate termios;
extern crate termios;
#[cfg(windows)]
extern crate winapi;

View File

@ -2,32 +2,27 @@
//! This module is used for windows 10 terminals and unix terminals by default.
//! This module uses the stdout to write to the console.
use std::io::{self, Write};
use std::any::Any;
use std::io::{self, Write};
use super::IScreenManager;
pub struct AnsiScreenManager
{
pub struct AnsiScreenManager {
pub is_alternate_screen: bool,
output: Box<Write>,
}
impl IScreenManager for AnsiScreenManager
{
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
{
impl IScreenManager for AnsiScreenManager {
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
self.is_alternate_screen = is_alternate_screen;
}
fn write_ansi(&mut self, string: String)
{
fn write_ansi(&mut self, string: String) {
write!(self.output, "{}", string);
self.flush();
}
fn write_ansi_str(&mut self, string: &str)
{
fn write_ansi_str(&mut self, string: &str) {
write!(self.output, "{}", string);
self.flush();
}
@ -40,8 +35,7 @@ impl IScreenManager for AnsiScreenManager
self.output.flush()
}
fn as_any(&mut self) -> &mut Any
{
fn as_any(&mut self) -> &mut Any {
self
}
}
@ -50,7 +44,7 @@ impl AnsiScreenManager {
pub fn new() -> Self {
AnsiScreenManager {
output: (Box::from(io::stdout()) as Box<Write>),
is_alternate_screen: false
is_alternate_screen: false,
}
}
}
}

View File

@ -1,66 +1,64 @@
//! This module provides an interface for working with the screen. With that I mean that you can get or wirte to the handle of the current screen. stdout.
//! Because crossterm can work with alternate screen, we need a place that holds the handle to the current screen so we can write to that screen.
use super::*;
use super::super::shared::functions;
use super::*;
use std::any::Any;
use std::fmt::Display;
use std::io::{ self, Write };
use std::io::{self, Write};
#[cfg(target_os = "windows")]
use winapi::um::winnt::HANDLE;
/// Struct that stores an specific platform implementation for screen related actions.
pub struct ScreenManager
{
screen_manager: Box<IScreenManager>
pub struct ScreenManager {
screen_manager: Box<IScreenManager>,
}
impl ScreenManager
{
impl ScreenManager {
/// Create new screen manager instance whereon screen related actions can be performed.
pub fn new() -> ScreenManager {
#[cfg(target_os = "windows")]
let screen_manager = functions::get_module::<Box<IScreenManager>>(Box::from(WinApiScreenManager::new()), Box::from(AnsiScreenManager::new())).unwrap();
let screen_manager = functions::get_module::<Box<IScreenManager>>(
Box::from(WinApiScreenManager::new()),
Box::from(AnsiScreenManager::new()),
).unwrap();
#[cfg(not(target_os = "windows"))]
let screen_manager = Box::from(AnsiScreenManager::new()) as Box<IScreenManager>;
let screen_manager = Box::from(AnsiScreenManager::new()) as Box<IScreenManager>;
ScreenManager
{
screen_manager: screen_manager
ScreenManager {
screen_manager: screen_manager,
}
}
pub fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
{
self.screen_manager.toggle_is_alternate_screen(is_alternate_screen);
pub fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
self.screen_manager
.toggle_is_alternate_screen(is_alternate_screen);
}
/// Write an ANSI code as String.
pub fn write_ansi(&mut self, string: String)
{
pub fn write_ansi(&mut self, string: String) {
self.screen_manager.write_ansi(string);
}
/// Write an ANSI code as &str
pub fn write_ansi_str(&mut self, string: &str)
{
pub fn write_ansi_str(&mut self, string: &str) {
self.screen_manager.write_ansi_str(string);
}
/// Can be used to get an specific implementation used for the current platform.
pub fn as_any(&mut self) -> &mut Any { self.screen_manager.as_any() }
pub fn as_any(&mut self) -> &mut Any {
self.screen_manager.as_any()
}
pub fn write_val(&mut self, value: String)
{
pub fn write_val(&mut self, value: String) {
self.screen_manager.write(value.as_bytes());
}
}
impl Write for ScreenManager
{
impl Write for ScreenManager {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.write(buf)
}

View File

@ -3,20 +3,19 @@
pub mod manager;
mod ansi_manager;
#[cfg(target_os = "windows")]
mod win_manager;
mod ansi_manager;
pub use self::ansi_manager::AnsiScreenManager;
#[cfg(target_os = "windows")]
pub use self::win_manager::WinApiScreenManager;
pub use self::ansi_manager::AnsiScreenManager;
pub use self::manager::{ ScreenManager };
use std::io;
pub use self::manager::ScreenManager;
use std::any::Any;
use std::io;
pub trait IScreenManager
{
pub trait IScreenManager {
/// Toggle the value if alternatescreen is on.
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool);
/// Write ansi code as String to the current stdout.
@ -29,4 +28,4 @@ pub trait IScreenManager
fn flush(&mut self) -> io::Result<()>;
/// Can be used to convert to an specific IScreenManager implementation.
fn as_any(&mut self) -> &mut Any;
}
}

View File

@ -1,40 +1,33 @@
use super::IScreenManager;
use kernel::windows_kernel::kernel;
use winapi::um::winnt::HANDLE;
use winapi::um::wincon::ENABLE_PROCESSED_OUTPUT;
use winapi::um::winnt::HANDLE;
use std::io::{self,Write};
use std::any::Any;
use std::io::{self, Write};
use std::rc::Rc;
pub struct WinApiScreenManager
{
pub struct WinApiScreenManager {
pub is_alternate_screen: bool,
output: HANDLE,
alternate_handle: HANDLE
alternate_handle: HANDLE,
}
impl IScreenManager for WinApiScreenManager
{
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
{
impl IScreenManager for WinApiScreenManager {
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
self.is_alternate_screen = is_alternate_screen;
}
fn write_ansi(&mut self, string: String)
{ }
fn write_ansi(&mut self, string: String) {}
fn write_ansi_str(&mut self, string: &str)
{ }
fn write_ansi_str(&mut self, string: &str) {}
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if self.is_alternate_screen
{
kernel::write_char_buffer(self.alternate_handle, buf);
}
else {
kernel::write_char_buffer(self.output, buf);
}
if self.is_alternate_screen {
kernel::write_char_buffer(self.alternate_handle, buf);
} else {
kernel::write_char_buffer(self.output, buf);
}
Ok(0)
}
@ -42,8 +35,7 @@ impl IScreenManager for WinApiScreenManager
Ok(())
}
fn as_any(&mut self) -> &mut Any
{
fn as_any(&mut self) -> &mut Any {
self
}
}
@ -57,22 +49,18 @@ impl WinApiScreenManager {
}
}
pub fn set_alternate_handle(&mut self, alternate_handle: HANDLE)
{
pub fn set_alternate_handle(&mut self, alternate_handle: HANDLE) {
self.alternate_handle = alternate_handle;
// needs to be turned on so that escape characters like \n and \t will be processed.
kernel::set_console_mode(&self.alternate_handle, ENABLE_PROCESSED_OUTPUT as u32);
}
pub fn get_handle(&mut self) -> &HANDLE
{
if self.is_alternate_screen
{
pub fn get_handle(&mut self) -> &HANDLE {
if self.is_alternate_screen {
return &self.alternate_handle;
}
else {
} else {
return &self.output;
}
}
}
}

View File

@ -1,66 +1,60 @@
use Context;
use super::super::cursor;
use super::super::terminal::terminal;
use super::super::style;
use super::super::terminal::terminal;
use Context;
use std::fmt::Display;
use std::mem;
use std::rc::Rc;
use std::fmt::Display;
use std::sync::{ONCE_INIT, Once};
use std::sync::{Once, ONCE_INIT};
static START: Once = ONCE_INIT;
pub struct Environment
{
pub struct Environment {
context: Rc<Context>,
terminal: Box<terminal::Terminal>,
cursor: Box<cursor::TerminalCursor>,
color: Box<style::TerminalColor>
color: Box<style::TerminalColor>,
}
impl Environment
{
pub fn new() -> Environment
{
return Environment { context: Context::new(), terminal: unsafe{ mem::zeroed()}, cursor: unsafe{ mem::zeroed()}, color: unsafe{ mem::zeroed() }}
impl Environment {
pub fn new() -> Environment {
return Environment {
context: Context::new(),
terminal: unsafe { mem::zeroed() },
cursor: unsafe { mem::zeroed() },
color: unsafe { mem::zeroed() },
};
}
pub fn terminal(&mut self) -> &Box<terminal::Terminal>
{
pub fn terminal(&mut self) -> &Box<terminal::Terminal> {
START.call_once(|| {
self.terminal = terminal::terminal(self.context.clone());
self.terminal = terminal::terminal(self.context.clone());
});
&self.terminal
&self.terminal
}
pub fn cursor(&mut self) -> &Box<cursor::TerminalCursor>
{
pub fn cursor(&mut self) -> &Box<cursor::TerminalCursor> {
START.call_once(|| {
self.cursor = cursor::cursor(self.context.clone());
});
&self.cursor
}
pub fn color(&mut self) -> &Box<style::TerminalColor>
{
pub fn color(&mut self) -> &Box<style::TerminalColor> {
START.call_once(|| {
self.color = style::color(self.context.clone());
});
&self.color
}
pub fn paint<D: Display>(&mut self, value: D) -> style::StyledObject<D>
{
pub fn paint<D: Display>(&mut self, value: D) -> style::StyledObject<D> {
self.terminal().paint(value)
}
pub fn context(&self) -> Rc<Context>
{
return self.context.clone()
pub fn context(&self) -> Rc<Context> {
return self.context.clone();
}
}

View File

@ -1,9 +1,9 @@
//! Some actions need to preformed platform independently since they can not be solved `ANSI escape codes`.
use Context;
use ScreenManager;
use std::rc::Rc;
use std::sync::Mutex;
use Context;
use ScreenManager;
#[cfg(windows)]
use kernel::windows_kernel::terminal::{exit, terminal_size};
@ -12,11 +12,10 @@ use kernel::windows_kernel::terminal::{exit, terminal_size};
use kernel::windows_kernel::cursor::pos;
#[cfg(unix)]
use kernel::unix_kernel::terminal::{pos, exit,terminal_size };
use kernel::unix_kernel::terminal::{exit, pos, terminal_size};
/// Get the terminal size based on the current platform.
pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16)
{
pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
#[cfg(unix)]
return terminal_size(screen_manager);
@ -25,8 +24,7 @@ pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16
}
/// Get the cursor position based on the current platform.
pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16)
{
pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16) {
#[cfg(unix)]
return pos(context.clone());
@ -35,41 +33,37 @@ pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16)
}
/// exit the current terminal.
pub fn exit_terminal()
{
pub fn exit_terminal() {
#[cfg(unix)]
exit();
exit();
#[cfg(windows)]
exit();
exit();
}
#[cfg(windows)]
/// Get an module specific implementation based on the current platform.
pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T>
{
pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T> {
let mut term: Option<T> = None;
let mut does_support = true;
if cfg!(target_os = "windows") {
// #[cfg(windows)]
// use kernel::windows_kernel::ansi_support::try_enable_ansi_support;
// #[cfg(windows)]
// use kernel::windows_kernel::ansi_support::try_enable_ansi_support;
// Try to enable ansi on windows if not than use WINAPI.
// does_support = try_enable_ansi_support();
// does_support = try_enable_ansi_support();
does_support = false;
if !does_support
{
if !does_support {
term = Some(winapi_impl);
}
}
if does_support
{
if does_support {
println!("Does support");
term = Some(unix_impl);
}
term
}
}

View File

@ -2,10 +2,10 @@
#[macro_use]
pub mod macros;
pub mod traits;
pub mod environment;
pub mod functions;
pub mod screen;
pub mod environment;
pub mod traits;
#[cfg(target_os = "unix")]
pub mod raw;
pub mod raw;

View File

@ -26,27 +26,24 @@ use super::super::state::commands::unix_command::EnableRawModeCommand;
#[cfg(windows)]
use state::commands::win_commands::EnableRawModeCommand;
use {Context, CommandManager };
use state::commands::IStateCommand;
use {CommandManager, Context};
use std::io::{ self, Write};
use std::io::{self, Write};
use std::rc::Rc;
/// A wrapper for the raw terminal state. Which can be used to write to.
pub struct RawTerminal
{
context : Rc<Context>,
pub struct RawTerminal {
context: Rc<Context>,
command_id: u16,
}
/// Trait withs contains a method for switching into raw mode.
pub trait IntoRawMode: Write + Sized
{
fn into_raw_mode(&self, context:Rc<Context>) -> io::Result<RawTerminal>;
pub trait IntoRawMode: Write + Sized {
fn into_raw_mode(&self, context: Rc<Context>) -> io::Result<RawTerminal>;
}
impl <W: Write> IntoRawMode for W
{
impl<W: Write> IntoRawMode for W {
/// Raw mode means that input (stdin) won't be printed it will instead have to be written manually by
/// the program. The input isn't canonicalised or line buffered (that is, you can
/// read from input(stdin) one byte of a time).
@ -55,10 +52,14 @@ impl <W: Write> IntoRawMode for W
let success = CommandManager::execute(context.clone(), command_id);
if success
{
Ok(RawTerminal { context: context.clone(), command_id: command_id})
}else { panic!("cannot move into raw mode") }
if success {
Ok(RawTerminal {
context: context.clone(),
command_id: command_id,
})
} else {
panic!("cannot move into raw mode")
}
}
}
@ -79,10 +80,8 @@ impl Write for RawTerminal {
}
/// If an instance of `RawTerminal` will be dropped all terminal changes that are made will be undone.
impl Drop for RawTerminal
{
fn drop(&mut self)
{
impl Drop for RawTerminal {
fn drop(&mut self) {
let success = CommandManager::undo(self.context.clone(), self.command_id);
}
}
}

View File

@ -8,16 +8,16 @@
//! !! Note: this module is only working for unix and windows 10 terminals only. If you are using windows 10 or lower do not implement this functionality. Work in progress...
//!
use Context;
use state::commands::*;
use shared::functions;
use state::commands::*;
use Context;
use std::io::{self, Write};
use std::rc::Rc;
pub struct AlternateScreen {
context: Rc<Context>,
command_id: u16
command_id: u16,
}
impl AlternateScreen {
@ -27,14 +27,16 @@ impl AlternateScreen {
pub fn from(context: Rc<Context>) -> Self {
let command_id = get_to_alternate_screen_command(context.clone());
let screen = AlternateScreen { context: context, command_id: command_id };
let screen = AlternateScreen {
context: context,
command_id: command_id,
};
screen.to_alternate();
return screen;
}
/// Change the current screen to the mainscreen.
pub fn to_main(&self)
{
pub fn to_main(&self) {
let mut mutex = &self.context.state_manager;
{
let mut state_manager = mutex.lock().unwrap();
@ -48,8 +50,7 @@ impl AlternateScreen {
}
/// Change the current screen to alternate screen.
pub fn to_alternate(&self)
{
pub fn to_alternate(&self) {
let mut mutex = &self.context.state_manager;
{
let mut state_manager = mutex.lock().unwrap();
@ -79,10 +80,8 @@ impl Write for AlternateScreen {
}
}
impl Drop for AlternateScreen
{
fn drop(&mut self)
{
impl Drop for AlternateScreen {
fn drop(&mut self) {
use CommandManager;
CommandManager::undo(self.context.clone(), self.command_id);
@ -90,13 +89,15 @@ impl Drop for AlternateScreen
}
// Get the alternate screen command to enable and disable alternate screen based on the current platform
fn get_to_alternate_screen_command(context: Rc<Context>) -> u16
{
fn get_to_alternate_screen_command(context: Rc<Context>) -> u16 {
#[cfg(target_os = "windows")]
let command_id = functions::get_module::<u16>(win_commands::ToAlternateScreenBufferCommand::new(context.clone()), shared_commands::ToAlternateScreenBufferCommand::new(context.clone())).unwrap();
let command_id = functions::get_module::<u16>(
win_commands::ToAlternateScreenBufferCommand::new(context.clone()),
shared_commands::ToAlternateScreenBufferCommand::new(context.clone()),
).unwrap();
#[cfg(not(target_os = "windows"))]
let command_id = shared_commands::ToAlternateScreenBufferCommand::new(context.clone());
return command_id;
}
}

View File

@ -2,4 +2,3 @@
pub trait Empty {
fn empty() -> Self;
}

View File

@ -1,16 +1,14 @@
use super::commands::IStateCommand;
use std::rc::Rc;
use std::sync::Mutex;
use Context;
use super::commands::IStateCommand;
/// Simple wrapper for executing an command.
pub struct CommandManager;
impl CommandManager
{
impl CommandManager {
/// execute an certain command by id.
pub fn execute(context: Rc<Context>, command_id: u16) -> bool
{
pub fn execute(context: Rc<Context>, command_id: u16) -> bool {
let mut mutex: Rc<Mutex<Box<IStateCommand>>>;
let mut state = context.state_manager.lock().unwrap();
@ -24,8 +22,7 @@ impl CommandManager
}
/// undo an certain command by id.
pub fn undo(context: Rc<Context>, command_id: u16) -> bool
{
pub fn undo(context: Rc<Context>, command_id: u16) -> bool {
let mut mutex: Rc<Mutex<Box<IStateCommand>>>;
let mut state = context.state_manager.lock().unwrap();
@ -37,4 +34,4 @@ impl CommandManager
let has_succeeded = command.undo();
return has_succeeded;
}
}
}

View File

@ -9,8 +9,8 @@
//!
//! See the `StateManager` struct where we store the commands for more info.
use std::sync::Mutex;
use std::rc::Rc;
use std::sync::Mutex;
#[cfg(unix)]
pub mod unix_command;
@ -25,11 +25,9 @@ pub use self::unix_command::*;
#[cfg(windows)]
pub use self::win_commands::*;
/// This command is used for complex commands whits change the terminal state.
/// By passing an `Context` instance this command will register it self to notify the terminal state change.
pub trait IStateCommand
{
pub trait IStateCommand {
fn execute(&mut self) -> bool;
fn undo(&mut self) -> bool;
}
}

View File

@ -1,38 +1,34 @@
//! This module contains the commands that can be used for both unix and windows systems. Or else said terminals that support ansi codes.
use super::IStateCommand;
use Context;
use super::{IStateCommand};
use std::rc::Rc;
pub struct EmptyCommand;
impl IStateCommand for EmptyCommand
{
fn execute(&mut self) -> bool
{
return false
impl IStateCommand for EmptyCommand {
fn execute(&mut self) -> bool {
return false;
}
fn undo(&mut self) -> bool
{
return false;
fn undo(&mut self) -> bool {
return false;
}
}
/// This command is used for switching to alternate screen and back to main screen.
pub struct ToAlternateScreenBufferCommand
{
context: Rc<Context>
pub struct ToAlternateScreenBufferCommand {
context: Rc<Context>,
}
impl ToAlternateScreenBufferCommand
{
impl ToAlternateScreenBufferCommand {
pub fn new(context: Rc<Context>) -> u16 {
let mut state = context.state_manager.lock().unwrap();
{
let key = state.get_changes_count();
let command = ToAlternateScreenBufferCommand {context: context.clone()};
let command = ToAlternateScreenBufferCommand {
context: context.clone(),
};
state.register_change(Box::from(command), key);
key
@ -40,11 +36,8 @@ impl ToAlternateScreenBufferCommand
}
}
impl IStateCommand for ToAlternateScreenBufferCommand
{
fn execute(&mut self) -> bool
{
impl IStateCommand for ToAlternateScreenBufferCommand {
fn execute(&mut self) -> bool {
println!("asdfasdf");
let mut screen = self.context.screen_manager.lock().unwrap();
{
@ -53,8 +46,7 @@ impl IStateCommand for ToAlternateScreenBufferCommand
}
}
fn undo(&mut self) -> bool
{
fn undo(&mut self) -> bool {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_ansi_str(csi!("?1049l"));
@ -62,4 +54,4 @@ impl IStateCommand for ToAlternateScreenBufferCommand
return true;
}
}
}
}

View File

@ -1,26 +1,23 @@
//! This module contains the commands that can be used for unix systems.
use {Context, StateManager, CommandManager};
use super::IStateCommand;
use kernel::unix_kernel::terminal;
use termios::{Termios, tcsetattr, TCSAFLUSH, ICANON, ECHO, CREAD};
use termios::{tcsetattr, Termios, CREAD, ECHO, ICANON, TCSAFLUSH};
use {CommandManager, Context, StateManager};
const FD_STDIN: ::std::os::unix::io::RawFd = 1;
use std::sync::Mutex;
use std::rc::Rc;
use std::sync::Mutex;
/// This command is used for switching to NoncanonicalMode.
#[derive(Copy, Clone)]
pub struct NoncanonicalModeCommand
{
key: u16
pub struct NoncanonicalModeCommand {
key: u16,
}
impl NoncanonicalModeCommand
{
pub fn new(state_manager: &Mutex<StateManager>) -> u16
{
impl NoncanonicalModeCommand {
pub fn new(state_manager: &Mutex<StateManager>) -> u16 {
let mut state = state_manager.lock().unwrap();
{
let key = state.get_changes_count();
@ -32,63 +29,56 @@ impl NoncanonicalModeCommand
}
}
impl IStateCommand for NoncanonicalModeCommand
{
fn execute(&mut self) -> bool
{
impl IStateCommand for NoncanonicalModeCommand {
fn execute(&mut self) -> bool {
// Set noncanonical mode
if let Ok(orig) = Termios::from_fd(FD_STDIN)
{
if let Ok(orig) = Termios::from_fd(FD_STDIN) {
let mut noncan = orig.clone();
noncan.c_lflag &= !ICANON;
noncan.c_lflag &= !ECHO;
noncan.c_lflag &= !CREAD;
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan)
{
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) {
Ok(_) => return true,
Err(_) => return false,
};
}else {
return false
} else {
return false;
}
}
fn undo(&mut self) -> bool
{
fn undo(&mut self) -> bool {
// Disable noncanonical mode
if let Ok(orig) = Termios::from_fd(FD_STDIN)
{
let mut noncan = orig.clone();
noncan.c_lflag &= ICANON;
noncan.c_lflag &= ECHO;
noncan.c_lflag &= CREAD;
if let Ok(orig) = Termios::from_fd(FD_STDIN) {
let mut noncan = orig.clone();
noncan.c_lflag &= ICANON;
noncan.c_lflag &= ECHO;
noncan.c_lflag &= CREAD;
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan)
{
Ok(_) => return true,
Err(_) => return false,
};
}else {
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) {
Ok(_) => return true,
Err(_) => return false,
};
} else {
return false;
}
}
}
/// This command is used for enabling and disabling raw mode for the terminal.
pub struct EnableRawModeCommand
{
pub struct EnableRawModeCommand {
original_mode: Option<Box<Termios>>,
command_id: u16
command_id: u16,
}
impl EnableRawModeCommand
{
pub fn new(state_manager: &Mutex<StateManager>) -> u16{
impl EnableRawModeCommand {
pub fn new(state_manager: &Mutex<StateManager>) -> u16 {
let mut state = state_manager.lock().unwrap();
{
let key = state.get_changes_count();
let command = EnableRawModeCommand { original_mode: None, command_id: key };
let command = EnableRawModeCommand {
original_mode: None,
command_id: key,
};
state.register_change(Box::from(command), key);
key
@ -96,37 +86,30 @@ impl EnableRawModeCommand
}
}
impl IStateCommand for EnableRawModeCommand
{
fn execute(&mut self) -> bool
{
impl IStateCommand for EnableRawModeCommand {
fn execute(&mut self) -> bool {
let original_mode = terminal::get_terminal_mode();
if let Ok(original_mode) = original_mode
{
if let Ok(original_mode) = original_mode {
self.original_mode = Some(Box::from(original_mode));
let mut new_mode = original_mode;
terminal::make_raw(&mut new_mode);
terminal::set_terminal_mode(&new_mode);
true
}else {
} else {
return false;
}
}
fn undo(&mut self) -> bool
{
if let Some(ref original_mode) = self.original_mode
{
fn undo(&mut self) -> bool {
if let Some(ref original_mode) = self.original_mode {
let result = terminal::set_terminal_mode(&original_mode);
match result
{
match result {
Ok(()) => true,
Err(_) => false
Err(_) => false,
}
}else {
} else {
return false;
}
}

View File

@ -1,13 +1,13 @@
//! This module contains the commands that can be used for windows systems.
use super::IStateCommand;
use {StateManager, Context};
use {Context, StateManager};
use kernel::windows_kernel::{kernel, ansi_support};
use kernel::windows_kernel::{ansi_support, kernel};
use std::mem;
use winapi::shared::minwindef::DWORD;
use winapi::um::wincon;
use winapi::um::wincon::{ENABLE_VIRTUAL_TERMINAL_PROCESSING, SMALL_RECT, COORD, CHAR_INFO};
use std::mem;
use winapi::um::wincon::{CHAR_INFO, COORD, ENABLE_VIRTUAL_TERMINAL_PROCESSING, SMALL_RECT};
use std::rc::Rc;
use std::sync::Mutex;
@ -15,67 +15,57 @@ use std::sync::Mutex;
/// This command is used for enabling and disabling ANSI code support for windows systems,
/// For more info check: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences.
#[derive(Clone, Copy)]
pub struct EnableAnsiCommand
{
pub struct EnableAnsiCommand {
mask: DWORD,
}
impl EnableAnsiCommand
{
impl EnableAnsiCommand {
pub fn new() -> Box<EnableAnsiCommand> {
let command = EnableAnsiCommand { mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING };
let command = EnableAnsiCommand {
mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING,
};
Box::from(command)
}
}
impl IStateCommand for EnableAnsiCommand
{
fn execute(&mut self) -> bool
{
impl IStateCommand for EnableAnsiCommand {
fn execute(&mut self) -> bool {
// we need to check whether we tried to enable ansi before. If we have we can just return if that had succeeded.
if ansi_support::has_been_tried_to_enable_ansi() && ansi_support::ansi_enabled()
{
return ansi_support::windows_supportable();
} else {
if ansi_support::has_been_tried_to_enable_ansi() && ansi_support::ansi_enabled() {
return ansi_support::windows_supportable();
} else {
let output_handle = kernel::get_output_handle();
let mut dw_mode: DWORD = 0;
if !kernel::get_console_mode(&output_handle, &mut dw_mode)
{
return false;
}
if !kernel::get_console_mode(&output_handle, &mut dw_mode) {
return false;
}
dw_mode |= self.mask;
if !kernel::set_console_mode(&output_handle, dw_mode)
{
return false;
}
if !kernel::set_console_mode(&output_handle, dw_mode) {
return false;
}
return true;
}
}
fn undo(&mut self) -> bool
{
if ansi_support::ansi_enabled()
{
let output_handle = kernel::get_output_handle();
fn undo(&mut self) -> bool {
if ansi_support::ansi_enabled() {
let output_handle = kernel::get_output_handle();
let mut dw_mode: DWORD = 0;
if !kernel::get_console_mode(&output_handle, &mut dw_mode)
{
return false;
}
dw_mode &= !self.mask;
if !kernel::set_console_mode(&output_handle, dw_mode)
{
return false;
}
ansi_support::set_ansi_enabled(false);
let mut dw_mode: DWORD = 0;
if !kernel::get_console_mode(&output_handle, &mut dw_mode) {
return false;
}
dw_mode &= !self.mask;
if !kernel::set_console_mode(&output_handle, dw_mode) {
return false;
}
ansi_support::set_ansi_enabled(false);
}
return true;
}
}
@ -83,65 +73,59 @@ impl IStateCommand for EnableAnsiCommand
/// This command is used for enabling and disabling raw mode for windows systems.
/// For more info check: https://docs.microsoft.com/en-us/windows/console/high-level-console-modes.
#[derive(Clone, Copy)]
pub struct EnableRawModeCommand
{
pub struct EnableRawModeCommand {
mask: DWORD,
key: u16,
}
impl EnableRawModeCommand
{
impl EnableRawModeCommand {
pub fn new(state_manager: &Mutex<StateManager>) -> u16 {
use self::wincon::{ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT, ENABLE_ECHO_INPUT};
use self::wincon::{ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT};
let mut state = state_manager.lock().unwrap();
{
let key = state.get_changes_count();
let command = EnableRawModeCommand { mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT, key: key };
let command = EnableRawModeCommand {
mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT,
key: key,
};
state.register_change(Box::from(command), key);
key
}
}
}
impl IStateCommand for EnableRawModeCommand
{
fn execute(&mut self) -> bool
{
impl IStateCommand for EnableRawModeCommand {
fn execute(&mut self) -> bool {
let input_handle = kernel::get_input_handle();
let mut dw_mode: DWORD = 0;
if !kernel::get_console_mode(&input_handle, &mut dw_mode)
{
return false;
}
if !kernel::get_console_mode(&input_handle, &mut dw_mode) {
return false;
}
let new_mode = dw_mode & !self.mask;
if !kernel::set_console_mode(&input_handle, new_mode)
{
return false;
}
if !kernel::set_console_mode(&input_handle, new_mode) {
return false;
}
true
}
fn undo(&mut self) -> bool
{
fn undo(&mut self) -> bool {
let output_handle = kernel::get_output_handle();
let mut dw_mode: DWORD = 0;
if !kernel::get_console_mode(&output_handle, &mut dw_mode)
{
return false;
}
if !kernel::get_console_mode(&output_handle, &mut dw_mode) {
return false;
}
let new_mode = dw_mode | self.mask;
if !kernel::set_console_mode(&output_handle, new_mode)
{
return false;
}
if !kernel::set_console_mode(&output_handle, new_mode) {
return false;
}
true
}
@ -149,19 +133,18 @@ impl IStateCommand for EnableRawModeCommand
/// This command is used for switching to alternate screen and back to main screen.
/// check https://docs.microsoft.com/en-us/windows/console/reading-and-writing-blocks-of-characters-and-attributes for more info
pub struct ToAlternateScreenBufferCommand
{
context: Rc<Context>
pub struct ToAlternateScreenBufferCommand {
context: Rc<Context>,
}
impl ToAlternateScreenBufferCommand
{
pub fn new(context: Rc<Context>) -> u16
{
impl ToAlternateScreenBufferCommand {
pub fn new(context: Rc<Context>) -> u16 {
let mut state = context.state_manager.lock().unwrap();
{
let key = state.get_changes_count();
let command = ToAlternateScreenBufferCommand { context: context.clone() };
let command = ToAlternateScreenBufferCommand {
context: context.clone(),
};
state.register_change(Box::from(command), key);
key
@ -169,10 +152,8 @@ impl ToAlternateScreenBufferCommand
}
}
impl IStateCommand for ToAlternateScreenBufferCommand
{
fn execute(&mut self) -> bool
{
impl IStateCommand for ToAlternateScreenBufferCommand {
fn execute(&mut self) -> bool {
use super::super::super::manager::WinApiScreenManager;
let mut chi_buffer: [CHAR_INFO; 160] = unsafe { mem::zeroed() };
@ -188,9 +169,12 @@ impl IStateCommand for ToAlternateScreenBufferCommand
let mut screen_manager = self.context.screen_manager.lock().unwrap();
screen_manager.toggle_is_alternate_screen(true);
let b: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
Some(b) => { b }
None => panic!("")
let b: &mut WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
{
Some(b) => b,
None => panic!(""),
};
b.set_alternate_handle(new_handle);
@ -198,8 +182,7 @@ impl IStateCommand for ToAlternateScreenBufferCommand
true
}
fn undo(&mut self) -> bool
{
fn undo(&mut self) -> bool {
let handle = kernel::get_output_handle();
kernel::set_active_screen_buffer(handle);

View File

@ -1,19 +1,17 @@
//! This module contains the code for the context of the terminal.
use { StateManager, ScreenManager };
use {ScreenManager, StateManager};
use std::sync::Mutex;
use std::rc::Rc;
use std::sync::Mutex;
/// This type contains the context of the current terminal. The context surrounds the changed states of the terminal and can be used for managing the output of the terminal.
pub struct Context
{
pub struct Context {
pub screen_manager: Rc<Mutex<ScreenManager>>,
pub state_manager: Mutex<StateManager>
pub state_manager: Mutex<StateManager>,
}
impl Context
{
impl Context {
/// Create new Context instance so that you can provide it to other modules like terminal, cursor and color
///
/// This context type is just an wrapper that crossterm uses for managing the state the terminal.
@ -36,21 +34,18 @@ impl Context
/// let color = terminal::color(&context);
///
/// ```
pub fn new() -> Rc<Context>
{
pub fn new() -> Rc<Context> {
Rc::new(Context {
screen_manager: Rc::new(Mutex::new(ScreenManager::new())),
state_manager: Mutex::new(StateManager::new())
state_manager: Mutex::new(StateManager::new()),
})
}
}
use std::io::Write;
impl Drop for Context
{
fn drop(&mut self)
{
impl Drop for Context {
fn drop(&mut self) {
panic!();
let mut changes = self.state_manager.lock().unwrap();
changes.restore_changes();

View File

@ -3,7 +3,7 @@
//! If `crossterm` changes some core state of the terminal like: enabling ANSI or enabling raw mode it should be reverted when the current process ends.
//! It would be a little lame to let the terminal in raw mode after the the current process ends for the user of this library.
pub mod state_manager;
pub mod commands;
pub mod command_manager;
pub mod context;
pub mod commands;
pub mod context;
pub mod state_manager;

View File

@ -1,33 +1,28 @@
//! This module is used for registering, storing an restoring the terminal state changes.
use super::commands::IStateCommand;
use super::commands::shared_commands::EmptyCommand;
use super::commands::IStateCommand;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Mutex;
use std::collections::HashMap;
/// Struct that stores the changed states of the terminal.
pub struct StateManager
{
pub struct StateManager {
changed_states: HashMap<u16, Rc<Mutex<Box<IStateCommand>>>>,
}
impl StateManager
{
impl StateManager {
/// Create new Context where the terminals states can be handled.
pub fn new() -> StateManager
{
pub fn new() -> StateManager {
StateManager {
changed_states: HashMap::new(),
}
}
/// Restore all changes that are made to the terminal.
pub fn restore_changes(&mut self)
{
for (id, item) in self.changed_states.iter_mut()
{
pub fn restore_changes(&mut self) {
for (id, item) in self.changed_states.iter_mut() {
let mut item = item.lock().unwrap();
item.undo();
@ -36,27 +31,20 @@ impl StateManager
}
/// Register new changed state with the given key.
pub fn register_change(&mut self, change: Box<IStateCommand>, key: u16)
{
pub fn register_change(&mut self, change: Box<IStateCommand>, key: u16) {
self.changed_states.insert(key, Rc::new(Mutex::new(change)));
}
/// Get an state command from storage by id.
pub fn get(&mut self, state_key: u16) -> Rc<Mutex<Box<IStateCommand>>>
{
if self.changed_states.contains_key(&state_key)
{
return self.changed_states[&state_key].clone()
pub fn get(&mut self, state_key: u16) -> Rc<Mutex<Box<IStateCommand>>> {
if self.changed_states.contains_key(&state_key) {
return self.changed_states[&state_key].clone();
}
return Rc::new(Mutex::new(Box::new(EmptyCommand)))
return Rc::new(Mutex::new(Box::new(EmptyCommand)));
}
pub fn get_changes_count(&self) -> u16
{
return self.changed_states.len() as u16
pub fn get_changes_count(&self) -> u16 {
return self.changed_states.len() as u16;
}
}

View File

@ -1,9 +1,9 @@
//! This is an ANSI specific implementation for styling related action.
//! This module is used for windows 10 terminals and unix terminals by default.
use ScreenManager;
use super::ITerminalColor;
use super::super::{Color, ColorType};
use super::ITerminalColor;
use ScreenManager;
use std::rc::Rc;
use std::sync::Mutex;
@ -20,17 +20,22 @@ impl AnsiColor {
impl ITerminalColor for AnsiColor {
fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let mut screen = screen_manager.lock().unwrap();
{
screen.write_ansi(format!(csi!("{}m"),self.color_value(fg_color, ColorType::Foreground)));
screen.write_ansi(format!(
csi!("{}m"),
self.color_value(fg_color, ColorType::Foreground)
));
}
}
fn set_bg(&self, bg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let mut screen = screen_manager.lock().unwrap();
{
screen.write_ansi(format!(csi!("{}m"),self.color_value(bg_color, ColorType::Background)));
screen.write_ansi(format!(
csi!("{}m"),
self.color_value(bg_color, ColorType::Background)
));
}
}
@ -42,28 +47,22 @@ impl ITerminalColor for AnsiColor {
}
fn color_value(&self, color: Color, color_type: ColorType) -> String {
let mut ansi_value = String::new();
match color_type
{
ColorType::Foreground => {
ansi_value.push_str("38;")
},
ColorType::Background => {
ansi_value.push_str("48;")
},
match color_type {
ColorType::Foreground => ansi_value.push_str("38;"),
ColorType::Background => ansi_value.push_str("48;"),
}
#[cfg(unix)]
let rgb_val: String;
let color_val = match color {
Color::Black => "5;0",
Color::Red => "5;9",
Color::DarkRed =>"5;1",
Color::DarkRed => "5;1",
Color::Green => "5;10",
Color::DarkGreen => "5;2",
Color::DarkGreen => "5;2",
Color::Yellow => "5;11",
Color::DarkYellow => "5;3",
Color::Blue => "5;12",
@ -72,15 +71,21 @@ impl ITerminalColor for AnsiColor {
Color::DarkMagenta => "5;5",
Color::Cyan => "5;14",
Color::DarkCyan => "5;6",
Color::Grey => "5;15",
Color::Grey => "5;15",
Color::White => "5;7",
#[cfg(unix)]
Color::Rgb{r,g,b} => { rgb_val = format!("2;{};{};{}", r,g,b); rgb_val.as_str()},
Color::Rgb { r, g, b } => {
rgb_val = format!("2;{};{};{}", r, g, b);
rgb_val.as_str()
}
#[cfg(unix)]
Color::AnsiValue(val) => { rgb_val = format!("5;{}",val); rgb_val.as_str() }
Color::AnsiValue(val) => {
rgb_val = format!("5;{}", val);
rgb_val.as_str()
}
};
ansi_value.push_str(color_val);
ansi_value
}
}
}

View File

@ -1,30 +1,36 @@
//! With this module you can perform actions that are color related.
//! Like styling the font, foreground color and background.
use {ScreenManager, Context};
use super::super::super::shared::functions;
use super::*;
use style::Color;
use std::io;
use std::rc::Rc;
use std::sync::Mutex;
use super::super::super::shared::functions;
use style::Color;
use {Context, ScreenManager};
/// Struct that stores an specific platform implementation for color related actions.
pub struct TerminalColor {
color: Option<Box<ITerminalColor>>,
screen_manager: Rc<Mutex<ScreenManager>>
screen_manager: Rc<Mutex<ScreenManager>>,
}
impl TerminalColor {
/// Create new instance whereon color related actions can be performed.
pub fn new(context: Rc<Context>) -> TerminalColor {
#[cfg(target_os = "windows")]
let color = functions::get_module::<Box<ITerminalColor>>(WinApiColor::new(context.screen_manager.clone()), AnsiColor::new());
let color = functions::get_module::<Box<ITerminalColor>>(
WinApiColor::new(context.screen_manager.clone()),
AnsiColor::new(),
);
#[cfg(not(target_os = "windows"))]
let color = Some(AnsiColor::new() as Box<ITerminalColor>);
TerminalColor { color: color, screen_manager: context.screen_manager.clone() }
TerminalColor {
color: color,
screen_manager: context.screen_manager.clone(),
}
}
/// Set the foreground color to the given color.
@ -41,7 +47,7 @@ impl TerminalColor {
///
/// // Get colored terminal instance
/// let mut colored_terminal = color(&context);
///
///
/// // Set foreground color of the font
/// colored_terminal.set_fg(Color::Red);
/// // crossterm provides to set the background from &str or String
@ -69,7 +75,7 @@ impl TerminalColor {
///
/// // Get colored terminal instance
/// let mut colored_terminal = color(&context);
///
///
/// // Set background color of the font
/// colored_terminal.set_bg(Color::Red);
/// // crossterm provides to set the background from &str or String
@ -95,7 +101,7 @@ impl TerminalColor {
///
/// // Get colored terminal instance
/// let mut colored_terminal = color(&context);
///
///
/// colored_terminal.reset();
///
/// ```
@ -106,10 +112,9 @@ impl TerminalColor {
}
/// Get available color count.
pub fn get_available_color_count(&self) -> io::Result<u16>
{
pub fn get_available_color_count(&self) -> io::Result<u16> {
use std::env;
Ok(match env::var_os("TERM") {
Some(val) => {
if val.to_str().unwrap_or("").contains("256color") {

View File

@ -1,15 +1,15 @@
pub mod color;
mod ansi_color;
#[cfg(target_os = "windows")]
mod winapi_color;
mod ansi_color;
use self::ansi_color::AnsiColor;
#[cfg(target_os = "windows")]
use self::winapi_color::WinApiColor;
use self::ansi_color::AnsiColor;
use { ScreenManager };
use super::{Color, ColorType};
use ScreenManager;
use std::rc::Rc;
use std::sync::Mutex;
@ -28,7 +28,7 @@ pub trait ITerminalColor {
/// Set the background color to the given color.
fn set_bg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>);
/// Reset the terminal color to default.
fn reset(&self,screen_manager: Rc<Mutex<ScreenManager>>);
fn reset(&self, screen_manager: Rc<Mutex<ScreenManager>>);
/// Gets an value that represents an color from the given `Color` and `ColorType`.
fn color_value(&self, color: Color, color_type: ColorType) -> String;
}
}

View File

@ -1,29 +1,28 @@
use super::super::{Color, ColorType};
use super::ITerminalColor;
use super::super::{ColorType, Color};
use winapi::um::wincon;
use kernel::windows_kernel::kernel;
use winapi::um::wincon;
use ScreenManager;
use std::sync::Mutex;
use std::rc::Rc;
use std::sync::Mutex;
/// This struct is an windows implementation for color related actions.
pub struct WinApiColor {
original_console_color: u16,
screen_manager: Rc<Mutex<ScreenManager>>
screen_manager: Rc<Mutex<ScreenManager>>,
}
impl WinApiColor {
pub fn new(screen_manager: Rc<Mutex<ScreenManager>>) -> Box<WinApiColor> {
Box::from(WinApiColor {
original_console_color: kernel::get_original_console_color(&screen_manager),
screen_manager: screen_manager
screen_manager: screen_manager,
})
}
}
impl ITerminalColor for WinApiColor {
fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let color_value = &self.color_value(fg_color, ColorType::Foreground);
@ -42,7 +41,7 @@ impl ITerminalColor for WinApiColor {
color = color | wincon::BACKGROUND_INTENSITY as u16;
}
kernel::set_console_text_attribute(color,&self.screen_manager);
kernel::set_console_text_attribute(color, &self.screen_manager);
}
fn set_bg(&self, bg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
@ -62,16 +61,15 @@ impl ITerminalColor for WinApiColor {
color = color | wincon::FOREGROUND_INTENSITY as u16;
}
kernel::set_console_text_attribute(color,&self.screen_manager);
kernel::set_console_text_attribute(color, &self.screen_manager);
}
fn reset(&self, screen_manager: Rc<Mutex<ScreenManager>>) {
kernel::set_console_text_attribute(self.original_console_color,&self.screen_manager);
kernel::set_console_text_attribute(self.original_console_color, &self.screen_manager);
}
/// This will get the winapi color value from the Color and ColorType struct
fn color_value(&self, color: Color, color_type: ColorType) -> String {
use style::{Color, ColorType};
let winapi_color: u16;

View File

@ -4,7 +4,7 @@
mod color;
mod styles;
pub use self::color::color::{color, TerminalColor };
pub use self::color::color::{color, TerminalColor};
pub use self::styles::objectstyle::ObjectStyle;
pub use self::styles::styledobject::StyledObject;
@ -21,7 +21,7 @@ pub enum Attribute {
RapidBlink = 6,
Reverse = 7,
Hidden = 8,
CrossedOut = 9
CrossedOut = 9,
}
/// Colors that are available for coloring the termainal font.
@ -51,9 +51,13 @@ pub enum Color {
White,
#[cfg(unix)]
Rgb { r: u8, g: u8, b:u8 },
Rgb {
r: u8,
g: u8,
b: u8,
},
#[cfg(unix)]
AnsiValue(u8)
AnsiValue(u8),
}
/// Color types that can be used to determine if the Color enum is an Fore- or Background Color
@ -100,4 +104,4 @@ impl FromStr for Color {
_ => Ok(Color::White),
}
}
}
}

View File

@ -1,4 +1,4 @@
//! This module contains the modules that are responsible for storing the styling displayable objects or simply set text.
pub mod objectstyle;
pub mod styledobject;
pub mod styledobject;

View File

@ -1,7 +1,7 @@
//! This module contains the `object style` that can be applied to an `styled object`.
use Context;
use style::{Color, StyledObject};
use Context;
use std::fmt::Display;
use std::rc::Rc;
@ -16,7 +16,7 @@ pub struct ObjectStyle {
pub bg_color: Option<Color>,
#[cfg(unix)]
pub attrs: Vec<Attribute>
pub attrs: Vec<Attribute>,
}
impl Default for ObjectStyle {
@ -25,7 +25,7 @@ impl Default for ObjectStyle {
fg_color: Some(Color::White),
bg_color: Some(Color::Black),
#[cfg(unix)]
attrs: Vec::new()
attrs: Vec::new(),
}
}
}
@ -49,7 +49,7 @@ impl ObjectStyle {
fg_color: None,
bg_color: None,
#[cfg(unix)]
attrs: Vec::new()
attrs: Vec::new(),
};
}
@ -66,8 +66,7 @@ impl ObjectStyle {
}
#[cfg(unix)]
pub fn add_attr(&mut self, attr: Attribute)
{
pub fn add_attr(&mut self, attr: Attribute) {
self.attrs.push(attr);
}
}

View File

@ -15,7 +15,7 @@ use style::{Color, ObjectStyle};
pub struct StyledObject<D> {
pub object_style: ObjectStyle,
pub content: D,
pub context: Rc<Context>
pub context: Rc<Context>,
}
impl<D> StyledObject<D> {
@ -37,7 +37,7 @@ impl<D> StyledObject<D> {
/// println!("{}", styledobject1);
/// // print an styled object directly.
/// println!("{}", paint("I am colored green").with(Color::Green));
///
///
/// ```
pub fn with(mut self, foreground_color: Color) -> StyledObject<D> {
self.object_style = self.object_style.fg(foreground_color);
@ -48,7 +48,7 @@ impl<D> StyledObject<D> {
///
/// #Example
///
/// ```rust
/// ```rust
/// extern crate crossterm;
/// use self::crossterm::style::{paint,Color};
///
@ -62,7 +62,7 @@ impl<D> StyledObject<D> {
/// println!("{}", styledobject1);
/// // print an styled object directly.
/// println!("{}", paint("I am colored green").on(Color::Green))
///
///
/// ```
pub fn on(mut self, background_color: Color) -> StyledObject<D> {
self.object_style = self.object_style.bg(background_color);
@ -74,72 +74,103 @@ impl<D> StyledObject<D> {
/// #Example
///
/// ```rust
///
///
/// extern crate crossterm;
/// use self::crossterm::style::{paint,Attribute};
///
/// println!("{}", paint("Bold").attr(Attribute::Bold));
///
///
/// ```
#[cfg(unix)]
pub fn attr(mut self, attr: Attribute) -> StyledObject<D>
{
pub fn attr(mut self, attr: Attribute) -> StyledObject<D> {
&self.object_style.add_attr(attr);
self
}
/// Increase the font intensity.
#[cfg(unix)]#[inline(always)] pub fn bold(self) -> StyledObject<D> { self.attr(Attribute::Bold) }
#[cfg(unix)]
#[inline(always)]
pub fn bold(self) -> StyledObject<D> {
self.attr(Attribute::Bold)
}
/// Faint (decreased intensity) (Not widely supported).
#[cfg(unix)]#[inline(always)] pub fn dim(self) -> StyledObject<D> { self.attr(Attribute::Dim) }
#[cfg(unix)]
#[inline(always)]
pub fn dim(self) -> StyledObject<D> {
self.attr(Attribute::Dim)
}
/// Make the font italic (Not widely supported; Sometimes treated as inverse).
#[cfg(unix)]#[inline(always)] pub fn italic(self) -> StyledObject<D> { self.attr(Attribute::Italic) }
#[cfg(unix)]
#[inline(always)]
pub fn italic(self) -> StyledObject<D> {
self.attr(Attribute::Italic)
}
/// Underline font.
#[cfg(unix)]#[inline(always)] pub fn underlined(self) -> StyledObject<D> { self.attr(Attribute::Underlined) }
#[cfg(unix)]
#[inline(always)]
pub fn underlined(self) -> StyledObject<D> {
self.attr(Attribute::Underlined)
}
/// Slow Blink (less than 150 per minute; not widely supported).
#[cfg(unix)]#[inline(always)] pub fn slow_blink(self) -> StyledObject<D> { self.attr(Attribute::SlowBlink) }
#[cfg(unix)]
#[inline(always)]
pub fn slow_blink(self) -> StyledObject<D> {
self.attr(Attribute::SlowBlink)
}
/// Rapid Blink (MS-DOS ANSI.SYS; 150+ per minute; not widely supported).
#[cfg(unix)]#[inline(always)] pub fn rapid_blink(self) -> StyledObject<D> { self.attr(Attribute::RapidBlink) }
/// Swap foreground and background colors.
#[cfg(unix)]#[inline(always)] pub fn reverse(self) -> StyledObject<D> { self.attr(Attribute::Reverse) }
#[cfg(unix)]
#[inline(always)]
pub fn rapid_blink(self) -> StyledObject<D> {
self.attr(Attribute::RapidBlink)
}
/// Swap foreground and background colors.
#[cfg(unix)]
#[inline(always)]
pub fn reverse(self) -> StyledObject<D> {
self.attr(Attribute::Reverse)
}
/// Hide text (Not widely supported).
#[cfg(unix)]#[inline(always)] pub fn hidden(self) -> StyledObject<D> { self.attr(Attribute::Hidden) }
#[cfg(unix)]
#[inline(always)]
pub fn hidden(self) -> StyledObject<D> {
self.attr(Attribute::Hidden)
}
/// Characters legible, but marked for deletion. Not widely supported.
#[cfg(unix)]#[inline(always)] pub fn crossed_out(self) -> StyledObject<D> { self.attr(Attribute::CrossedOut) }
#[cfg(unix)]
#[inline(always)]
pub fn crossed_out(self) -> StyledObject<D> {
self.attr(Attribute::CrossedOut)
}
}
/// This is used to make StyledObject able to be displayed.
/// This macro will set the styles stored in Styled Object
macro_rules! impl_fmt
{
macro_rules! impl_fmt {
($name:ident) => {
impl<D: fmt::$name> fmt::$name for StyledObject<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut colored_terminal = super::super::color(self.context.clone());
let mut reset = true;
if let Some(bg) = self.object_style.bg_color
{
if let Some(bg) = self.object_style.bg_color {
colored_terminal.set_bg(bg);
reset = true;
}
if let Some(fg) = self.object_style.fg_color
{
colored_terminal.set_fg(fg);
reset = true;
if let Some(fg) = self.object_style.fg_color {
colored_terminal.set_fg(fg);
reset = true;
}
#[cfg(unix)]
for attr in self.object_style.attrs.iter() {
let mutex = &self.context.screen_manager;
for attr in self.object_style.attrs.iter() {
let mutex = &self.context.screen_manager;
{
let mut screen = mutex.lock().unwrap();
screen.write_ansi(format!(csi!("{}m"), *attr as i16));
screen.write_ansi(format!(csi!("{}m"), *attr as i16));
}
reset = true;
}
}
fmt::$name::fmt(&self.content, f)?;
@ -149,15 +180,14 @@ macro_rules! impl_fmt
screen.flush();
}
if reset
{
if reset {
colored_terminal.reset();
}
Ok(())
}
}
}
};
}
impl_fmt!(Debug);

View File

@ -1,43 +1,41 @@
//! This is an `ANSI escape code` specific implementation for terminal related action.
//! This module is used for windows 10 terminals and unix terminals by default.
use Context;
use shared::functions;
use super::{ClearType, ITerminal, Rc};
use shared::functions;
use Context;
/// This struct is an ansi implementation for terminal related actions.
pub struct AnsiTerminal
{
context: Rc<Context>
pub struct AnsiTerminal {
context: Rc<Context>,
}
impl AnsiTerminal {
pub fn new(context: Rc<Context>) -> Box<AnsiTerminal> {
Box::from(AnsiTerminal {context: context})
Box::from(AnsiTerminal { context: context })
}
}
impl ITerminal for AnsiTerminal {
fn clear(&self, clear_type: ClearType)
{
fn clear(&self, clear_type: ClearType) {
let mut screen_manager = self.context.screen_manager.lock().unwrap();
{
match clear_type {
ClearType::All => {
screen_manager.write_ansi_str(csi!("2J"));
},
}
ClearType::FromCursorDown => {
screen_manager.write_ansi_str(csi!("J"));
},
}
ClearType::FromCursorUp => {
screen_manager.write_ansi_str(csi!("1J"));
},
}
ClearType::CurrentLine => {
screen_manager.write_ansi_str(csi!("2K"));
},
}
ClearType::UntilNewLine => {
screen_manager.write_ansi_str(csi!("K"));
},
}
};
}
}
@ -67,8 +65,7 @@ impl ITerminal for AnsiTerminal {
}
}
fn exit(&self)
{
fn exit(&self) {
functions::exit_terminal();
}
}

View File

@ -8,17 +8,17 @@
pub mod terminal;
mod ansi_terminal;
#[cfg(target_os = "windows")]
mod winapi_terminal;
mod ansi_terminal;
use self::ansi_terminal::AnsiTerminal;
#[cfg(target_os = "windows")]
use self::winapi_terminal::WinApiTerminal;
use self::ansi_terminal::AnsiTerminal;
use std::rc::Rc;
pub use self::terminal::terminal;
use Context;
pub use self::terminal::{ terminal};
/// Enum that can be used for the kind of clearing that can be done in the terminal.
pub enum ClearType {
@ -47,7 +47,7 @@ pub trait ITerminal {
/// Scroll `n` lines down in the current terminal.
fn scroll_down(&self, count: i16);
/// Resize terminal to the given width and height.
fn set_size(&self,width: i16, height: i16);
fn set_size(&self, width: i16, height: i16);
/// Close the current terminal
fn exit(&self);
}

View File

@ -1,36 +1,41 @@
//! With this module you can perform actions that are terminal related.
//! Like clearing and scrolling in the terminal or getting the size of the terminal.
use super::super::shared::functions;
use super::super::style;
use super::*;
use Context;
use super::super::style;
use super::super::shared::functions;
use std::fmt::Write;
use std::fmt;
use std::fmt::Write;
use std::rc::Rc;
/// Struct that stores an specific platform implementation for terminal related actions.
pub struct Terminal {
terminal: Option<Box<ITerminal>>,
context: Rc<Context>
context: Rc<Context>,
}
impl Terminal {
/// Create new terminal instance whereon terminal related actions can be performed.
pub fn new(context: Rc<Context>) -> Terminal {
#[cfg(target_os = "windows")]
let terminal = functions::get_module::<Box<ITerminal>>(WinApiTerminal::new(context.clone()), AnsiTerminal::new(context.clone()));
let terminal = functions::get_module::<Box<ITerminal>>(
WinApiTerminal::new(context.clone()),
AnsiTerminal::new(context.clone()),
);
#[cfg(not(target_os = "windows"))]
let terminal = Some(AnsiTerminal::new(context.clone()) as Box<ITerminal>);
Terminal { terminal, context: context }
Terminal {
terminal,
context: context,
}
}
/// Clear the current cursor by specifying the clear type
///
///
/// #Example
///
/// ```rust
@ -41,7 +46,7 @@ impl Terminal {
///
/// let context = Context::new();
/// let mut term = terminal::terminal(&context);
///
///
/// // clear all cells in terminal.
/// term.clear(terminal::ClearType::All);
/// // clear all cells from the cursor position downwards in terminal.
@ -52,7 +57,7 @@ impl Terminal {
/// term.clear(terminal::ClearType::CurrentLine);
/// // clear all cells from cursor position until new line in terminal.
/// term.clear(terminal::ClearType::UntilNewLine);
///
///
/// ```
pub fn clear(&mut self, clear_type: ClearType) {
if let Some(ref terminal) = self.terminal {
@ -61,7 +66,7 @@ impl Terminal {
}
/// Get the terminal size (x,y).
///
///
/// #Example
///
/// ```rust
@ -75,17 +80,17 @@ impl Terminal {
///
/// let size = term.terminal_size();
/// println!("{:?}", size);
///
///
/// ```
pub fn terminal_size(&mut self) -> (u16, u16) {
if let Some(ref terminal) = self.terminal {
return terminal.terminal_size()
return terminal.terminal_size();
}
(0,0)
(0, 0)
}
/// Scroll `n` lines up in the current terminal.
///
///
/// #Example
///
/// ```rust
@ -96,10 +101,10 @@ impl Terminal {
///
/// let context = Context::new();
/// let mut term = terminal::terminal(&context);
///
///
/// // scroll up by 5 lines
/// let size = term.scroll_up(5);
///
///
/// ```
pub fn scroll_up(&mut self, count: i16) {
if let Some(ref terminal) = self.terminal {
@ -108,7 +113,7 @@ impl Terminal {
}
/// Scroll `n` lines up in the current terminal.
///
///
/// #Example
///
/// ```rust
@ -119,10 +124,10 @@ impl Terminal {
///
/// let context = Context::new();
/// let mut term = terminal::terminal(&context);
///
///
/// // scroll down by 5 lines
/// let size = term.scroll_down(5);
///
///
/// ```
pub fn scroll_down(&mut self, count: i16) {
if let Some(ref terminal) = self.terminal {
@ -145,12 +150,11 @@ impl Terminal {
///
/// // Set of the size to X: 10 and Y: 10
/// let size = term.set_size(10,10);
///
///
/// ```
pub fn set_size(&mut self, width: i16, height: i16)
{
if let Some (ref terminal) = self.terminal {
terminal.set_size(width,height);
pub fn set_size(&mut self, width: i16, height: i16) {
if let Some(ref terminal) = self.terminal {
terminal.set_size(width, height);
}
}
@ -182,21 +186,19 @@ impl Terminal {
/// }
/// ```
pub fn paint<D>(&self, val: D) -> style::StyledObject<D>
where
D: fmt::Display,
where
D: fmt::Display,
{
style::ObjectStyle::new().apply_to(val, self.context.clone())
}
pub fn exit(&self)
{
if let Some (ref terminal) = self.terminal {
pub fn exit(&self) {
if let Some(ref terminal) = self.terminal {
terminal.exit();
}
}
pub fn write<D: fmt::Display>(&mut self, value: D)
{
pub fn write<D: fmt::Display>(&mut self, value: D) {
let mut mutex = &self.context.screen_manager;
{
let mut screen_manager = mutex.lock().unwrap();

View File

@ -1,20 +1,19 @@
//! This is an `WINAPI` specific implementation for terminal related action.
//! This module is used for non supporting `ANSI` windows terminals.
use Context;
use cursor::cursor;
use super::{ClearType, ITerminal, Rc};
use winapi::um::wincon::{SMALL_RECT, COORD, CONSOLE_SCREEN_BUFFER_INFO,};
use kernel::windows_kernel::{kernel, terminal};
use super::super::shared::functions;
use super::super::ScreenManager;
use super::{ClearType, ITerminal, Rc};
use cursor::cursor;
use kernel::windows_kernel::{kernel, terminal};
use winapi::um::wincon::{CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT};
use Context;
use std::sync::Mutex;
/// This struct is an windows implementation for terminal related actions.
pub struct WinApiTerminal
{
context: Rc<Context>
pub struct WinApiTerminal {
context: Rc<Context>,
}
impl WinApiTerminal {
@ -24,15 +23,13 @@ impl WinApiTerminal {
}
impl ITerminal for WinApiTerminal {
fn clear(&self, clear_type: ClearType) {
let csbi = kernel::get_console_screen_buffer_info(&self.context.screen_manager);
let pos = cursor(self.context.clone()).pos();
match clear_type
{
match clear_type {
ClearType::All => clear_entire_screen(csbi, &self.context),
ClearType::FromCursorDown => clear_after_cursor(pos,csbi, &self.context),
ClearType::FromCursorDown => clear_after_cursor(pos, csbi, &self.context),
ClearType::FromCursorUp => clear_before_cursor(pos, csbi, &self.context),
ClearType::CurrentLine => clear_current_line(pos, csbi, &self.context),
ClearType::UntilNewLine => clear_until_line(pos, csbi, &self.context),
@ -40,7 +37,7 @@ impl ITerminal for WinApiTerminal {
}
fn terminal_size(&self) -> (u16, u16) {
terminal::terminal_size(&self.context.screen_manager)
terminal::terminal_size(&self.context.screen_manager)
}
fn scroll_up(&self, count: i16) {
@ -59,7 +56,8 @@ impl ITerminal for WinApiTerminal {
srct_window.Top += count; // move top down
srct_window.Bottom += count; // move bottom down
let success = kernel::set_console_info(true, &mut srct_window, &self.context.screen_manager);
let success =
kernel::set_console_info(true, &mut srct_window, &self.context.screen_manager);
if success {
panic!("Something went wrong when scrolling down");
}
@ -68,15 +66,13 @@ impl ITerminal for WinApiTerminal {
/// Set the current terminal size
fn set_size(&self, width: i16, height: i16) {
if width <= 0
{
panic!("Cannot set the terminal width lower than 1");
}
if width <= 0 {
panic!("Cannot set the terminal width lower than 1");
}
if height <= 0
{
panic!("Cannot set the terminal height lower then 1")
}
if height <= 0 {
panic!("Cannot set the terminal height lower then 1")
}
// Get the position of the current console window
let csbi = kernel::get_console_screen_buffer_info(&self.context.screen_manager);
@ -85,23 +81,23 @@ impl ITerminal for WinApiTerminal {
// If the buffer is smaller than this new window size, resize the
// buffer to be large enough. Include window position.
let mut resize_buffer = false;
let mut size = COORD { X: csbi.dwSize.X, Y: csbi.dwSize.Y };
let mut size = COORD {
X: csbi.dwSize.X,
Y: csbi.dwSize.Y,
};
if csbi.dwSize.X < csbi.srWindow.Left + width
{
if csbi.srWindow.Left >= i16::max_value() - width
{
panic!("Argument out of range when setting terminal width.");
}
size.X = csbi.srWindow.Left + width;
resize_buffer = true;
if csbi.dwSize.X < csbi.srWindow.Left + width {
if csbi.srWindow.Left >= i16::max_value() - width {
panic!("Argument out of range when setting terminal width.");
}
size.X = csbi.srWindow.Left + width;
resize_buffer = true;
}
if csbi.dwSize.Y < csbi.srWindow.Top + height {
if csbi.srWindow.Top >= i16::max_value() - height
{
panic!("Argument out of range when setting terminal height");
}
if csbi.srWindow.Top >= i16::max_value() - height {
panic!("Argument out of range when setting terminal height");
}
size.Y = csbi.srWindow.Top + height;
resize_buffer = true;
@ -110,10 +106,9 @@ impl ITerminal for WinApiTerminal {
if resize_buffer {
success = kernel::set_console_screen_buffer_size(size, &self.context.screen_manager);
if !success
{
panic!("Something went wrong when setting screen buffer size.");
}
if !success {
panic!("Something went wrong when setting screen buffer size.");
}
}
let mut fsr_window: SMALL_RECT = csbi.srWindow;
@ -131,43 +126,56 @@ impl ITerminal for WinApiTerminal {
let bounds = kernel::get_largest_console_window_size();
if width > bounds.X
{
panic!("Argument width: {} out of range when setting terminal width.", width);
if width > bounds.X {
panic!(
"Argument width: {} out of range when setting terminal width.",
width
);
}
if height > bounds.Y
{
panic!("Argument height: {} out of range when setting terminal height", height);
if height > bounds.Y {
panic!(
"Argument height: {} out of range when setting terminal height",
height
);
}
}
}
fn exit(&self)
{
fn exit(&self) {
functions::exit_terminal();
}
}
pub fn clear_after_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>) {
let (mut x,mut y) = pos;
pub fn clear_after_cursor(
pos: (u16, u16),
csbi: CONSOLE_SCREEN_BUFFER_INFO,
context: &Rc<Context>,
) {
let (mut x, mut y) = pos;
// if cursor position is at the outer right position
if x as i16 > csbi.dwSize.X
{
if x as i16 > csbi.dwSize.X {
y += 1;
x = 0;
}
// location where to start clearing
let start_location = COORD { X: x as i16, Y: y as i16};
let start_location = COORD {
X: x as i16,
Y: y as i16,
};
// get sum cells before cursor
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
clear(start_location,cells_to_write, &context.screen_manager);
clear(start_location, cells_to_write, &context.screen_manager);
}
pub fn clear_before_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>) {
let (xpos,ypos) = pos;
pub fn clear_before_cursor(
pos: (u16, u16),
csbi: CONSOLE_SCREEN_BUFFER_INFO,
context: &Rc<Context>,
) {
let (xpos, ypos) = pos;
// one cell after cursor position
let x = 0;
@ -175,9 +183,12 @@ pub fn clear_before_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, con
let y = 0;
// location where to start clearing
let start_location = COORD { X: x as i16, Y: y as i16};
let start_location = COORD {
X: x as i16,
Y: y as i16,
};
// get sum cells before cursor
let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1);
let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1);
clear(start_location, cells_to_write, &context.screen_manager);
}
@ -189,26 +200,35 @@ pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Contex
let y = 0;
// location where to start clearing
let start_location = COORD { X: x as i16, Y: y as i16};
let start_location = COORD {
X: x as i16,
Y: y as i16,
};
// get sum cells before cursor
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
clear( start_location, cells_to_write, &context.screen_manager);
clear(start_location, cells_to_write, &context.screen_manager);
// put the cursor back at (0, 0)
cursor(context.clone()).goto(0, 0);
}
pub fn clear_current_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>)
{
pub fn clear_current_line(
pos: (u16, u16),
csbi: CONSOLE_SCREEN_BUFFER_INFO,
context: &Rc<Context>,
) {
// position x at start
let x = 0;
// position y at start
let y = pos.1;
// location where to start clearing
let start_location = COORD { X: x as i16, Y: y as i16};
let start_location = COORD {
X: x as i16,
Y: y as i16,
};
// get sum cells before cursor
let cells_to_write = csbi.dwSize.X as u32;
@ -219,41 +239,48 @@ pub fn clear_current_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, cont
cursor(context.clone()).goto(0, y);
}
pub fn clear_until_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>)
{
let (x,y) = pos;
pub fn clear_until_line(pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>) {
let (x, y) = pos;
// location where to start clearing
let start_location = COORD { X: x as i16, Y: y as i16};
let start_location = COORD {
X: x as i16,
Y: y as i16,
};
// get sum cells before cursor
let cells_to_write = (csbi.dwSize.X - x as i16) as u32;
let cells_to_write = (csbi.dwSize.X - x as i16) as u32;
clear(start_location, cells_to_write, &context.screen_manager);
// put the cursor back at original cursor position
cursor(context.clone()).goto(x,y);
cursor(context.clone()).goto(x, y);
}
fn clear(
start_loaction: COORD,
cells_to_write: u32,
screen_manager: &Rc<Mutex<ScreenManager>>
) {
fn clear(start_loaction: COORD, cells_to_write: u32, screen_manager: &Rc<Mutex<ScreenManager>>) {
let mut cells_written = 0;
let mut success = false;
success = kernel::fill_console_output_character(&mut cells_written, start_loaction, cells_to_write, screen_manager);
success = kernel::fill_console_output_character(
&mut cells_written,
start_loaction,
cells_to_write,
screen_manager,
);
if !success
{
if !success {
panic!("Could not clear screen after cursor");
}
cells_written = 0;
success = kernel::fill_console_output_attribute(&mut cells_written, start_loaction, cells_to_write, screen_manager);
success = kernel::fill_console_output_attribute(
&mut cells_written,
start_loaction,
cells_to_write,
screen_manager,
);
if !success {
panic!("Couldnot reset attributes after cursor");
}
}
}