howl.interactions.file_selection

local tmpdir, command_line

before_each ->
  for buf in *app.buffers
    app\close_buffer buf

  app.window = Window!
  app.window\realize!
  app.editor = app\new_editor!
  command_line = app.window.command_line
  tmpdir = File.tmpdir!

after_each ->
  tmpdir\rm_r!
  for buf in *app.buffers
    app\close_buffer buf
  app.editor = nil
  app.window\destroy!
  app.window = nil

registers interactions

assert.not_nil interact.select_file
assert.not_nil interact.select_file_in_project
assert.not_nil interact.select_directory

interact.select_file

opens the home directory by default

local prompt
within_activity interact.select_file, ->
  prompt = command_line.prompt
assert.same '~/', prompt

typing a path opens the closest parent

prompts = {}
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir)
  table.insert prompts, command_line.prompt
assert.same {tostring(tmpdir.parent) .. '/'}, prompts

typing "/" after a directory name opens the directory

local prompt
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir) .. '/'
  prompt = command_line.prompt
assert.same tostring(tmpdir) .. '/', prompt

typing a trailing "/~/" jumps to the home directory

prompts = {}
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir) .. '/'
  table.insert prompts, command_line.prompt
  command_line\write '~/'
  table.insert prompts, command_line.prompt
assert.same {tostring(tmpdir) .. '/', '~/'}, prompts

typing "../" switches to the parent of the current directory

prompts = {}
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir) .. '/'
  table.insert prompts, command_line.prompt
  command_line\write tostring(tmpdir) .. '../'
  table.insert prompts, command_line.prompt
assert.same {tostring(tmpdir) .. '/', tostring(tmpdir.parent) .. '/'}, prompts

typing "/" without any preceeding text changes to home directory

local prompt
within_activity interact.select_file, ->
  command_line\write '/'
  prompt = command_line.prompt
assert.same '/', prompt

shows files matching entered text in the current directory

files = { 'ab1', 'ab2', 'bc1' }
for f in *files
  f = tmpdir / f
  f.contents = 'a'

local items, items2
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir) .. '/'
  items = get_ui_list_widget_column(2)

  command_line\write 'ab'
  items2 = get_ui_list_widget_column(2)

assert.same files, items
assert.same {'ab1', 'ab2'}, items2

(when a buffer associated with a file is open)

opens the directory of the current buffer, if any

_, app.editor = app\open_file tmpdir / 'f'
local prompt
within_activity interact.select_file, ->
  prompt = command_line.prompt
assert.same tostring(tmpdir)..'/', prompt

(for directory names ending with ~)

before_each -> File.mkdir tmpdir / 'subdir~'

typing subdir~/ switches to the directory

prompts = {}
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir) .. '/subdir~/'
  table.insert prompts, command_line.prompt
assert.same {tostring(tmpdir) .. '/subdir~/'}, prompts

(spillover)

(.. when spillover is not an absolute path)

opens the home directory and matches the spillover text

local prompt, text
command_line\write_spillover 'matchthis'
within_activity interact.select_file, ->
  prompt = command_line.prompt
  text = command_line.text
assert.same '~/', prompt
assert.same 'matchthis', text

(.. when spillover is an absolute path)

opens the closest valid directory

local prompt, text
command_line\write_spillover tostring(tmpdir / 'matchthis')
within_activity interact.select_file, ->
  prompt = command_line.prompt
  text = command_line.text
assert.same tostring(tmpdir)..'/', prompt
assert.same 'matchthis', text

(.. when spillover is a directory path that exists)

before_each ->
  File.mkdir tmpdir / 'subdir'

opens the directory when specified with a trailing "/"

local prompt, text
command_line\write_spillover tostring(tmpdir / 'subdir') .. '/'
within_activity interact.select_file, ->
  prompt = command_line.prompt
  text = command_line.text
assert.same tostring(tmpdir / 'subdir')..'/', prompt
assert.same '', text

opens the parent when specified without any trailing "/"

local prompt, text
command_line\write_spillover tostring(tmpdir / 'subdir')
within_activity interact.select_file, ->
  prompt = command_line.prompt
  text = command_line.text
assert.same tostring(tmpdir)..'/', prompt
assert.same 'subdir', text

(when config.hidden_file_extensions is set)

local files

before_each ->
  config.reset!
  config.hidden_file_extensions = {'a'}
  files = { 'x.a', 'x.b', 'x.c' }
  for f in *files
    f = tmpdir / f
    f.contents = 'x'

does not show hidden files in list

local items
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir) .. '/'
  items = get_ui_list_widget_column(2)
assert.same { 'x.b', 'x.c' }, items

shows a hidden file after its exact name is entered

local items
within_activity interact.select_file, ->
  command_line\write tostring(tmpdir) .. '/'
  command_line\write 'x.a'
  command_line\clear!
  command_line\write ''
  items = get_ui_list_widget_column(2)
assert.same { 'x.b', 'x.c', 'x.a' }, items

(in subtree mode)

shows files and directories in the subtree

files = { 'ab1', 'ab2/', 'ab2/xy', 'ef/', 'ef/gh/', 'ef/gh/ab4'}
for name in *files
  f = tmpdir / name
  if name\ends_with '/'
    f\mkdir!
  else
    f.contents = 'a'

command_line\write_spillover tostring(tmpdir) .. '/'

local items, items2
within_activity (-> interact.select_file(show_subtree: true)), ->
  items = get_ui_list_widget_column(2)
  command_line\write 'ab'
  items2 = get_ui_list_widget_column(2)
  table.sort items
  table.sort items2

assert.same files, items
assert.same {'ab1', 'ab2/', 'ab2/xy','ef/gh/ab4'}, items2

interact.select_directory

shows only sub directories including "./", but no files

files = { 'ab1', 'ab2', 'bc1' }
directories = { 'dir1', 'dir2' }
for f in *files
  f = tmpdir / f
  f.contents = 'a'

for d in *directories
  f = tmpdir / d
  f\mkdir!

local items
within_activity interact.select_directory, ->
  command_line\write tostring(tmpdir) .. '/'
  items = get_ui_list_widget_column(2)

assert.same { './', 'dir1/', 'dir2/' }, items