Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9b31f54208ef
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 428acab7ea8a
Choose a head ref
  • 3 commits
  • 1 file changed
  • 2 contributors

Commits on Jul 23, 2016

  1. Add IO#noecho and IO#noecho!

    jhass committed Jul 23, 2016
    Copy the full SHA
    165d230 View commit details
  2. Copy the full SHA
    602e24e View commit details
  3. Merge pull request #3035 from jhass/noecho

    Add IO#noecho and IO#noecho!
    Ary Borenszweig authored Jul 23, 2016
    Copy the full SHA
    428acab View commit details
Showing with 49 additions and 0 deletions.
  1. +49 −0 src/io/console.cr
49 changes: 49 additions & 0 deletions src/io/console.cr
Original file line number Diff line number Diff line change
@@ -1,13 +1,54 @@
require "termios"

module IO
# Turn off character echoing for the duration of the given block.
# This will prevent displaying back to the user what they enter on the terminal.
# Only call this when this IO is a TTY, such as a not redirected stdin.
#
# ```
# print "Enter password: "
# password = STDIN.noecho &.gets.try &.chomp
# puts
# ```
def noecho
preserving_tc_mode("can't set IO#noecho") do |mode|
noecho_from_tc_mode!
yield self
end
end

# Turn off character echoing for this IO.
# This will prevent displaying back to the user what they enter on the terminal.
# Only call this when this IO is a TTY, such as a not redirected stdin.
def noecho!
if LibC.tcgetattr(fd, out mode) != 0
raise Errno.new "can't set IO#noecho!"
end
noecho_from_tc_mode!
end

macro noecho_from_tc_mode!
mode.c_lflag &= ~(Termios::LocalMode.flags(ECHO, ECHOE, ECHOK, ECHONL).value)
LibC.tcsetattr(fd, Termios::LineControl::TCSANOW, pointerof(mode))
end

# Enable character processing for the duration of the given block.
# The so called cooked mode is the standard behavior of a terminal,
# doing line wise editing by the terminal and only sending the input to
# the program on a newline.
# Only call this when this IO is a TTY, such as a not redirected stdin.
def cooked
preserving_tc_mode("can't set IO#cooked") do |mode|
cooked_from_tc_mode!
yield self
end
end

# Enable character processing for this IO.
# The so called cooked mode is the standard behavior of a terminal,
# doing line wise editing by the terminal and only sending the input to
# the program on a newline.
# Only call this when this IO is a TTY, such as a not redirected stdin.
def cooked!
if LibC.tcgetattr(fd, out mode) != 0
raise Errno.new "can't set IO#cooked!"
@@ -31,13 +72,21 @@ module IO
LibC.tcsetattr(fd, Termios::LineControl::TCSANOW, pointerof(mode))
end

# Enable raw mode for the duration of the given block.
# In raw mode every keypress is directly sent to the program, no interpretation
# is done by the terminal.
# Only call this when this IO is a TTY, such as a not redirected stdin.
def raw
preserving_tc_mode("can't set IO#raw") do |mode|
raw_from_tc_mode!
yield self
end
end

# Enable raw mode for this IO.
# In raw mode every keypress is directly sent to the program, no interpretation
# is done by the terminal.
# Only call this when this IO is a TTY, such as a not redirected stdin.
def raw!
if LibC.tcgetattr(fd, out mode) != 0
raise Errno.new "can't set IO#raw!"