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"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="310aeab2-4737-4e8e-b7eb-0aac10d104a3" name="Default" comment=""> <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)/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)/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)/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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" /> <change beforePath="$PROJECT_DIR$/src/terminal/winapi_terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/winapi_terminal.rs" afterDir="false" />
</list> </list>
@ -47,88 +64,11 @@
</component> </component>
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="cursor.rs" pinned="false" current-in-tab="false"> <file leaf-file-name="raw.rs" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/cursor/cursor.rs"> <entry file="file://$PROJECT_DIR$/src/shared/raw.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408"> <state relative-caret-position="357">
<caret line="313" column="11" selection-start-line="313" selection-start-column="11" selection-end-line="313" selection-end-column="11" /> <caret line="53" lean-forward="true" selection-start-line="53" selection-end-line="53" />
</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> </state>
</provider> </provider>
</entry> </entry>
@ -209,7 +149,6 @@
<option value="$PROJECT_DIR$/src/terminal/mod.rs" /> <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$/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/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)/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)/color/mod.rs" />
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/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$/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$/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/kernel/windows_kernel/kernel.rs" />
<option value="$PROJECT_DIR$/src/shared/raw.rs" />
</list> </list>
</option> </option>
</component> </component>
@ -622,12 +562,12 @@
<workItem from="1530289442537" duration="10502000" /> <workItem from="1530289442537" duration="10502000" />
<workItem from="1530344478032" duration="18289000" /> <workItem from="1530344478032" duration="18289000" />
<workItem from="1530446561530" duration="7222000" /> <workItem from="1530446561530" duration="7222000" />
<workItem from="1530473645162" duration="3874000" /> <workItem from="1530473645162" duration="4134000" />
</task> </task>
<servers /> <servers />
</component> </component>
<component name="TimeTrackingManager"> <component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="681698000" /> <option name="totallyTimeSpent" value="681958000" />
</component> </component>
<component name="ToolWindowManager"> <component name="ToolWindowManager">
<frame x="-8" y="-8" width="2576" height="1056" extended-state="6" /> <frame x="-8" y="-8" width="2576" height="1056" extended-state="6" />
@ -699,27 +639,6 @@
<option name="myLimit" value="2678400000" /> <option name="myLimit" value="2678400000" />
</component> </component>
<component name="editorHistoryManager"> <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"> <entry file="file://$PROJECT_DIR$/src/state/state_manager.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="442"> <state relative-caret-position="442">
@ -862,13 +781,6 @@
<state relative-caret-position="-255" /> <state relative-caret-position="-255" />
</provider> </provider>
</entry> </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"> <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"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="275"> <state relative-caret-position="275">
@ -918,17 +830,6 @@
</state> </state>
</provider> </provider>
</entry> </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"> <entry file="file://$PROJECT_DIR$/src/terminal/winapi_terminal.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="424"> <state relative-caret-position="424">
@ -936,13 +837,6 @@
</state> </state>
</provider> </provider>
</entry> </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"> <entry file="file://$PROJECT_DIR$/src/shared/functions.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="228"> <state relative-caret-position="228">
@ -950,13 +844,6 @@
</state> </state>
</provider> </provider>
</entry> </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"> <entry file="file://$PROJECT_DIR$/src/manager/manager.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408"> <state relative-caret-position="408">
@ -973,25 +860,22 @@
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/style/color/winapi_color.rs"> <entry file="file://$PROJECT_DIR$/src/style/color/winapi_color.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="158"> <state relative-caret-position="141">
<caret line="64" column="69" selection-start-line="64" selection-start-column="69" selection-end-line="64" selection-end-column="69" /> <caret line="63" column="69" selection-start-line="63" selection-start-column="69" selection-end-line="63" selection-end-column="69" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/terminal/ansi_terminal.rs"> <entry file="file://$PROJECT_DIR$/src/terminal/ansi_terminal.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="391"> <state relative-caret-position="357">
<caret line="45" column="66" selection-start-line="45" selection-start-column="66" selection-end-line="45" selection-end-column="66" /> <caret line="43" column="66" selection-start-line="43" selection-start-column="66" selection-end-line="43" selection-end-column="66" />
</state> </state>
</provider> </provider>
</entry> </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"> <entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="459"> <state relative-caret-position="442">
<caret line="27" column="61" selection-start-line="27" selection-start-column="61" selection-end-line="27" selection-end-column="61" /> <caret line="26" column="61" selection-start-line="26" selection-start-column="61" selection-end-line="26" selection-end-column="61" />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -1004,36 +888,80 @@
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/terminal/terminal.rs"> <entry file="file://$PROJECT_DIR$/src/terminal/terminal.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="742"> <state relative-caret-position="844">
<caret line="197" column="11" selection-start-line="197" selection-start-column="11" selection-end-line="197" selection-end-column="11" /> <caret line="200" column="11" selection-start-line="200" selection-start-column="11" selection-end-line="200" selection-end-column="11" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs"> <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"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204"> <state relative-caret-position="187">
<caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" /> <caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/cursor/cursor.rs"> <entry file="file://$PROJECT_DIR$/src/cursor/cursor.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408"> <state relative-caret-position="459">
<caret line="313" column="11" selection-start-line="313" selection-start-column="11" selection-end-line="313" selection-end-column="11" /> <caret line="316" column="11" selection-start-line="316" selection-start-column="11" selection-end-line="316" selection-end-column="11" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/cursor/winapi_cursor.rs"> <entry file="file://$PROJECT_DIR$/src/cursor/winapi_cursor.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="498"> <state relative-caret-position="566">
<caret line="66" column="25" selection-start-line="66" selection-start-column="25" selection-end-line="66" selection-end-column="25" /> <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> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs"> <entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="540"> <state relative-caret-position="98">
<caret line="203" column="5" selection-start-line="203" selection-start-column="5" selection-end-line="203" selection-end-column="5" /> <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> </state>
</provider> </provider>
</entry> </entry>

View File

@ -13,13 +13,12 @@
extern crate crossterm; extern crate crossterm;
mod terminal;
mod cursor;
mod color; mod color;
mod cursor;
mod program_examples; mod program_examples;
mod terminal;
fn main() { fn main() {
use crossterm::Context; use crossterm::Context;
{ {

View File

@ -4,13 +4,12 @@
extern crate crossterm; extern crate crossterm;
use self::crossterm::style::{ Color }; use self::crossterm::style::Color;
use self::crossterm::terminal; use self::crossterm::terminal;
use self::crossterm::Context; use self::crossterm::Context;
/// print some red font | demonstration. /// print some red font | demonstration.
pub fn paint_foreground() pub fn paint_foreground() {
{
let context = Context::new(); let context = Context::new();
let terminal = terminal::terminal(context.clone()); let terminal = terminal::terminal(context.clone());
@ -27,8 +26,7 @@ pub fn paint_foreground()
} }
/// print some font on red background | demonstration. /// print some font on red background | demonstration.
pub fn paint_background() pub fn paint_background() {
{
let context = Context::new(); let context = Context::new();
let terminal = terminal::terminal(context.clone()); let terminal = terminal::terminal(context.clone());
@ -45,8 +43,7 @@ pub fn paint_background()
} }
/// print font with fore- background color | demonstration. /// print font with fore- background color | demonstration.
pub fn paint_foreground_and_background() pub fn paint_foreground_and_background() {
{
let context = Context::new(); let context = Context::new();
let terminal = terminal::terminal(context.clone()); let terminal = terminal::terminal(context.clone());
@ -67,35 +64,60 @@ pub fn paint_foreground_and_background()
println!("{}", styledobject); println!("{}", styledobject);
// Crossterm provides method chaining so that the above points can be inlined. // 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. /// Print all available foreground colors | demonstration.
pub fn print_all_foreground_colors() pub fn print_all_foreground_colors() {
{
let context = Context::new(); let context = Context::new();
let terminal = terminal::terminal(context.clone()); let terminal = terminal::terminal(context.clone());
println!("Black : \t {}", terminal.paint("").with(Color::Black)); println!("Black : \t {}", terminal.paint("").with(Color::Black));
println!("Red : \t\t {}", terminal.paint("").with(Color::Red)); 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!("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!("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!("Blue : \t\t {}", terminal.paint("").with(Color::Blue));
println!("Dark Blue : \t {}", terminal.paint("").with(Color::DarkBlue)); println!(
println!("Magenta : \t {}", terminal.paint("").with(Color::Magenta)); "Dark Blue : \t {}",
println!("Dark Magenta : \t {}", terminal.paint("").with(Color::DarkMagenta)); 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!("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!("Grey : \t\t {}", terminal.paint("").with(Color::Grey));
println!("White : \t {}", terminal.paint("").with(Color::White)); println!("White : \t {}", terminal.paint("").with(Color::White));
} }
/// Print all available foreground colors | demonstration. /// Print all available foreground colors | demonstration.
pub fn print_all_background_colors() pub fn print_all_background_colors() {
{
let context = Context::new(); let context = Context::new();
let terminal = terminal::terminal(context.clone()); 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!("Red : \t\t {}", terminal.paint(" ").on(Color::Red));
println!("Dark Red: \t {}", terminal.paint(" ").on(Color::DarkRed)); println!("Dark Red: \t {}", terminal.paint(" ").on(Color::DarkRed));
println!("Green : \t {}", terminal.paint(" ").on(Color::Green)); 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!("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!("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!("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!("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!("Grey : \t\t {}", terminal.paint(" ").on(Color::Grey));
println!("White : \t {}", terminal.paint(" ").on(Color::White)); println!("White : \t {}", terminal.paint(" ").on(Color::White));
#[cfg(unix)] #[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)] #[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.. /// 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)] #[cfg(unix)]
pub fn print_font_with_attributes() pub fn print_font_with_attributes() {
{
let context = Context::new(); let context = Context::new();
let terminal = terminal::terminal(context.clone()); let terminal = terminal::terminal(context.clone());
@ -141,15 +187,20 @@ pub fn print_font_with_attributes()
/// Print all supported rgb colors | demonstration. /// Print all supported rgb colors | demonstration.
#[cfg(unix)] #[cfg(unix)]
pub fn print_supported_colors() pub fn print_supported_colors() {
{
let context = Context::new(); let context = Context::new();
let terminal = terminal::terminal(context.clone()); 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 for i in 0..count {
{ println!(
println!("{}", terminal.paint(format!("Color: {}",i)).with(Color::AnsiValue(i as u8))); "{}",
terminal
.paint(format!("Color: {}", i))
.with(Color::AnsiValue(i as u8))
);
} }
} }

View File

@ -7,30 +7,27 @@ use self::crossterm::cursor::{cursor, TerminalCursor};
use self::crossterm::Context; use self::crossterm::Context;
/// Set the cursor to position X: 10, Y: 5 in the terminal. /// Set the cursor to position X: 10, Y: 5 in the terminal.
pub fn goto() pub fn goto() {
{
let context = Context::new(); let context = Context::new();
// Get the cursor // Get the cursor
let mut cursor = cursor(context.clone()); let mut cursor = cursor(context.clone());
// Set the cursor to position X: 10, Y: 5 in the terminal // Set the cursor to position X: 10, Y: 5 in the terminal
cursor.goto(10,5); cursor.goto(10, 5);
} }
/// get the cursor position /// get the cursor position
pub fn pos() pub fn pos() {
{
let context = Context::new(); let context = Context::new();
// Get the cursor // Get the cursor
let mut cursor = cursor(context.clone()); let mut cursor = cursor(context.clone());
// get the cursor position. // get the cursor position.
let (x,y) = cursor.pos(); let (x, y) = cursor.pos();
} }
/// Move the cursor 3 up | demonstration. /// Move the cursor 3 up | demonstration.
pub fn move_up() pub fn move_up() {
{
let context = Context::new(); let context = Context::new();
// Get the cursor // Get the cursor
@ -40,8 +37,7 @@ pub fn move_up()
} }
/// Move the cursor 3 to the right | demonstration. /// Move the cursor 3 to the right | demonstration.
pub fn move_right() pub fn move_right() {
{
let context = Context::new(); let context = Context::new();
// Get the cursor // Get the cursor
@ -51,8 +47,7 @@ pub fn move_right()
} }
/// Move the cursor 3 down | demonstration. /// Move the cursor 3 down | demonstration.
pub fn move_down() pub fn move_down() {
{
let context = Context::new(); let context = Context::new();
// Get the cursor // Get the cursor
@ -62,8 +57,7 @@ pub fn move_down()
} }
/// Move the cursor 3 to the left | demonstration. /// Move the cursor 3 to the left | demonstration.
pub fn move_left() pub fn move_left() {
{
let context = Context::new(); let context = Context::new();
// Get the cursor // Get the cursor
@ -73,8 +67,7 @@ pub fn move_left()
} }
/// Print character at X: 10 Y: 5 | demonstration. /// Print character at X: 10 Y: 5 | demonstration.
pub fn print() pub fn print() {
{
let context = Context::new(); let context = Context::new();
// To print an some displayable content on an certain position. // To print an some displayable content on an certain position.
@ -82,7 +75,7 @@ pub fn print()
// Get the cursor // Get the cursor
let mut cursor = cursor(context.clone()); let mut cursor = cursor(context.clone());
// Set the cursor to position X: 10, Y: 5 in the terminal // 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 the @ symbol at position X: 10, Y: 5 in the terminal
print!("@"); 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.
@ -96,22 +89,21 @@ pub fn print()
Crossterm provides method chaining so that the above points can be inlined. 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.. /// Save and reset cursor position | demonstration..
pub fn safe_and_reset_position() pub fn safe_and_reset_position() {
{
let context = Context::new(); let context = Context::new();
let mut cursor = cursor(context.clone()); let mut cursor = cursor(context.clone());
// Goto X: 5 Y: 5 // Goto X: 5 Y: 5
cursor.goto(5,5); cursor.goto(5, 5);
// Safe cursor position: X: 5 Y: 5 // Safe cursor position: X: 5 Y: 5
cursor.save_position(); cursor.save_position();
// Goto X: 5 Y: 20 // Goto X: 5 Y: 20
cursor.goto(5,20); cursor.goto(5, 20);
// Print at X: 5 Y: 20. // Print at X: 5 Y: 20.
println!("Yea!"); println!("Yea!");
// Reset back to X: 5 Y: 5. // Reset back to X: 5 Y: 5.
@ -123,8 +115,7 @@ pub fn safe_and_reset_position()
} }
/// Hide cursor display | demonstration. /// Hide cursor display | demonstration.
pub fn hide_cursor() pub fn hide_cursor() {
{
let context = Context::new(); let context = Context::new();
let cursor = cursor(context.clone()); let cursor = cursor(context.clone());
@ -132,8 +123,7 @@ pub fn hide_cursor()
} }
/// Show cursor display | demonstration. /// Show cursor display | demonstration.
pub fn show_cursor() pub fn show_cursor() {
{
let context = Context::new(); let context = Context::new();
let cursor = cursor(context.clone()); let cursor = cursor(context.clone());
@ -141,32 +131,10 @@ pub fn show_cursor()
} }
/// Show cursor display, only works on certain terminals.| demonstration /// Show cursor display, only works on certain terminals.| demonstration
pub fn blink_cursor() pub fn blink_cursor() {
{
let context = Context::new(); let context = Context::new();
let cursor = cursor(context.clone()); let cursor = cursor(context.clone());
cursor.blink(false); cursor.blink(false);
cursor.blink(false); cursor.blink(false);
} }

View File

@ -1,42 +1,42 @@
extern crate crossterm; extern crate crossterm;
use crossterm::Context;
use crossterm::screen::AlternateScreen;
use crossterm::cursor::cursor; use crossterm::cursor::cursor;
use crossterm::screen::AlternateScreen;
use crossterm::terminal::{self, ClearType}; use crossterm::terminal::{self, ClearType};
use crossterm::Context;
use std::io::{Write, stdout}; use std::io::{stdout, Write};
use std::{time, thread};
use std::rc::Rc; 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()); let mut terminal = terminal::terminal(context.clone());
terminal.clear(ClearType::All); terminal.clear(ClearType::All);
let mut cursor = cursor(context.clone()); let mut cursor = cursor(context.clone());
cursor.goto(0,0); cursor.goto(0, 0);
cursor.hide(); cursor.hide();
terminal.write("Welcome to the wait screen.\n\ terminal.write(
Please wait a few seconds until we arrive back at the main screen.\n\ "Welcome to the wait screen.\n\
Progress: "); Please wait a few seconds until we arrive back at the main screen.\n\
Progress: ",
);
// print some progress example. // 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}` // 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 // 1 second delay
thread::sleep(time::Duration::from_secs(1)); thread::sleep(time::Duration::from_secs(1));
} }
} }
/// print wait screen on alternate screen, then swich back. /// 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. // create scope. If this scope ends the screen will be switched back to mainscreen.
// because `AlternateScreen` switches back to main screen when switching back. // 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. /// 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 context = Context::new();
let mut cursor = cursor(context.clone()); let mut cursor = cursor(context.clone());
{ {
// create new alternate screen instance and switch to the alternate screen. // create new alternate screen instance and switch to the alternate screen.
let mut screen = AlternateScreen::from(context.clone()); let mut screen = AlternateScreen::from(context.clone());
cursor.goto(0,0); cursor.goto(0, 0);
write!(screen, "we are at the alternate screen!"); write!(screen, "we are at the alternate screen!");
screen.flush(); screen.flush();
thread::sleep(time::Duration::from_secs(3)); thread::sleep(time::Duration::from_secs(3));

View File

@ -1,39 +1,40 @@
extern crate crossterm; extern crate crossterm;
use crossterm::Context;
use crossterm::screen::AlternateScreen;
use crossterm::cursor::cursor; use crossterm::cursor::cursor;
use crossterm::screen::AlternateScreen;
use crossterm::terminal::{self, ClearType}; use crossterm::terminal::{self, ClearType};
use crossterm::Context;
use std::io::{Write, stdout}; use std::io::{stdout, Write};
use std::{time, thread};
use std::rc::Rc; use std::rc::Rc;
use std::{thread, time};
use crossterm::raw::IntoRawMode; use crossterm::raw::IntoRawMode;
// raw screen is not working correctly currently // 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); terminal::terminal(context.clone()).clear(ClearType::All);
let mut cursor = cursor(context.clone()); let mut cursor = cursor(context.clone());
cursor.goto(0,0).print("Welcome to the wait screen."); 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
cursor.goto(0,2).print("Progress: "); .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. // 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}` // 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 // 1 second delay
thread::sleep(time::Duration::from_secs(1)); 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(); let context = Context::new();
// create scope. If this scope ends the screen will be switched back to mainscreen. // create scope. If this scope ends the screen will be switched back to mainscreen.

View File

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

View File

@ -2,14 +2,13 @@
//! This module is used for windows 10 terminals and unix terminals by default. //! 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. //! 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 super::*;
use shared::functions;
use Context;
/// This struct is an ansi implementation for cursor related actions. /// This struct is an ansi implementation for cursor related actions.
pub struct AnsiCursor pub struct AnsiCursor {
{ context: Rc<Context>,
context: Rc<Context>
} }
impl AnsiCursor { impl AnsiCursor {
@ -19,8 +18,7 @@ impl AnsiCursor {
} }
impl ITerminalCursor for 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(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {
screen.write_ansi(format!(csi!("{};{}H"), y + 1, x + 1)); 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(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {
screen.write_ansi_str(csi!("s")); screen.write_ansi_str(csi!("s"));
} }
} }
fn reset_position(&self) fn reset_position(&self) {
{
let mut screen = self.context.screen_manager.lock().unwrap(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {
screen.write_ansi_str(csi!("u")); screen.write_ansi_str(csi!("u"));
} }
} }
fn hide(&self) fn hide(&self) {
{
let mut screen = self.context.screen_manager.lock().unwrap(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {
screen.write_ansi_str(csi!("?25l")); screen.write_ansi_str(csi!("?25l"));
} }
} }
fn show(&self) fn show(&self) {
{
let mut screen = self.context.screen_manager.lock().unwrap(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {
screen.write_ansi_str(csi!("?25h")); 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(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {
if blink if blink {
{
screen.write_ansi_str(csi!("?12h")); screen.write_ansi_str(csi!("?12h"));
} } else {
else {
screen.write_ansi_str(csi!("?12l")); 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 //! 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::super::shared::functions;
use super::*;
use std::io::Write; use std::io::Write;
use Context;
use std::fmt::Display; use std::fmt::Display;
use std::rc::Rc; use std::rc::Rc;
@ -17,17 +17,22 @@ pub struct TerminalCursor {
terminal_cursor: Option<Box<ITerminalCursor>>, terminal_cursor: Option<Box<ITerminalCursor>>,
} }
impl TerminalCursor impl TerminalCursor {
{
/// Create new cursor instance whereon cursor related actions can be performed. /// Create new cursor instance whereon cursor related actions can be performed.
pub fn new(context: Rc<Context>) -> TerminalCursor { pub fn new(context: Rc<Context>) -> TerminalCursor {
#[cfg(target_os = "windows")] #[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"))] #[cfg(not(target_os = "windows"))]
let cursor = Some(AnsiCursor::new(context.clone()) as Box<ITerminalCursor>); 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. /// Goto some position (x,y) in the terminal.
@ -267,8 +272,7 @@ impl TerminalCursor
/// cursor::cursor(&context).safe_position(); /// 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 { if let Some(ref mut terminal_cursor) = self.terminal_cursor {
terminal_cursor.save_position(); terminal_cursor.save_position();
} }
@ -290,8 +294,7 @@ impl TerminalCursor
/// cursor(&context).reset_position(); /// 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 { if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.reset_position(); terminal_cursor.reset_position();
} }
@ -311,8 +314,7 @@ impl TerminalCursor
/// cursor(&context).hide(); /// cursor(&context).hide();
/// ///
/// ``` /// ```
pub fn hide(&self) pub fn hide(&self) {
{
if let Some(ref terminal_cursor) = self.terminal_cursor { if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.hide(); terminal_cursor.hide();
} }
@ -332,8 +334,7 @@ impl TerminalCursor
/// cursor(&context).show(); /// cursor(&context).show();
/// ///
/// ``` /// ```
pub fn show(&self) pub fn show(&self) {
{
if let Some(ref terminal_cursor) = self.terminal_cursor { if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.show(); terminal_cursor.show();
} }
@ -357,8 +358,7 @@ impl TerminalCursor
/// cursor.blink(false); /// cursor.blink(false);
/// ///
/// ``` /// ```
pub fn blink(&self, blink: bool) pub fn blink(&self, blink: bool) {
{
if let Some(ref terminal_cursor) = self.terminal_cursor { if let Some(ref terminal_cursor) = self.terminal_cursor {
terminal_cursor.blink(blink); terminal_cursor.blink(blink);
} }

View File

@ -10,15 +10,15 @@
pub mod cursor; pub mod cursor;
mod ansi_cursor;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
mod winapi_cursor; mod winapi_cursor;
mod ansi_cursor;
use self::ansi_cursor::AnsiCursor;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use self::winapi_cursor::WinApiCursor; 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; use std::rc::Rc;

View File

@ -1,18 +1,17 @@
//! This is an WINAPI specific implementation for cursor related action. //! This is an WINAPI specific implementation for cursor related action.
//! This module is used for windows terminals that do not support ANSI escape codes. //! 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. //! 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::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::rc::Rc;
use std::sync::Mutex; use std::sync::Mutex;
/// This struct is an windows implementation for cursor related actions. /// This struct is an windows implementation for cursor related actions.
pub struct WinApiCursor pub struct WinApiCursor {
{ screen_manager: Rc<Mutex<ScreenManager>>,
screen_manager: Rc<Mutex<ScreenManager>>
} }
impl WinApiCursor { impl WinApiCursor {
@ -21,10 +20,8 @@ impl WinApiCursor {
} }
} }
impl ITerminalCursor for WinApiCursor impl ITerminalCursor for WinApiCursor {
{
fn goto(&self, x: u16, y: u16) { fn goto(&self, x: u16, y: u16) {
kernel::set_console_cursor_position(x as i16, y as i16, &self.screen_manager); 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) { fn move_up(&self, count: u16) {
let (xpos,ypos) = self.pos(); let (xpos, ypos) = self.pos();
self.goto(xpos, ypos - count); self.goto(xpos, ypos - count);
} }
fn move_right(&self, count: u16) { fn move_right(&self, count: u16) {
let (xpos,ypos) = self.pos(); let (xpos, ypos) = self.pos();
self.goto(xpos + count, ypos); self.goto(xpos + count, ypos);
} }
fn move_down(&self, count: u16) { fn move_down(&self, count: u16) {
let (xpos,ypos) = self.pos(); let (xpos, ypos) = self.pos();
self.goto(xpos, ypos + count); self.goto(xpos, ypos + count);
} }
fn move_left(&self, count: u16) { fn move_left(&self, count: u16) {
let (xpos,ypos) = self.pos(); let (xpos, ypos) = self.pos();
self.goto(xpos - count, ypos); self.goto(xpos - count, ypos);
} }
fn save_position(&mut self) fn save_position(&mut self) {
{
cursor::save_cursor_pos(&self.screen_manager); cursor::save_cursor_pos(&self.screen_manager);
} }
fn reset_position(&self) fn reset_position(&self) {
{
cursor::reset_to_saved_position(&self.screen_manager); cursor::reset_to_saved_position(&self.screen_manager);
} }
fn hide(&self) fn hide(&self) {
{
kernel::cursor_visibility(false, &self.screen_manager); kernel::cursor_visibility(false, &self.screen_manager);
} }
fn show(&self) fn show(&self) {
{
kernel::cursor_visibility(true, &self.screen_manager); 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; pub mod unix_kernel;
#[cfg(windows)] #[cfg(windows)]
pub mod windows_kernel; pub mod windows_kernel;

View File

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

View File

@ -1,14 +1,14 @@
//! This module contains all `unix` specific terminal related logic. //! 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; use termios::Termios;
pub use self::libc::{termios}; use {libc, CommandManager, Context, StateManager};
use self::libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl, c_int};
use state::commands::{ NoncanonicalModeCommand, IStateCommand} ;
use std::io::Error; use std::io::Error;
use std::{ io, mem };
use std::rc::Rc; use std::rc::Rc;
use std::{io, mem};
/// A representation of the size of the current terminal. /// A representation of the size of the current terminal.
#[repr(C)] #[repr(C)]
@ -23,7 +23,7 @@ pub struct UnixSize {
} }
/// Get the current terminal size. /// 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 // http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
let us = UnixSize { let us = UnixSize {
rows: 0, rows: 0,
@ -34,16 +34,15 @@ pub fn terminal_size() -> (u16,u16) {
let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) }; let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
if r == 0 { 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. // 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 { } else {
(0,0) (0, 0)
} }
} }
/// Get the current cursor position. /// Get the current cursor position.
pub fn pos(context: Rc<Context>) -> (u16, u16) pub fn pos(context: Rc<Context>) -> (u16, u16) {
{ use std::io::{Read, Write};
use std::io::{ Write,Read };
let mut command_id = NoncanonicalModeCommand::new(&context.state_manager); 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(); let (cols, c) = read_num();
// Expect `R` // 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); 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. /// 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" { extern "C" {
pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int; 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. /// Get the current terminal mode.
pub fn get_terminal_mode() -> io::Result<Termios> pub fn get_terminal_mode() -> io::Result<Termios> {
{
extern "C" { extern "C" {
pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int; pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int;
} }
@ -132,16 +133,13 @@ pub fn get_terminal_mode() -> io::Result<Termios>
} }
} }
pub fn exit() pub fn exit() {
{
::std::process::exit(0); ::std::process::exit(0);
} }
/// Is the return value true? /// Is the return value true?
fn is_true(value: i32) -> Result<(), Error> fn is_true(value: i32) -> Result<(), Error> {
{ match value {
match value
{
-1 => Err(io::Error::last_os_error()), -1 => Err(io::Error::last_os_error()),
0 => Ok(()), 0 => Ok(()),
_ => Err(io::Error::last_os_error()), _ => Err(io::Error::last_os_error()),

View File

@ -1,16 +1,15 @@
//! This module handles the enabling `ANSI escape codes` for windows terminals. //! This module handles the enabling `ANSI escape codes` for windows terminals.
use IStateCommand;
use std::sync::{Once, ONCE_INIT}; use std::sync::{Once, ONCE_INIT};
use IStateCommand;
static mut HAS_BEEN_TRYED_TO_ENABLE: bool = false; static mut HAS_BEEN_TRYED_TO_ENABLE: bool = false;
static mut IS_ANSI_ON_WINDOWS_ENABLED: Option<bool> = None; 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; static START: Once = ONCE_INIT;
/// Try enable `ANSI escape codes` and return the result. /// 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(|| { START.call_once(|| {
use state::commands::win_commands::EnableAnsiCommand; use state::commands::win_commands::EnableAnsiCommand;
let mut command = EnableAnsiCommand::new(); let mut command = EnableAnsiCommand::new();
@ -21,53 +20,43 @@ pub fn try_enable_ansi_support() -> bool
has_been_tried_to_enable(true); has_been_tried_to_enable(true);
}); });
windows_supportable() windows_supportable()
} }
/// Get whether ansi has been enabled. /// Get whether ansi has been enabled.
pub fn ansi_enabled() -> bool pub fn ansi_enabled() -> bool {
{ unsafe { IS_ANSI_ON_WINDOWS_ENABLED.unwrap_or_else(|| false) }
unsafe { IS_ANSI_ON_WINDOWS_ENABLED.unwrap_or_else(| | false) }
} }
/// Get whether windows supports ansi /// Get whether windows supports ansi
pub fn windows_supportable() -> bool pub fn windows_supportable() -> bool {
{ unsafe { DOES_WINDOWS_SUPPORT_ANSI.unwrap_or_else(|| false) }
unsafe { DOES_WINDOWS_SUPPORT_ANSI.unwrap_or_else(| | false)}
} }
/// Get whether ansi has been tried to enable before. /// Get whether ansi has been tried to enable before.
pub fn has_been_tried_to_enable_ansi() -> bool pub fn has_been_tried_to_enable_ansi() -> bool {
{ unsafe {
unsafe
{
return HAS_BEEN_TRYED_TO_ENABLE; 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. /// 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) pub fn set_ansi_enabled(is_enabled: bool) {
{ unsafe {
unsafe
{
IS_ANSI_ON_WINDOWS_ENABLED = Some(is_enabled); IS_ANSI_ON_WINDOWS_ENABLED = Some(is_enabled);
} }
} }
/// Set the is_windows_ansi_supportable property. So whe can determine whether windows supports ansi. /// Set the is_windows_ansi_supportable property. So whe can determine whether windows supports ansi.
fn set_is_windows_ansi_supportable(is_enabled :bool) fn set_is_windows_ansi_supportable(is_enabled: bool) {
{ unsafe {
unsafe
{
DOES_WINDOWS_SUPPORT_ANSI = Some(is_enabled); 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. /// 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) fn has_been_tried_to_enable(has_been_tried: bool) {
{ unsafe {
unsafe
{
HAS_BEEN_TRYED_TO_ENABLE = has_been_tried; 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. //! This module handles some logic for cursor interaction in the windows console.
use super::kernel;
use super::super::super::manager::{ScreenManager, WinApiScreenManager}; use super::super::super::manager::{ScreenManager, WinApiScreenManager};
use super::kernel;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex; use std::sync::Mutex;
/// This stores the cursor pos, at program level. So it can be recalled later. /// 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 /// 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 { 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. /// 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); let position = pos(screen_manager);
unsafe { unsafe {
@ -28,8 +30,10 @@ pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>)
} }
/// get the current cursor position. /// 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); 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. //! 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 std::rc::Rc;
use Context;
use winapi::um::winnt::HANDLE; use winapi::shared::minwindef::{FALSE, TRUE};
use winapi::um::winbase::{STD_OUTPUT_HANDLE, STD_INPUT_HANDLE }; use winapi::shared::ntdef::NULL;
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::um::consoleapi::WriteConsoleW; use winapi::um::consoleapi::WriteConsoleW;
use winapi::um::wincon:: use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode};
{ use winapi::um::handleapi::INVALID_HANDLE_VALUE;
ENABLE_PROCESSED_INPUT, use winapi::um::processenv::GetStdHandle;
WriteConsoleOutputW, use winapi::um::winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
WriteConsoleOutputCharacterA, use winapi::um::wincon;
WriteConsoleOutputCharacterW, use winapi::um::wincon::{
SetConsoleWindowInfo, SetConsoleCursorPosition, SetConsoleTextAttribute, SetConsoleScreenBufferSize, CreateConsoleScreenBuffer,SetConsoleActiveScreenBuffer, SetConsoleCursorInfo, CreateConsoleScreenBuffer, FillConsoleOutputAttribute, FillConsoleOutputCharacterA,
GetLargestConsoleWindowSize, GetConsoleScreenBufferInfo, GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize, SetConsoleActiveScreenBuffer,
FillConsoleOutputCharacterA, FillConsoleOutputAttribute,WriteConsoleOutputAttribute, SetConsoleCursorInfo, SetConsoleCursorPosition, SetConsoleScreenBufferSize,
CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD, CHAR_INFO, PSMALL_RECT, CONSOLE_CURSOR_INFO 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_OUTPUT_HANDLE: Option<HANDLE> = None;
static mut CONSOLE_INPUT_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; use std::sync::Mutex;
/// Get the global stored handle. /// 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(); return screen_manager.get_handle();
} }
@ -44,8 +41,7 @@ pub fn get_output_handle() -> HANDLE {
} else { } else {
let handle = GetStdHandle(STD_OUTPUT_HANDLE); let handle = GetStdHandle(STD_OUTPUT_HANDLE);
if !is_valid_handle(&handle) if !is_valid_handle(&handle) {
{
panic!("Cannot get output handle") panic!("Cannot get output handle")
} }
@ -63,8 +59,7 @@ pub fn get_input_handle() -> HANDLE {
} else { } else {
let handle = GetStdHandle(STD_INPUT_HANDLE); let handle = GetStdHandle(STD_INPUT_HANDLE);
if !is_valid_handle(&handle) if !is_valid_handle(&handle) {
{
panic!("Cannot get input 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. /// 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 mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() { let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
Some(win_api) => { win_api }, .as_any()
None => panic!("") .downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
}; };
let output_handle = get_current_handle(winapi_screen_manager); 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. /// Create a new console screen buffer info struct.
pub fn get_console_screen_buffer_info_from_handle(handle: &HANDLE) -> CONSOLE_SCREEN_BUFFER_INFO { pub fn get_console_screen_buffer_info_from_handle(handle: &HANDLE) -> CONSOLE_SCREEN_BUFFER_INFO {
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty(); let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
let success; 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. /// 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(); let output_handle = get_output_handle();
unsafe { unsafe { GetLargestConsoleWindowSize(output_handle) }
GetLargestConsoleWindowSize(output_handle)
}
} }
/// Get the original color of the terminal. /// 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. /// 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 { unsafe {
let success = SetConsoleMode(*handle, console_mode); let success = SetConsoleMode(*handle, console_mode);
return is_true(success); return is_true(success);
@ -145,8 +139,7 @@ pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool
} }
/// Get the console mode. /// 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 { unsafe {
let success = GetConsoleMode(*handle, &mut *current_mode); let success = GetConsoleMode(*handle, &mut *current_mode);
return is_true(success); 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. /// 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() { if x < 0 || x >= <i16>::max_value() {
panic!("X: {}, Argument Out of Range Exception", x); 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 mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() { let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
Some(win_api) => { win_api }, .as_any()
None => panic!("") .downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
}; };
let handle = get_current_handle(winapi_screen_manager); 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. /// 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 mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() { let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
Some(win_api) => { win_api }, .as_any()
None => panic!("") .downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
}; };
let handle = get_current_handle(winapi_screen_manager); let handle = get_current_handle(winapi_screen_manager);
let cursor_info = CONSOLE_CURSOR_INFO let cursor_info = CONSOLE_CURSOR_INFO {
{
dwSize: 100, dwSize: 100,
bVisible: if visable { TRUE } else {FALSE} bVisible: if visable { TRUE } else { FALSE },
}; };
unsafe unsafe {
{
SetConsoleCursorInfo(*handle, &cursor_info); SetConsoleCursorInfo(*handle, &cursor_info);
} }
} }
/// Change the console text attribute. /// 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(); let output_handle = get_output_handle();
unsafe { unsafe {
@ -217,56 +211,75 @@ pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenMa
} }
/// Change console info. /// 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 mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() { let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
Some(win_api) => { win_api }, .as_any()
None => panic!("") .downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
}; };
let handle = get_current_handle(winapi_screen_manager); let handle = get_current_handle(winapi_screen_manager);
let absolute = match absolute { true => 1, false => 0, }; let absolute = match absolute {
unsafe true => 1,
{ false => 0,
let success = SetConsoleWindowInfo(*handle,absolute ,rect); };
unsafe {
let success = SetConsoleWindowInfo(*handle, absolute, rect);
is_true(success) is_true(success)
} }
} }
/// Set the console screen buffer size /// 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 mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() { let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
Some(win_api) => { win_api }, .as_any()
None => panic!("") .downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
}; };
let handle = get_current_handle(winapi_screen_manager); let handle = get_current_handle(winapi_screen_manager);
unsafe unsafe {
{
let success = SetConsoleScreenBufferSize(*handle, size); let success = SetConsoleScreenBufferSize(*handle, size);
is_true(success) is_true(success)
} }
} }
/// Fill a certain block with characters. /// 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 mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() { let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
Some(win_api) => { win_api }, .as_any()
None => panic!("") .downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
}; };
let handle = get_current_handle(winapi_screen_manager); let handle = get_current_handle(winapi_screen_manager);
unsafe { unsafe {
// fill the cells in console with blanks // fill the cells in console with blanks
let success = FillConsoleOutputCharacterA ( let success = FillConsoleOutputCharacterA(
*handle, *handle,
' ' as i8, ' ' as i8,
cells_to_write, 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. /// 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 // Get the position of the current console window
let csbi = get_console_screen_buffer_info(screen_manager); let csbi = get_console_screen_buffer_info(screen_manager);
let mut screen_manager = screen_manager.lock().unwrap(); let mut screen_manager = screen_manager.lock().unwrap();
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() { let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
Some(win_api) => { win_api }, .as_any()
None => panic!("") .downcast_mut::<WinApiScreenManager>()
{
Some(win_api) => win_api,
None => panic!(""),
}; };
let handle = get_current_handle(winapi_screen_manager); 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; let success;
unsafe { unsafe {
success = FillConsoleOutputAttribute ( success = FillConsoleOutputAttribute(
*handle, *handle,
csbi.wAttributes, csbi.wAttributes,
cells_to_write, 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. /// Create new console screen buffer. This can be used for alternate screen.
pub fn create_console_screen_buffer() -> HANDLE 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;
use std::mem::size_of; 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 unsafe {
{ let mut security_attr: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES {
let mut security_attr: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES
{
nLength: size_of::<SECURITY_ATTRIBUTES>() as u32, nLength: size_of::<SECURITY_ATTRIBUTES>() as u32,
lpSecurityDescriptor: NULL, lpSecurityDescriptor: NULL,
bInheritHandle: TRUE bInheritHandle: TRUE,
}; };
let new_screen_buffer = CreateConsoleScreenBuffer( let new_screen_buffer = CreateConsoleScreenBuffer(
GENERIC_READ | // read/write access GENERIC_READ | // read/write access
GENERIC_WRITE, GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_READ | FILE_SHARE_WRITE, // shared
FILE_SHARE_WRITE, // shared &mut security_attr, // default security attributes
&mut security_attr, // default security attributes CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE NULL,
NULL
); );
new_screen_buffer new_screen_buffer
} }
} }
/// Set the active screen buffer to the given handle. This can be used for alternate screen. /// 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) pub fn set_active_screen_buffer(new_buffer: HANDLE) {
{ unsafe {
unsafe if !is_true(SetConsoleActiveScreenBuffer(new_buffer)) {
{
if !is_true(SetConsoleActiveScreenBuffer(new_buffer))
{
panic!("Cannot set active screen buffer"); panic!("Cannot set active screen buffer");
} }
} }
} }
/// Read the console outptut. /// 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; use self::wincon::ReadConsoleOutputA;
unsafe unsafe {
{ if !is_true(
if !is_true(ReadConsoleOutputA( ReadConsoleOutputA(
*read_buffer, // screen buffer to read from *read_buffer, // screen buffer to read from
copy_buffer.as_mut_ptr(), // buffer to copy into copy_buffer.as_mut_ptr(), // buffer to copy into
buffer_size, // col-row size of chiBuffer buffer_size, // col-row size of chiBuffer
buffer_coord, // top left dest. cell in chiBuffer buffer_coord, // top left dest. cell in chiBuffer
source_buffer) // screen buffer source rectangle source_buffer,
){ ), // screen buffer source rectangle
) {
panic!("Cannot read console output"); panic!("Cannot read console output");
} }
} }
} }
/// Write 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; use self::wincon::WriteConsoleOutputA;
unsafe unsafe {
{ if !is_true(
if !is_true(WriteConsoleOutputA( WriteConsoleOutputA(
*write_buffer, // screen buffer to write to *write_buffer, // screen buffer to write to
copy_buffer.as_mut_ptr(), // buffer to copy into copy_buffer.as_mut_ptr(), // buffer to copy into
buffer_size, // col-row size of chiBuffer buffer_size, // col-row size of chiBuffer
buffer_coord, // top left dest. cell in chiBuffer buffer_coord, // top left dest. cell in chiBuffer
source_buffer)// screen buffer source rectangle source_buffer,
){ ), // screen buffer source rectangle
) {
panic!("Cannot write to console output"); panic!("Cannot write to console output");
}
} }
}
} }
use std::ffi::OsStr; use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::iter::once; use std::iter::once;
use std::os::windows::ffi::OsStrExt;
fn win32_string( value : &str ) -> Vec<u16> { fn win32_string(value: &str) -> Vec<u16> {
OsStr::new( value ).encode_wide().chain( once( 0 ) ).collect() OsStr::new(value).encode_wide().chain(once(0)).collect()
} }
//use std::os::raw::c_void; //use std::os::raw::c_void;
use winapi::ctypes::c_void;
use std::mem::transmute; use std::mem::transmute;
use std::str; use std::str;
use winapi::ctypes::c_void;
/// Write utf8 buffer to console. /// 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 // get string from u8[] and parse it to an c_str
let mut utf8 = match str::from_utf8(buf) let mut utf8 = match str::from_utf8(buf) {
{ Ok(string) => string,
Ok(string) => string, Err(_) => "123",
Err(_) => "123", };
};
let utf16: Vec<u16> = utf8.encode_utf16().collect(); let utf16: Vec<u16> = utf8.encode_utf16().collect();
let utf16_ptr: *const c_void = utf16.as_ptr() as *const _ as *const c_void; 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); let csbi = get_console_screen_buffer_info_from_handle(&handle);
// get current position // 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; let mut cells_written: u32 = 0;
// write to console // write to console
unsafe unsafe {
{ WriteConsoleW(
WriteConsoleW(handle, utf16_ptr, utf16.len() as u32, &mut cells_written, NULL); handle,
utf16_ptr,
utf16.len() as u32,
&mut cells_written,
NULL,
);
} }
} }
/// Parse integer to an bool /// Parse integer to an bool
fn is_true(value: i32) -> bool fn is_true(value: i32) -> bool {
{ if value == 0 {
if value == 0{
return false; return false;
} } else {
else{
return true; return true;
} }
} }

View File

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

View File

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

View File

@ -9,22 +9,22 @@ mod kernel;
mod state; mod state;
pub mod cursor; pub mod cursor;
pub mod manager;
pub mod style; pub mod style;
pub mod terminal; pub mod terminal;
pub mod manager;
pub use shared::{screen};
pub use shared::environment::Environment; pub use shared::environment::Environment;
pub use shared::screen;
pub use state::context::Context; pub use state::context::Context;
use state::commands::IStateCommand;
use state::command_manager::CommandManager;
use state::state_manager::StateManager;
use manager::ScreenManager; use manager::ScreenManager;
use state::command_manager::CommandManager;
use state::commands::IStateCommand;
use state::state_manager::StateManager;
#[cfg(windows)]
extern crate winapi;
#[cfg(unix)] #[cfg(unix)]
extern crate libc; extern crate libc;
#[cfg(unix)] #[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 is used for windows 10 terminals and unix terminals by default.
//! This module uses the stdout to write to the console. //! This module uses the stdout to write to the console.
use std::io::{self, Write};
use std::any::Any; use std::any::Any;
use std::io::{self, Write};
use super::IScreenManager; use super::IScreenManager;
pub struct AnsiScreenManager pub struct AnsiScreenManager {
{
pub is_alternate_screen: bool, pub is_alternate_screen: bool,
output: Box<Write>, output: Box<Write>,
} }
impl IScreenManager for AnsiScreenManager impl IScreenManager for AnsiScreenManager {
{ fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
{
self.is_alternate_screen = is_alternate_screen; 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); write!(self.output, "{}", string);
self.flush(); self.flush();
} }
fn write_ansi_str(&mut self, string: &str) fn write_ansi_str(&mut self, string: &str) {
{
write!(self.output, "{}", string); write!(self.output, "{}", string);
self.flush(); self.flush();
} }
@ -40,8 +35,7 @@ impl IScreenManager for AnsiScreenManager
self.output.flush() self.output.flush()
} }
fn as_any(&mut self) -> &mut Any fn as_any(&mut self) -> &mut Any {
{
self self
} }
} }
@ -50,7 +44,7 @@ impl AnsiScreenManager {
pub fn new() -> Self { pub fn new() -> Self {
AnsiScreenManager { AnsiScreenManager {
output: (Box::from(io::stdout()) as Box<Write>), 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. //! 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. //! 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::super::shared::functions;
use super::*;
use std::any::Any; use std::any::Any;
use std::fmt::Display; use std::fmt::Display;
use std::io::{ self, Write }; use std::io::{self, Write};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use winapi::um::winnt::HANDLE; use winapi::um::winnt::HANDLE;
/// Struct that stores an specific platform implementation for screen related actions. /// Struct that stores an specific platform implementation for screen related actions.
pub struct ScreenManager pub struct ScreenManager {
{ screen_manager: Box<IScreenManager>,
screen_manager: Box<IScreenManager>
} }
impl ScreenManager impl ScreenManager {
{
/// Create new screen manager instance whereon screen related actions can be performed. /// Create new screen manager instance whereon screen related actions can be performed.
pub fn new() -> ScreenManager { pub fn new() -> ScreenManager {
#[cfg(target_os = "windows")] #[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"))] #[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 ScreenManager {
{ screen_manager: screen_manager,
screen_manager: screen_manager
} }
} }
pub fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) pub fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
{ self.screen_manager
self.screen_manager.toggle_is_alternate_screen(is_alternate_screen); .toggle_is_alternate_screen(is_alternate_screen);
} }
/// Write an ANSI code as String. /// 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); self.screen_manager.write_ansi(string);
} }
/// Write an ANSI code as &str /// 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); self.screen_manager.write_ansi_str(string);
} }
/// Can be used to get an specific implementation used for the current platform. /// 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()); self.screen_manager.write(value.as_bytes());
} }
} }
impl Write for ScreenManager impl Write for ScreenManager {
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.write(buf) self.write(buf)
} }

View File

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

View File

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

View File

@ -1,66 +1,60 @@
use Context;
use super::super::cursor; use super::super::cursor;
use super::super::terminal::terminal;
use super::super::style; use super::super::style;
use super::super::terminal::terminal;
use Context;
use std::fmt::Display;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
use std::fmt::Display; use std::sync::{Once, ONCE_INIT};
use std::sync::{ONCE_INIT, Once};
static START: Once = ONCE_INIT; static START: Once = ONCE_INIT;
pub struct Environment pub struct Environment {
{
context: Rc<Context>, context: Rc<Context>,
terminal: Box<terminal::Terminal>, terminal: Box<terminal::Terminal>,
cursor: Box<cursor::TerminalCursor>, cursor: Box<cursor::TerminalCursor>,
color: Box<style::TerminalColor> color: Box<style::TerminalColor>,
} }
impl Environment impl Environment {
{ pub fn new() -> Environment {
pub fn new() -> Environment return Environment {
{ context: Context::new(),
return Environment { context: Context::new(), terminal: unsafe{ mem::zeroed()}, cursor: unsafe{ mem::zeroed()}, color: unsafe{ mem::zeroed() }} 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(|| { 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(|| { START.call_once(|| {
self.cursor = cursor::cursor(self.context.clone()); self.cursor = cursor::cursor(self.context.clone());
}); });
&self.cursor &self.cursor
} }
pub fn color(&mut self) -> &Box<style::TerminalColor> pub fn color(&mut self) -> &Box<style::TerminalColor> {
{
START.call_once(|| { START.call_once(|| {
self.color = style::color(self.context.clone()); self.color = style::color(self.context.clone());
}); });
&self.color &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) self.terminal().paint(value)
} }
pub fn context(&self) -> Rc<Context> pub fn context(&self) -> Rc<Context> {
{ return self.context.clone();
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`. //! 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::rc::Rc;
use std::sync::Mutex; use std::sync::Mutex;
use Context;
use ScreenManager;
#[cfg(windows)] #[cfg(windows)]
use kernel::windows_kernel::terminal::{exit, terminal_size}; 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; use kernel::windows_kernel::cursor::pos;
#[cfg(unix)] #[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. /// 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)] #[cfg(unix)]
return terminal_size(screen_manager); 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. /// 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)] #[cfg(unix)]
return pos(context.clone()); return pos(context.clone());
@ -35,38 +33,34 @@ pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16)
} }
/// exit the current terminal. /// exit the current terminal.
pub fn exit_terminal() pub fn exit_terminal() {
{
#[cfg(unix)] #[cfg(unix)]
exit(); exit();
#[cfg(windows)] #[cfg(windows)]
exit(); exit();
} }
#[cfg(windows)] #[cfg(windows)]
/// Get an module specific implementation based on the current platform. /// 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 term: Option<T> = None;
let mut does_support = true; let mut does_support = true;
if cfg!(target_os = "windows") { if cfg!(target_os = "windows") {
// #[cfg(windows)] // #[cfg(windows)]
// use kernel::windows_kernel::ansi_support::try_enable_ansi_support; // use kernel::windows_kernel::ansi_support::try_enable_ansi_support;
// Try to enable ansi on windows if not than use WINAPI. // 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; does_support = false;
if !does_support if !does_support {
{
term = Some(winapi_impl); term = Some(winapi_impl);
} }
} }
if does_support if does_support {
{
println!("Does support"); println!("Does support");
term = Some(unix_impl); term = Some(unix_impl);
} }

View File

@ -2,10 +2,10 @@
#[macro_use] #[macro_use]
pub mod macros; pub mod macros;
pub mod traits; pub mod environment;
pub mod functions; pub mod functions;
pub mod screen; pub mod screen;
pub mod environment; pub mod traits;
#[cfg(target_os = "unix")] #[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)] #[cfg(windows)]
use state::commands::win_commands::EnableRawModeCommand; use state::commands::win_commands::EnableRawModeCommand;
use {Context, CommandManager };
use state::commands::IStateCommand; use state::commands::IStateCommand;
use {CommandManager, Context};
use std::io::{ self, Write}; use std::io::{self, Write};
use std::rc::Rc; use std::rc::Rc;
/// A wrapper for the raw terminal state. Which can be used to write to. /// A wrapper for the raw terminal state. Which can be used to write to.
pub struct RawTerminal pub struct RawTerminal {
{ context: Rc<Context>,
context : Rc<Context>,
command_id: u16, command_id: u16,
} }
/// Trait withs contains a method for switching into raw mode. /// Trait withs contains a method for switching into raw mode.
pub trait IntoRawMode: Write + Sized pub trait IntoRawMode: Write + Sized {
{ fn into_raw_mode(&self, context: Rc<Context>) -> io::Result<RawTerminal>;
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 /// 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 /// the program. The input isn't canonicalised or line buffered (that is, you can
/// read from input(stdin) one byte of a time). /// 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); let success = CommandManager::execute(context.clone(), command_id);
if success if success {
{ Ok(RawTerminal {
Ok(RawTerminal { context: context.clone(), command_id: command_id}) context: context.clone(),
}else { panic!("cannot move into raw mode") } 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. /// If an instance of `RawTerminal` will be dropped all terminal changes that are made will be undone.
impl Drop for RawTerminal impl Drop for RawTerminal {
{ fn drop(&mut self) {
fn drop(&mut self)
{
let success = CommandManager::undo(self.context.clone(), self.command_id); 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... //! !! 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 shared::functions;
use state::commands::*;
use Context;
use std::io::{self, Write}; use std::io::{self, Write};
use std::rc::Rc; use std::rc::Rc;
pub struct AlternateScreen { pub struct AlternateScreen {
context: Rc<Context>, context: Rc<Context>,
command_id: u16 command_id: u16,
} }
impl AlternateScreen { impl AlternateScreen {
@ -27,14 +27,16 @@ impl AlternateScreen {
pub fn from(context: Rc<Context>) -> Self { pub fn from(context: Rc<Context>) -> Self {
let command_id = get_to_alternate_screen_command(context.clone()); 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(); screen.to_alternate();
return screen; return screen;
} }
/// Change the current screen to the mainscreen. /// 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 mutex = &self.context.state_manager;
{ {
let mut state_manager = mutex.lock().unwrap(); let mut state_manager = mutex.lock().unwrap();
@ -48,8 +50,7 @@ impl AlternateScreen {
} }
/// Change the current screen to alternate screen. /// 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 mutex = &self.context.state_manager;
{ {
let mut state_manager = mutex.lock().unwrap(); let mut state_manager = mutex.lock().unwrap();
@ -79,10 +80,8 @@ impl Write for AlternateScreen {
} }
} }
impl Drop for AlternateScreen impl Drop for AlternateScreen {
{ fn drop(&mut self) {
fn drop(&mut self)
{
use CommandManager; use CommandManager;
CommandManager::undo(self.context.clone(), self.command_id); CommandManager::undo(self.context.clone(), self.command_id);
@ -90,10 +89,12 @@ impl Drop for AlternateScreen
} }
// Get the alternate screen command to enable and disable alternate screen based on the current platform // 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")] #[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"))] #[cfg(not(target_os = "windows"))]
let command_id = shared_commands::ToAlternateScreenBufferCommand::new(context.clone()); let command_id = shared_commands::ToAlternateScreenBufferCommand::new(context.clone());

View File

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

View File

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

View File

@ -9,8 +9,8 @@
//! //!
//! See the `StateManager` struct where we store the commands for more info. //! See the `StateManager` struct where we store the commands for more info.
use std::sync::Mutex;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex;
#[cfg(unix)] #[cfg(unix)]
pub mod unix_command; pub mod unix_command;
@ -25,11 +25,9 @@ pub use self::unix_command::*;
#[cfg(windows)] #[cfg(windows)]
pub use self::win_commands::*; pub use self::win_commands::*;
/// This command is used for complex commands whits change the terminal state. /// 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. /// 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 execute(&mut self) -> bool;
fn undo(&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. //! 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 Context;
use super::{IStateCommand};
use std::rc::Rc; use std::rc::Rc;
pub struct EmptyCommand; pub struct EmptyCommand;
impl IStateCommand for EmptyCommand impl IStateCommand for EmptyCommand {
{ fn execute(&mut self) -> bool {
fn execute(&mut self) -> bool return false;
{
return false
} }
fn undo(&mut self) -> bool fn undo(&mut self) -> bool {
{ return false;
return false;
} }
} }
/// This command is used for switching to alternate screen and back to main screen. /// This command is used for switching to alternate screen and back to main screen.
pub struct ToAlternateScreenBufferCommand pub struct ToAlternateScreenBufferCommand {
{ context: Rc<Context>,
context: Rc<Context>
} }
impl ToAlternateScreenBufferCommand impl ToAlternateScreenBufferCommand {
{
pub fn new(context: Rc<Context>) -> u16 { pub fn new(context: Rc<Context>) -> u16 {
let mut state = context.state_manager.lock().unwrap(); let mut state = context.state_manager.lock().unwrap();
{ {
let key = state.get_changes_count(); 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); state.register_change(Box::from(command), key);
key key
@ -40,11 +36,8 @@ impl ToAlternateScreenBufferCommand
} }
} }
impl IStateCommand for ToAlternateScreenBufferCommand impl IStateCommand for ToAlternateScreenBufferCommand {
{ fn execute(&mut self) -> bool {
fn execute(&mut self) -> bool
{
println!("asdfasdf"); println!("asdfasdf");
let mut screen = self.context.screen_manager.lock().unwrap(); 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(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {
screen.write_ansi_str(csi!("?1049l")); screen.write_ansi_str(csi!("?1049l"));

View File

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

View File

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

View File

@ -1,19 +1,17 @@
//! This module contains the code for the context of the terminal. //! 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::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. /// 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 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 /// 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. /// 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); /// let color = terminal::color(&context);
/// ///
/// ``` /// ```
pub fn new() -> Rc<Context> pub fn new() -> Rc<Context> {
{
Rc::new(Context { Rc::new(Context {
screen_manager: Rc::new(Mutex::new(ScreenManager::new())), screen_manager: Rc::new(Mutex::new(ScreenManager::new())),
state_manager: Mutex::new(StateManager::new()) state_manager: Mutex::new(StateManager::new()),
}) })
} }
} }
use std::io::Write; use std::io::Write;
impl Drop for Context impl Drop for Context {
{ fn drop(&mut self) {
fn drop(&mut self)
{
panic!(); panic!();
let mut changes = self.state_manager.lock().unwrap(); let mut changes = self.state_manager.lock().unwrap();
changes.restore_changes(); 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. //! 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. //! 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 command_manager;
pub mod commands;
pub mod context; 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. //! 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::shared_commands::EmptyCommand;
use super::commands::IStateCommand;
use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex; use std::sync::Mutex;
use std::collections::HashMap;
/// Struct that stores the changed states of the terminal. /// Struct that stores the changed states of the terminal.
pub struct StateManager pub struct StateManager {
{
changed_states: HashMap<u16, Rc<Mutex<Box<IStateCommand>>>>, changed_states: HashMap<u16, Rc<Mutex<Box<IStateCommand>>>>,
} }
impl StateManager impl StateManager {
{
/// Create new Context where the terminals states can be handled. /// Create new Context where the terminals states can be handled.
pub fn new() -> StateManager pub fn new() -> StateManager {
{
StateManager { StateManager {
changed_states: HashMap::new(), changed_states: HashMap::new(),
} }
} }
/// Restore all changes that are made to the terminal. /// Restore all changes that are made to the terminal.
pub fn restore_changes(&mut self) pub fn restore_changes(&mut self) {
{ for (id, item) in self.changed_states.iter_mut() {
for (id, item) in self.changed_states.iter_mut()
{
let mut item = item.lock().unwrap(); let mut item = item.lock().unwrap();
item.undo(); item.undo();
@ -36,27 +31,20 @@ impl StateManager
} }
/// Register new changed state with the given key. /// 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))); self.changed_states.insert(key, Rc::new(Mutex::new(change)));
} }
/// Get an state command from storage by id. /// Get an state command from storage by id.
pub fn get(&mut self, state_key: u16) -> Rc<Mutex<Box<IStateCommand>>> pub fn get(&mut self, state_key: u16) -> Rc<Mutex<Box<IStateCommand>>> {
{ if self.changed_states.contains_key(&state_key) {
if self.changed_states.contains_key(&state_key) return self.changed_states[&state_key].clone();
{
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 pub fn get_changes_count(&self) -> u16 {
{ return self.changed_states.len() as 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 is an ANSI specific implementation for styling related action.
//! This module is used for windows 10 terminals and unix terminals by default. //! 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::super::{Color, ColorType};
use super::ITerminalColor;
use ScreenManager;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex; use std::sync::Mutex;
@ -20,17 +20,22 @@ impl AnsiColor {
impl ITerminalColor for AnsiColor { impl ITerminalColor for AnsiColor {
fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) { fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let mut screen = screen_manager.lock().unwrap(); 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>>) { fn set_bg(&self, bg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let mut screen = screen_manager.lock().unwrap(); 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,17 +47,11 @@ impl ITerminalColor for AnsiColor {
} }
fn color_value(&self, color: Color, color_type: ColorType) -> String { fn color_value(&self, color: Color, color_type: ColorType) -> String {
let mut ansi_value = String::new(); let mut ansi_value = String::new();
match color_type match color_type {
{ ColorType::Foreground => ansi_value.push_str("38;"),
ColorType::Foreground => { ColorType::Background => ansi_value.push_str("48;"),
ansi_value.push_str("38;")
},
ColorType::Background => {
ansi_value.push_str("48;")
},
} }
#[cfg(unix)] #[cfg(unix)]
@ -61,9 +60,9 @@ impl ITerminalColor for AnsiColor {
let color_val = match color { let color_val = match color {
Color::Black => "5;0", Color::Black => "5;0",
Color::Red => "5;9", Color::Red => "5;9",
Color::DarkRed =>"5;1", Color::DarkRed => "5;1",
Color::Green => "5;10", Color::Green => "5;10",
Color::DarkGreen => "5;2", Color::DarkGreen => "5;2",
Color::Yellow => "5;11", Color::Yellow => "5;11",
Color::DarkYellow => "5;3", Color::DarkYellow => "5;3",
Color::Blue => "5;12", Color::Blue => "5;12",
@ -72,12 +71,18 @@ impl ITerminalColor for AnsiColor {
Color::DarkMagenta => "5;5", Color::DarkMagenta => "5;5",
Color::Cyan => "5;14", Color::Cyan => "5;14",
Color::DarkCyan => "5;6", Color::DarkCyan => "5;6",
Color::Grey => "5;15", Color::Grey => "5;15",
Color::White => "5;7", Color::White => "5;7",
#[cfg(unix)] #[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)] #[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.push_str(color_val);

View File

@ -1,30 +1,36 @@
//! With this module you can perform actions that are color related. //! With this module you can perform actions that are color related.
//! Like styling the font, foreground color and background. //! Like styling the font, foreground color and background.
use {ScreenManager, Context}; use super::super::super::shared::functions;
use super::*; use super::*;
use style::Color;
use std::io; use std::io;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex; 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. /// Struct that stores an specific platform implementation for color related actions.
pub struct TerminalColor { pub struct TerminalColor {
color: Option<Box<ITerminalColor>>, color: Option<Box<ITerminalColor>>,
screen_manager: Rc<Mutex<ScreenManager>> screen_manager: Rc<Mutex<ScreenManager>>,
} }
impl TerminalColor { impl TerminalColor {
/// Create new instance whereon color related actions can be performed. /// Create new instance whereon color related actions can be performed.
pub fn new(context: Rc<Context>) -> TerminalColor { pub fn new(context: Rc<Context>) -> TerminalColor {
#[cfg(target_os = "windows")] #[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"))] #[cfg(not(target_os = "windows"))]
let color = Some(AnsiColor::new() as Box<ITerminalColor>); 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. /// Set the foreground color to the given color.
@ -106,8 +112,7 @@ impl TerminalColor {
} }
/// Get available color count. /// 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; use std::env;
Ok(match env::var_os("TERM") { Ok(match env::var_os("TERM") {

View File

@ -1,15 +1,15 @@
pub mod color; pub mod color;
mod ansi_color;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
mod winapi_color; mod winapi_color;
mod ansi_color;
use self::ansi_color::AnsiColor;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use self::winapi_color::WinApiColor; use self::winapi_color::WinApiColor;
use self::ansi_color::AnsiColor;
use { ScreenManager };
use super::{Color, ColorType}; use super::{Color, ColorType};
use ScreenManager;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex; use std::sync::Mutex;
@ -28,7 +28,7 @@ pub trait ITerminalColor {
/// Set the background color to the given color. /// Set the background color to the given color.
fn set_bg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>); fn set_bg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>);
/// Reset the terminal color to default. /// 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`. /// Gets an value that represents an color from the given `Color` and `ColorType`.
fn color_value(&self, color: Color, color_type: ColorType) -> String; 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::ITerminalColor;
use super::super::{ColorType, Color};
use winapi::um::wincon;
use kernel::windows_kernel::kernel; use kernel::windows_kernel::kernel;
use winapi::um::wincon;
use ScreenManager; use ScreenManager;
use std::sync::Mutex;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Mutex;
/// This struct is an windows implementation for color related actions. /// This struct is an windows implementation for color related actions.
pub struct WinApiColor { pub struct WinApiColor {
original_console_color: u16, original_console_color: u16,
screen_manager: Rc<Mutex<ScreenManager>> screen_manager: Rc<Mutex<ScreenManager>>,
} }
impl WinApiColor { impl WinApiColor {
pub fn new(screen_manager: Rc<Mutex<ScreenManager>>) -> Box<WinApiColor> { pub fn new(screen_manager: Rc<Mutex<ScreenManager>>) -> Box<WinApiColor> {
Box::from(WinApiColor { Box::from(WinApiColor {
original_console_color: kernel::get_original_console_color(&screen_manager), original_console_color: kernel::get_original_console_color(&screen_manager),
screen_manager: screen_manager screen_manager: screen_manager,
}) })
} }
} }
impl ITerminalColor for WinApiColor { impl ITerminalColor for WinApiColor {
fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) { fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
let color_value = &self.color_value(fg_color, ColorType::Foreground); 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; 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>>) { 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; 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>>) { 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 /// This will get the winapi color value from the Color and ColorType struct
fn color_value(&self, color: Color, color_type: ColorType) -> String { fn color_value(&self, color: Color, color_type: ColorType) -> String {
use style::{Color, ColorType}; use style::{Color, ColorType};
let winapi_color: u16; let winapi_color: u16;

View File

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

View File

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

View File

@ -15,7 +15,7 @@ use style::{Color, ObjectStyle};
pub struct StyledObject<D> { pub struct StyledObject<D> {
pub object_style: ObjectStyle, pub object_style: ObjectStyle,
pub content: D, pub content: D,
pub context: Rc<Context> pub context: Rc<Context>,
} }
impl<D> StyledObject<D> { impl<D> StyledObject<D> {
@ -82,64 +82,95 @@ impl<D> StyledObject<D> {
/// ///
/// ``` /// ```
#[cfg(unix)] #[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.object_style.add_attr(attr);
self self
} }
/// Increase the font intensity. /// 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). /// 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). /// 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. /// 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). /// 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). /// 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) } #[cfg(unix)]
#[inline(always)]
pub fn rapid_blink(self) -> StyledObject<D> {
self.attr(Attribute::RapidBlink)
}
/// Swap foreground and background colors. /// 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 reverse(self) -> StyledObject<D> {
self.attr(Attribute::Reverse)
}
/// Hide text (Not widely supported). /// 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. /// 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 is used to make StyledObject able to be displayed.
/// This macro will set the styles stored in Styled Object /// This macro will set the styles stored in Styled Object
macro_rules! impl_fmt macro_rules! impl_fmt {
{
($name:ident) => { ($name:ident) => {
impl<D: fmt::$name> fmt::$name for StyledObject<D> { 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 colored_terminal = super::super::color(self.context.clone());
let mut reset = true; 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); colored_terminal.set_bg(bg);
reset = true; reset = true;
} }
if let Some(fg) = self.object_style.fg_color if let Some(fg) = self.object_style.fg_color {
{ colored_terminal.set_fg(fg);
colored_terminal.set_fg(fg); reset = true;
reset = true;
} }
#[cfg(unix)] #[cfg(unix)]
for attr in self.object_style.attrs.iter() { for attr in self.object_style.attrs.iter() {
let mutex = &self.context.screen_manager; let mutex = &self.context.screen_manager;
{ {
let mut screen = mutex.lock().unwrap(); 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; reset = true;
} }
fmt::$name::fmt(&self.content, f)?; fmt::$name::fmt(&self.content, f)?;
@ -149,15 +180,14 @@ macro_rules! impl_fmt
screen.flush(); screen.flush();
} }
if reset if reset {
{
colored_terminal.reset(); colored_terminal.reset();
} }
Ok(()) Ok(())
} }
} }
} };
} }
impl_fmt!(Debug); impl_fmt!(Debug);

View File

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

View File

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

View File

@ -1,32 +1,37 @@
//! With this module you can perform actions that are terminal related. //! 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. //! 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 super::*;
use Context; use Context;
use super::super::style;
use super::super::shared::functions;
use std::fmt::Write;
use std::fmt; use std::fmt;
use std::fmt::Write;
use std::rc::Rc; use std::rc::Rc;
/// Struct that stores an specific platform implementation for terminal related actions. /// Struct that stores an specific platform implementation for terminal related actions.
pub struct Terminal { pub struct Terminal {
terminal: Option<Box<ITerminal>>, terminal: Option<Box<ITerminal>>,
context: Rc<Context> context: Rc<Context>,
} }
impl Terminal { impl Terminal {
/// Create new terminal instance whereon terminal related actions can be performed. /// Create new terminal instance whereon terminal related actions can be performed.
pub fn new(context: Rc<Context>) -> Terminal { pub fn new(context: Rc<Context>) -> Terminal {
#[cfg(target_os = "windows")] #[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"))] #[cfg(not(target_os = "windows"))]
let terminal = Some(AnsiTerminal::new(context.clone()) as Box<ITerminal>); 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 /// Clear the current cursor by specifying the clear type
@ -79,9 +84,9 @@ impl Terminal {
/// ``` /// ```
pub fn terminal_size(&mut self) -> (u16, u16) { pub fn terminal_size(&mut self) -> (u16, u16) {
if let Some(ref terminal) = self.terminal { 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. /// Scroll `n` lines up in the current terminal.
@ -147,10 +152,9 @@ impl Terminal {
/// let size = term.set_size(10,10); /// let size = term.set_size(10,10);
/// ///
/// ``` /// ```
pub fn set_size(&mut self, width: i16, height: i16) pub fn set_size(&mut self, width: i16, height: i16) {
{ if let Some(ref terminal) = self.terminal {
if let Some (ref terminal) = self.terminal { terminal.set_size(width, height);
terminal.set_size(width,height);
} }
} }
@ -182,21 +186,19 @@ impl Terminal {
/// } /// }
/// ``` /// ```
pub fn paint<D>(&self, val: D) -> style::StyledObject<D> pub fn paint<D>(&self, val: D) -> style::StyledObject<D>
where where
D: fmt::Display, D: fmt::Display,
{ {
style::ObjectStyle::new().apply_to(val, self.context.clone()) style::ObjectStyle::new().apply_to(val, self.context.clone())
} }
pub fn exit(&self) pub fn exit(&self) {
{ if let Some(ref terminal) = self.terminal {
if let Some (ref terminal) = self.terminal {
terminal.exit(); 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 mutex = &self.context.screen_manager;
{ {
let mut screen_manager = mutex.lock().unwrap(); let mut screen_manager = mutex.lock().unwrap();

View File

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