progress

thread safe progress bar and spinner library
git clone git://brookjeynes.dev/bjeynes/progress.git
Log | Files | Refs | README | LICENSE

termsize.zig (3220B)


      1 // Copyright (c) 2024 Doug Tangren
      2 //
      3 // Permission is hereby granted, free of charge, to any person obtaining
      4 // a copy of this software and associated documentation files (the
      5 // "Software"), to deal in the Software without restriction, including
      6 // without limitation the rights to use, copy, modify, merge, publish,
      7 // distribute, sublicense, and/or sell copies of the Software, and to
      8 // permit persons to whom the Software is furnished to do so, subject to
      9 // the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be
     12 // included in all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 //
     22 // Repo: https://github.com/softprops/zig-termsize
     23 // Modifications made by Brook Jeynes (https://github.com/brookjeynes)
     24 
     25 const std = @import("std");
     26 const builtin = @import("builtin");
     27 const os = std.os;
     28 
     29 /// Terminal size dimensions
     30 pub const TermSize = struct {
     31     /// Terminal width as measured number of characters that fit into a terminal horizontally
     32     width: u16,
     33     /// terminal height as measured number of characters that fit into terminal vertically
     34     height: u16,
     35 };
     36 
     37 /// ## example
     38 ///
     39 /// ```zig
     40 /// const std = @import("std");
     41 /// const termSize = @import("termsize");
     42 ///
     43 /// fn main(init: std.process.Init) !void {
     44 ///   std.debug.print(
     45 ///     "{any}",
     46 ///     termSize.termSize(std.Io.File.stdout(), init.io),
     47 ///   );
     48 /// }
     49 /// ```
     50 pub fn termSize(file: std.Io.File, io: std.Io) !?TermSize {
     51     const supports_ansi = file.supportsAnsiEscapeCodes(io) catch return null;
     52     if (!supports_ansi) {
     53         return null;
     54     }
     55     return switch (builtin.os.tag) {
     56         .windows => blk: {
     57             var buf: os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
     58             break :blk switch (os.windows.kernel32.GetConsoleScreenBufferInfo(
     59                 file.handle,
     60                 &buf,
     61             )) {
     62                 os.windows.TRUE => TermSize{
     63                     .width = @intCast(buf.srWindow.Right - buf.srWindow.Left + 1),
     64                     .height = @intCast(buf.srWindow.Bottom - buf.srWindow.Top + 1),
     65                 },
     66                 else => error.Unexpected,
     67             };
     68         },
     69         .linux, .macos => blk: {
     70             var buf: std.posix.winsize = undefined;
     71             break :blk switch (std.posix.errno(
     72                 std.posix.system.ioctl(
     73                     file.handle,
     74                     std.posix.T.IOCGWINSZ,
     75                     @intFromPtr(&buf),
     76                 ),
     77             )) {
     78                 .SUCCESS => TermSize{
     79                     .width = buf.col,
     80                     .height = buf.row,
     81                 },
     82                 else => error.IoctlError,
     83             };
     84         },
     85         else => error.Unsupported,
     86     };
     87 }