# -*- coding: utf-8 -*-
# This file is part of ranger, the console file manager.
# License: GNU GPL version 3, see the file "AUTHORS" for details.
"""The BrowserColumn widget displays the contents of a directory or file."""
import curses
import stat
from time import time
from os.path import splitext
from . import Widget
from .pager import Pager
from ranger.ext.widestring import WideString
from ranger.core import linemode
from ranger.gui.color import *
class BrowserColumn(Pager):
main_column = False
display_infostring = False
display_vcsstate = True
scroll_begin = 0
target = None
last_redraw_time = -1
ellipsis = { False: '~', True: '…' }
old_dir = None
old_thisfile = None
def __init__(self, win, level):
"""Initializes a Browser Column Widget
win = the curses window object of the BrowserView
level = what to display?
level >0 => previews
level 0 => current file/directory
level <0 => parent directories
"""
Pager.__init__(self, win)
Widget.__init__(self, win)
self.level = level
self.original_level = level
self.settings.signal_bind('setopt.display_size_in_main_column',
self.request_redraw, weak=True)
def request_redraw(self):
self.need_redraw = True
def resize(self, y, x, hei, wid):
Widget.resize(self, y, x, hei, wid)
def click(self, event):
"""Handle a MouseEvent"""
direction = event.mouse_wheel_direction()
if not (event.pressed(1) or event.pressed(3) or direction):
return False
if self.target is None:
pass
elif self.target.is_directory:
if self.target.accessible and self.target.content_loaded:
index = self.scroll_begin + event.y - self.y
if direction:
if self.level == -1:
self.fm.move_parent(direction)
else:
return False
elif event.pressed(1):
if not self.main_column:
self.fm.enter_dir(self.target.path)
if index < len(self.target):
self.fm.move(to=index)
elif event.pressed(3):
try:
clicked_file = self.target.files[index]
if clicked_file.is_directory:
self.fm.enter_dir(clicked_file.path)
elif self.level == 0:
self.fm.thisdir.move_to_obj(clicked_file)
self.fm.execute_file(clicked_file)
except:
pass
else:
if self.level > 0 and not direction:
self.fm.move(right=0)
return True
def execute_curses_batch(self, line, commands):
"""Executes a list of "commands" which can be easily cached.
"commands" is a list of lists. Each element contains
a text and an attribute. First, the attribute will be
set with attrset, then the text is printed.
Example:
execute_curses_batch(0, [["hello ", 0], ["world", curses.A_BOLD]])
"""
try:
self.win.move(line, 0)
except:
return
for entry in commands:
text, attr = entry
self.addstr(text, attr)
def has_preview(self):
if self.target is None:
return False
if self.target.is_file:
if not self.target.has_preview():
return False
if self.target.is_directory:
if self.level > 0 and not self.settings.preview_directories:
return False
return True
def level_shift(self, amount):
self.level = self.original_level + amount
def level_restore(self):
self.level = self.original_level
def poke(self):
Widget.poke(self)
self.target = self.fm.thistab.at_level(self.level)
def draw(self):
"""Call either _draw_file() or _draw_directory()"""
if self.target != self.old_dir:
self.need_redraw = True
self.old_dir = self.target
if self.target: # don't garbage collect this directory please
self.target.use()
if self.target and self.target.is_directory \
and (self.level <= 0 or self.settings.preview_directories):
if self.target.pointed_obj != self.old_thisfile:
self.need_redraw = True
self.old_thisfile = self.target.pointed_obj
if self.target.load_content_if_outdated() \
or self.target.sort_if_outdated() \
or self.last_redraw_time < self.target.last_update_time:
self.need_redraw = True
if self.need_redraw:
self.win.erase()
if self.target is None:
pass
elif self.target.is_file:
Pager.open(self)
self._draw_file()
elif self.target.is_directory:
self._draw_directory()
Widget.draw(self)
self.need_redraw = False
self.last_redraw_time = time()
def _draw_file(self):
"""Draw a preview of the file, if the settings allow it"""
self.win.move(0, 0)
if not self.target.accessible:
self.addnstr("not accessible", self.wid)
Pager.close(self)
return
if self.target is None or not self.target.has_preview():
Pager.close(self)
return
f = self.target.get_preview_source(self.wid, self.hei)
if f is None:
Pager.close(self)
else:
if self.target.is_image_preview():
self.set_image(f)
else:
self.set_source(f)
Pager.draw(self)
def _draw_directory(self):
"""Draw the contents of a directory"""
if self.image:
self.image = None
self.need_clear_image = True
Pager.clear_image(self)
if self.level > 0 and not self.settings.preview_directories:
return
base_color = ['in_browser']
self.win.move(0, 0)
if not self.target.content_loaded:
self.color(tuple(base_color))
self.addnstr("...", self.wid)
self.color_reset()
return
if self.main_column:
base_color.append('main_column')
if not self.target.accessible:
self.color(tuple(base_color + ['error']))
self.addnstr("not accessible", self.wid)
self.color_reset()
return
if self.target.empty():
self.color(tuple(base_color + ['empty']))
self.addnstr("empty", self.wid)
self.color_reset()
return
self._set_scroll_begin()
copied = [f.path for f in self.fm.copy_buffer]
selected_i = self.target.pointer
for line in range(self.hei):
i = line + self.scroll_begin
if line > self.hei:
break
try:
drawn = self.target.files[i]
except IndexError:
break
tagged = self.fm.tags and drawn.realpath in self.fm.tags
if tagged:
tagged_marker = self.fm.tags.marker(drawn.realpath)
else:
tagged_marker = " "
# Extract linemode-related information from the drawn object
metadata = None
current_linemode = drawn.linemode_dict[drawn._linemode]
if current_linemode.uses_metadata:
metadata = self.fm.metadata.get_metadata(drawn.path)
if not all(getattr(metadata, tag)
for tag in current_linemode.required_metadata):
current_linemode = drawn.linemode_dict[linemode.DEFAULT_LINEMODE]
metakey = hash(repr(sorted(metadata.items()))) if metadata else 0
key = (self.wid, selected_i == i, drawn.marked, self.main_column,
drawn.path in copied, tagged_marker, drawn.infostring,
drawn.vcsfilestatus, drawn.vcsremotestatus, self.fm.do_cut,
current_linemode.name, metakey)
if key in drawn.display_data:
self.execute_curses_batch(line, drawn.display_data[key])
self.color_reset()
continue
text = current_linemode.filetitle(drawn, metadata)
if drawn.marked and (self.main_column or \
self.settings.display_tags_in_all_columns):
text = " " + text
# Computing predisplay data. predisplay contains a list of lists
# [string, colorlst] where string is a piece of string to display,
# and colorlst a list of contexts that we later pass to the
# colorscheme, to compute the curses attribute.
predisplay_left = []
predisplay_right = []
space = self.wid
# selection mark
tagmark = self._draw_tagged_display(tagged, tagged_marker)
tagmarklen = self._total_len(tagmark)
if space - tagmarklen > 2:
predisplay_left += tagmark
space -= tagmarklen
# vcs data
vcsstring = self._draw_vcsstring_display(drawn)
vcsstringlen = self._total_len(vcsstring)
if space - vcsstringlen > 2:
predisplay_right += vcsstring
space -= vcsstringlen
# info string
infostring = []
infostringlen = 0
try:
infostringdata = current_linemode.infostring(drawn, metadata)
if infostringdata:
infostring.append([" " + infostringdata + " ",
["infostring"]])
except NotImplementedError:
infostring = self._draw_infostring_display(drawn, space)
if infostring:
infostringlen = self._total_len(infostring)
if space - infostringlen > 2:
predisplay_right = infostring + predisplay_right
space -= infostringlen
textstring = self._draw_text_display(text, space)
textstringlen = self._total_len(textstring)
predisplay_left += textstring
space -= textstringlen
if space > 0:
predisplay_left.append([' ' * space, []])
elif space < 0:
raise Exception("Error: there is not enough space to write "
"the text. I have computed spaces wrong.")
# Computing display data. Now we compute the display_data list
# ready to display in curses. It is a list of lists [string, attr]
this_color = base_color + list(drawn.mimetype_tuple) + \
self._draw_directory_color(i, drawn, copied)
display_data = []
drawn.display_d#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include "ui/keyhandlers.h"
#include "ui/inputwin.h"
#include "tests/helpers.h"
static char line[INP_WIN_MAX];
// append
void append_to_empty(void **state)
{
setlocale(LC_ALL, "");
line[0] = '\0';
int line_utf8_pos = 0;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, 'a', 80);
assert_string_equal("a", line);
assert_int_equal(line_utf8_pos, 1);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void append_wide_to_empty(void **state)
{
setlocale(LC_ALL, "");
line[0] = '\0';
int line_utf8_pos = 0;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, 0x56DB, 80);
assert_string_equal("四", line);
assert_int_equal(line_utf8_pos, 1);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void append_to_single(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "a", 1);
line[1] = '\0';
int line_utf8_pos = 1;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, 'b', 80);
assert_string_equal("ab", line);
assert_int_equal(line_utf8_pos, 2);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void append_wide_to_single_non_wide(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "a", 1);
line[1] = '\0';
int line_utf8_pos = 1;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, 0x56DB, 80);
assert_string_equal("a四", line);
assert_int_equal(line_utf8_pos, 2);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void append_non_wide_to_single_wide(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "四", 1);
line[strlen(line)] = '\0';
int line_utf8_pos = 1;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, 'b', 80);
assert_string_equal("四b", line);
assert_int_equal(line_utf8_pos, 2);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void append_wide_to_single_wide(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "四", 1);
line[strlen(line)] = '\0';
int line_utf8_pos = 1;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, 0x4E09, 80);
assert_string_equal("四三", line);
assert_int_equal(line_utf8_pos, 2);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void append_non_wide_when_overrun(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "0123456789四1234567", 18);
line[strlen(line)] = '\0';
int line_utf8_pos = 18;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, 'z', 20);
key_printable(line, &line_utf8_pos, &col, &pad_start, 'z', 20);
key_printable(line, &line_utf8_pos, &col, &pad_start, 'z', 20);
assert_string_equal("0123456789四1234567zzz", line);
assert_int_equal(line_utf8_pos, 21);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 3);
}
void insert_non_wide_to_non_wide(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd", 4);
line[strlen(line)] = '\0';
int line_utf8_pos = 2;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_printable(line, &line_utf8_pos, &col, &pad_start, '0', 80);
assert_string_equal("ab0cd", line);
assert_int_equal(line_utf8_pos, 3);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void insert_single_non_wide_when_pad_scrolled(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "AAAAAAAAAAAAAAA", 15);
line[strlen(line)] = '\0';
int line_utf8_pos = 2;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 2;
key_printable(line, &line_utf8_pos, &col, &pad_start, 'B', 12);
assert_string_equal("AABAAAAAAAAAAAAA", line);
assert_int_equal(line_utf8_pos, 3);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 2);
}
void insert_many_non_wide_when_pad_scrolled(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "AAAAAAAAAAAAAAA", 15);
line[strlen(line)] = '\0';
int line_utf8_pos = 2;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 2;
key_printable(line, &line_utf8_pos, &col, &pad_start, 'B', 12);
key_printable(line, &line_utf8_pos, &col, &pad_start, 'C', 12);
key_printable(line, &line_utf8_pos, &col, &pad_start, 'D', 12);
assert_string_equal("AABCDAAAAAAAAAAAAA", line);
assert_int_equal(line_utf8_pos, 5);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 2);
}
void insert_single_non_wide_last_column(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcdefghijklmno", 15);
line[strlen(line)] = '\0';
int line_utf8_pos = 7;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 2;
key_printable(line, &line_utf8_pos, &col, &pad_start, '1', 5);
assert_string_equal("abcdefg1hijklmno", line);
assert_int_equal(line_utf8_pos, 8);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 3);
}
void insert_many_non_wide_last_column(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcdefghijklmno", 15);
line[strlen(line)] = '\0';
int line_utf8_pos = 7;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 2;
key_printable(line, &line_utf8_pos, &col, &pad_start, '1', 5);
key_printable(line, &line_utf8_pos, &col, &pad_start, '2', 5);
assert_string_equal("abcdefg12hijklmno", line);
assert_int_equal(line_utf8_pos, 9);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 4);
}
void ctrl_left_when_no_input(void **state)
{
setlocale(LC_ALL, "");
line[0] = '\0';
int line_utf8_pos = 0;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_at_start(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 0;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_in_first_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 2;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_in_first_space(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 4;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_at_start_of_second_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 5;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_in_second_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 8;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 5);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_at_end_of_second_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 10;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 5);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_in_second_space(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 11;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 5);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_at_start_of_third_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 12;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 5);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_in_third_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 14;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 12);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_at_end_of_third_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 15;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 12);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_in_third_space(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 16;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 12);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_at_end(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "abcd efghij klmn opqr", 21);
line[strlen(line)] = '\0';
int line_utf8_pos = 20;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 17);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_in_only_whitespace(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, " ", 7);
line[strlen(line)] = '\0';
int line_utf8_pos = 5;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_start_whitespace_start_of_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, " hello", 9);
line[strlen(line)] = '\0';
int line_utf8_pos = 4;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_start_whitespace_middle_of_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, " hello", 9);
line[strlen(line)] = '\0';
int line_utf8_pos = 7;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 4);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_in_whitespace_between_words(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "hey hello", 12);
line[strlen(line)] = '\0';
int line_utf8_pos = 5;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_in_whitespace_between_words_start_of_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "hey hello", 12);
line[strlen(line)] = '\0';
int line_utf8_pos = 7;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_in_whitespace_between_words_middle_of_word(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "hey hello", 12);
line[strlen(line)] = '\0';
int line_utf8_pos = 9;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 7);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_left_when_word_overrun_to_left(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword anotherword", 20);
line[strlen(line)] = '\0';
int line_utf8_pos = 18;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 14;
key_ctrl_left(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 9);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 9);
}
void ctrl_right_when_no_input(void **state)
{
setlocale(LC_ALL, "");
line[0] = '\0';
int line_utf8_pos = 0;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 0);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_when_at_end(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword anotherword", 20);
line[strlen(line)] = '\0';
int line_utf8_pos = 20;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 20);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_one_word_at_start(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword", 8);
line[strlen(line)] = '\0';
int line_utf8_pos = 0;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 8);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_one_word_in_middle(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword", 8);
line[strlen(line)] = '\0';
int line_utf8_pos = 3;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 8);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_one_word_at_end(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword", 8);
line[strlen(line)] = '\0';
int line_utf8_pos = 7;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 8);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_two_words_from_middle_first(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword anotherword", 20);
line[strlen(line)] = '\0';
int line_utf8_pos = 4;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 8);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_two_words_from_end_first(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword anotherword", 20);
line[strlen(line)] = '\0';
int line_utf8_pos = 7;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 8);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_two_words_from_space(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword anotherword", 20);
line[strlen(line)] = '\0';
int line_utf8_pos = 8;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 20);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_two_words_from_start_second(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword anotherword", 20);
line[strlen(line)] = '\0';
int line_utf8_pos = 9;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 20);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_one_word_leading_whitespace(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, " someword", 15);
line[strlen(line)] = '\0';
int line_utf8_pos = 3;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 15);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_two_words_in_whitespace(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, " someword adfasdf", 30);
line[strlen(line)] = '\0';
int line_utf8_pos = 19;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 30);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}
void ctrl_right_trailing_whitespace_from_middle(void **state)
{
setlocale(LC_ALL, "");
g_utf8_strncpy(line, "someword ", 16);
line[strlen(line)] = '\0';
int line_utf8_pos = 3;
int col = utf8_pos_to_col(line, line_utf8_pos);
int pad_start = 0;
key_ctrl_right(line, &line_utf8_pos, &col, &pad_start, 80);
assert_int_equal(line_utf8_pos, 8);
assert_int_equal(col, utf8_pos_to_col(line, line_utf8_pos));
assert_int_equal(pad_start, 0);
}