Commit 66d95d71 authored by Dylan Aïssi's avatar Dylan Aïssi

New upstream version 3.7+dfsg

parents
*.ninja*
cmake_*
CMakeFiles*
CMakeCache*
nbproject
build
*.user
aft-*
doc
language: cpp
sudo: required
dist: trusty
matrix:
include:
- os: linux
compiler: gcc
- os: osx
osx_image: xcode10.1
compiler: clang
before_install:
- |
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
sudo add-apt-repository ppa:beineri/opt-qt592-trusty -y &&
sudo apt-get update -qq
fi
install:
- |
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
sudo apt-get -y install qt59base libfuse-dev libmagic-dev &&
source /opt/qt*/bin/qt*-env.sh
elif [ "${TRAVIS_OS_NAME}" = "osx" ]; then
brew tap homebrew/cask && brew install qt5 homebrew/cask/osxfuse
fi
script:
- |
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr &&
make -j$(nproc) &&
make DESTDIR=appdir -j$(nproc) install ; find appdir/ &&
sed -i -e 's|^Name=.*|Name=Android File Transfer|g' appdir/usr/share/applications/android-file-transfer.desktop &&
wget -c -q "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" &&
chmod a+x linuxdeployqt-continuous-x86_64.AppImage &&
unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH &&
export VERSION=$(git rev-parse --short HEAD) &&
./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -bundle-non-qt-libs &&
./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage
elif [ "${TRAVIS_OS_NAME}" = "osx" ]; then
mkdir build &&
cd build &&
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 -DCMAKE_INSTALL_PREFIX=$(pwd)/installdir &&
make -j$(sysctl -n hw.ncpu) &&
make install &&
mv installdir/android-file-transfer.app installdir/Android\ File\ Transfer\ for\ Linux.app &&
mkdir -p installdir/Android\ File\ Transfer\ for\ Linux.app/Contents/SharedSupport/ &&
mv installdir/bin installdir/Android\ File\ Transfer\ for\ Linux.app/Contents/SharedSupport/ &&
git clone https://github.com/andreyvit/create-dmg.git &&
cd create-dmg &&
./create-dmg --volicon "../../osx/android-file-transfer.icns" --icon-size 96 --icon "Android File Transfer for Linux" 110 100 --app-drop-link 380 100 AndroidFileTransferForLinux.dmg ../installdir/Android\ File\ Transfer\ for\ Linux.app
fi
after_success:
- |
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq &&
wget https://github.com/d1vanov/ciuploadtool/releases/download/continuous-master/ciuploadtool_linux.zip &&
unzip ciuploadtool_linux.zip &&
chmod 755 ciuploadtool &&
./ciuploadtool ./Android*.AppImage*
elif [ "${TRAVIS_OS_NAME}" = "osx" ]; then
wget https://github.com/d1vanov/ciuploadtool/releases/download/continuous-master/ciuploadtool_mac.zip &&
unzip ciuploadtool_mac.zip &&
chmod 755 ciuploadtool &&
./ciuploadtool AndroidFileTransferForLinux.dmg
fi
branches:
only:
- master
- /^v\d+\.\d+$/
project(android-file-transfer)
set (CMAKE_CXX_STANDARD 11)
set(VERSION_MAJOR "3")
set(VERSION_MINOR "6")
set(VERSION_PATCH "0")
set(VERSION_COUNT 3)
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
message(STATUS "building for ${CMAKE_SYSTEM_NAME}")
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(USB_BACKEND_DARWIN TRUE)
endif()
cmake_minimum_required(VERSION 2.8)
set(CMAKE_USE_RELATIVE_PATHS TRUE)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
include(FindPkgConfig)
include(CheckFunctionExists)
include(CheckIncludeFiles)
find_package ( Threads )
option(BUILD_FUSE "Build fuse mount helper" ON)
if (BUILD_FUSE)
pkg_check_modules ( FUSE fuse )
endif()
if (FUSE_FOUND)
message(STATUS "fuse found, building mount helper")
add_definitions(${FUSE_CFLAGS} -DFUSE_USE_VERSION=26)
endif()
check_include_files (magic.h HAVE_MAGIC_H)
check_library_exists(magic magic_open "" HAVE_LIBMAGIC)
if (HAVE_MAGIC_H AND HAVE_LIBMAGIC)
message(STATUS "libmagic found")
add_definitions(-DHAVE_LIBMAGIC)
list(APPEND MTP_LIBRARIES magic)
list(APPEND MTP_SHARED_LIBRARIES magic)
endif()
option(BUILD_QT_UI "Build reference Qt application" ON)
option(BUILD_SHARED_LIB "Build shared library" OFF)
option(USB_BACKEND_LIBUSB "Use libusb-1.0" OFF)
if (USB_BACKEND_LIBUSB)
message(WARNING "WARNING! You're using libusb, this is known to be broken -- large memory consumption, violating kernel memory limits and bugs. Continue at your own risk")
endif()
add_definitions(-Wall -pthread)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
if (CMAKE_BUILD_TYPE STREQUAL Debug)
add_definitions(-ggdb)
endif()
include_directories(. ${CMAKE_SOURCE_DIR})
include_directories(mtp/backend/posix)
set(SOURCES
mtp/log.cpp
mtp/ByteArray.cpp
mtp/ptp/Device.cpp
mtp/ptp/ObjectFormat.cpp
mtp/ptp/PipePacketer.cpp
mtp/ptp/Response.cpp
mtp/ptp/Session.cpp
mtp/usb/DeviceBusyException.cpp
mtp/usb/BulkPipe.cpp
mtp/usb/Request.cpp
mtp/backend/posix/FileHandler.cpp
mtp/backend/posix/Exception.cpp
)
exec_program(git ARGS describe --tags OUTPUT_VARIABLE AFT_VERSION RETURN_VALUE GIT_STATUS)
if (GIT_STATUS GREATER 0)
file(READ ${CMAKE_SOURCE_DIR}/README.md README_MD)
string(REGEX MATCH "version-([0-9a-fA-F.]+)-" _VERSION ${README_MD})
set(AFT_VERSION "v${CMAKE_MATCH_1}-snapshot")
endif()
message(STATUS "version: ${AFT_VERSION}")
set(VERSION_SRC ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/version.cpp)
configure_file(mtp/version.cpp.in ${VERSION_SRC})
list(APPEND SOURCES ${VERSION_SRC})
if (USB_BACKEND_LIBUSB)
pkg_check_modules(LIBUSB libusb-1.0 REQUIRED)
include_directories(${LIBUSB_INCLUDE_DIRS})
include_directories(mtp/backend/libusb)
add_definitions(-DUSB_BACKEND_LIBUSB)
list(APPEND SOURCES
mtp/backend/libusb/usb/Context.cpp
mtp/backend/libusb/usb/Device.cpp
mtp/backend/libusb/usb/DeviceDescriptor.cpp
mtp/backend/libusb/usb/Exception.cpp
)
list(APPEND MTP_LIBRARIES ${LIBUSB_LIBRARIES})
elseif (USB_BACKEND_DARWIN)
find_library(CORE_LIBRARY CoreFoundation)
find_library(IOKIT_LIBRARY IOKit)
list(APPEND MTP_LIBRARIES ${IOKIT_LIBRARY} ${CORE_LIBRARY})
include_directories(mtp/backend/darwin)
list(APPEND SOURCES
mtp/backend/darwin/usb/Context.cpp
mtp/backend/darwin/usb/Device.cpp
mtp/backend/darwin/usb/DeviceDescriptor.cpp
mtp/backend/darwin/usb/Exception.cpp
mtp/backend/darwin/usb/Interface.cpp
)
else()
include_directories(mtp/backend/linux)
list(APPEND SOURCES
mtp/backend/linux/usb/Endpoint.cpp
mtp/backend/linux/usb/Context.cpp
mtp/backend/linux/usb/Device.cpp
mtp/backend/linux/usb/Interface.cpp
mtp/backend/linux/usb/DeviceDescriptor.cpp
)
endif()
if (BUILD_SHARED_LIB)
add_library(mtp-ng SHARED ${SOURCES})
set_target_properties(mtp-ng PROPERTIES SOVERSION ${VERSION})
target_link_libraries(mtp-ng ${CMAKE_THREAD_LIBS_INIT} ${MTP_SHARED_LIBRARIES})
if (USB_BACKEND_LIBUSB)
target_link_libraries(mtp-ng ${LIBUSB_LIBRARIES})
endif()
list(INSERT MTP_LIBRARIES 0 mtp-ng)
install(TARGETS mtp-ng LIBRARY DESTINATION "lib${LIB_SUFFIX}" ARCHIVE DESTINATION "lib${LIB_SUFFIX}")
else (BUILD_SHARED_LIB)
add_library(mtp-ng-static STATIC ${SOURCES})
target_link_libraries(mtp-ng-static ${MTP_LIBRARIES})
list(INSERT MTP_LIBRARIES 0 mtp-ng-static)
install(TARGETS mtp-ng-static LIBRARY DESTINATION "lib${LIB_SUFFIX}" ARCHIVE DESTINATION "lib${LIB_SUFFIX}")
endif (BUILD_SHARED_LIB)
add_definitions(-D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64)
add_subdirectory(cli)
if (FUSE_FOUND)
add_subdirectory(fuse)
endif()
if (BUILD_QT_UI)
add_subdirectory(qt)
endif()
add_custom_target(uninstall COMMAND xargs rm < install_manifest.txt)
This diff is collapsed.
# FAQ
## Is it possible to use cli tool for automated file management?
Yes. There's two options of achieving this.
1. Pass every command as **single** command line argument, e.g. ```aft-mtp-cli "get Pictures" "cd Pictures" "ls"```. If you need quoted argument for commands, you have to escape them, e.g. ```aft-mtp-cli "get \"Pictures\"".
2. Pass -b command line option and feed your script to stdin.
## How to unmount my device?
Run
```fusermount -u <path>```
## I'm getting «ioctl(_fd, USBDEVFS_CLAIMINTERFACE, &interfaceNumber): Device or resource busy» or «Device is already used by another process» exception/message box right after you started the application. This clearly indicates that some other process is accessing MTP device right now.
You could do the following steps to find the offending process:
* Open you console emulator (gnome-terminal, konsole, whatever) and type: ```lsusb``` (sudo apt-get install usbutils if it did not start) and find your device in its output, for example
```
Bus 006 Device 070: ID 18d1:4ee2 Google Inc. Nexus 4 (debug)
```
* Start fuser ```sudo fuser /dev/bus/usb/<BUS>/<DEVICE>``` (sudo apt-get install psmisc if it did not start)
* It should output something like this: ```/dev/bus/usb/006/070: 23253 24377``` (actually, there could be more of them after semicolon, like : 24377, 24378, …) so, 23253 and 24377 are the pids of the processes which opened your device.
* So, finally run:
```
ps -x -q 23253
23253 ? Sl 0:00 /usr/local/bin/android-file-transfer
ps -x -q 24377
24377 ? Sl 21:14 adb -P 5037 fork-server server
```
Usually, adb is not offending process, because it uses another interface, so the /usr/local/bin/android-file-transfer is the one
## No MTP device found, but it's listed in lsusb
Maybe you don't have sufficient privileges to access usb device under /dev/bus/usb
First, try checking what bus and device numbers your device has by running lsusb command and finding your device in its output.
For instance, my old Nexus 5 phone:
```
Bus 010 Device 003: ID 18d1:4ee2 Google Inc. Nexus Device (debug)
```
Note the bus/device number in row with your device Then, go /dev/bus/usb/<bus> and check file <device> there. (010 and 003 respectively in my case).
```
ls -l /dev/bus/usb/010/
crw-rw-r-- 1 root usb 189, 1152 Jan 5 21:30 001
crw-rw----+ 1 root plugdev 189, 1154 Jan 5 22:46 003
```
plugdev group may have different name for different distros, consult your distro's manual for details. You can check what groups you're in by running 'id' command.
If device's group is 'root', then you have to add udev rule:
http://reactivated.net/writing_udev_rules.html
Please find some examples there.
This diff is collapsed.
# Android File Transfer For Linux (and Mac OS X!)
[![License](http://img.shields.io/:license-LGPLv2.1-blue.svg)](https://github.com/whoozle/android-file-transfer-linux/blob/master/LICENSE)
[![Version](http://img.shields.io/:version-3.6-green.svg)](https://github.com/whoozle/android-file-transfer-linux)
[![Build Status](https://travis-ci.org/whoozle/android-file-transfer-linux.svg?branch=master)](https://travis-ci.org/whoozle/android-file-transfer-linux)
Android File Transfer for Linux — reliable MTP client with minimalistic UI similar to [Android File Transfer for Mac](https://www.android.com/intl/en_us/filetransfer/).
It just works™.
## Do I need it?
If you're happy with `gmtp`/`gvfs`/`mtpfs` or any other mtp software, you might not need this software (but give it a try!).
If you're suffering from crashes, missing tags, album covers, usb freezes and corrupted files, this software is right for you.
## Features
* Simple Qt UI with progress dialogs.
* FUSE wrapper (If you'd prefer mounting your device), supporting partial read/writes, allowing instant access to your files.
* No file size limits.
* Automatically renames album cover to make it visible from media player.
* USB 'Zerocopy' support found in recent Linux kernel (no user/kernel data copying)
* No extra dependencies (e.g. `libptp`/`libmtp`).
* Available as static/shared library.
* Command line tool (aft-mtp-cli)
## FAQ
[Please take a look at FAQ if you have issues with your operating system](FAQ.md). It's not that big, but those are the questions asked very often.
## Support me
If you want to help me with development, click on the link below and follow the instructions. I'm developing AFTL in my spare time and try to fix everything as fast as possible, sometimes adding features in realtime (more than 100 tickes closed by now).
Any amount would help relieving pain of using MTP. :D
https://www.paypal.me/whoozle
## Building instructions
### Gentoo
AFT for Linux is now included in Gentoo, you don't have to build anything, just run
```
sudo emerge -av sys-fs/android-file-transfer-linux
```
If you need fuse mount helper to mount MTP filesystem, you have to enable fuse use flag, e.g. adding the following in /etc/portage/package.use (which can either be a directory or a file)
```
sys-fs/android-file-transfer-linux fuse
```
You can use ```sys-fs/android-file-transfer-linux-9999``` ebuild if you want the latest git-version by adding the following entry into /etc/portage/package.accept_keywords (which can either be a directory or a file)
```
=sys-fs/android-file-transfer-linux-9999 **
```
### Prerequisites
* You will need Qt libraries for building ui program. If you're planning to use only library (*Qt is not needed*), you could turn the option ```BUILD_QT_UI``` off.
* For ubuntu and other debian-based distros use the following command:
```shell
sudo apt-get install build-essential cmake libqt4-dev ninja-build libfuse-dev libreadline-dev
```
For Fedora:
```
dnf install make automake gcc gcc-c++ kernel-devel cmake fuse fuse-devel qt-devel readline-devel
```
* Basically, you need `libqtX-dev` for UI, `libfuse-dev` for FUSE interface, `cmake`, `ninja` or `make` for building the project. You could use libqt5-dev as well.
### Building with ninja
```shell
mkdir build
cd build
cmake -G Ninja ..
ninja
./qt/android-file-transfer
```
### Building with make
```shell
mkdir build
cd build
cmake ..
make
./qt/android-file-transfer
```
### Installing binary package on OS X / macOS
There is a binary package that can be installed via Homebrew:
* First [install brew](https://brew.sh) if you don't have it already installed.
* Then the stable package may be installed via:
```shell
brew install homebrew/cask/whoozle-android-file-transfer
```
* Nighlty build may be installed via;
```shell
brew install homebrew/cask-versions/whoozle-android-file-transfer-nightly
```
* Please note: they are in conflict, so please make sure to uninstall it when you want switch between stable and nightly.
### Building app package on OS X / macOS
You'll need Qt installed to build the GUI app. Here are the build instructions with qt5 from homebrew (`brew install qt5`):
```shell
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=~/Applications -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5
make
make install
open ~/Applications/android-file-transfer.app
```
### Installation
`sudo ninja install` or `sudo make install` will install program into cmake prefix/bin directory (usually /usr/local/bin)
## How to use
### FUSE interface
```shell
mkdir ~/my-device
./aft-mtp-mount ~/my-device
```
Remember, if you want album art to be displayed, it must be named 'albumart.xxx' and placed *first* in the destination folder. Then copy other files.
Also, note that fuse could be 7-8 times slower than ui/cli file transfer.
### Qt user interface
1. Start application, choose destination folder and click any button on toolbar.
2. The options available there are: `Upload Album`, `Upload Directory` and `Upload Files`.
The latter two are self-explanatory. `Upload album` tries searching source directory for album cover and sets best available cover.
3. You could drop any files or folders right into application window, the transfer will start automatically.
### Known problems
* Samsung removed android extensions from MTP, so fuse will be available readonly, sorry. Feel free to post your complaints to http://developer.samsung.com/forum/en
* Sometimes downloading fails with usb timeout, then phone becomes unresponsive. [Android bug #75259](https://code.google.com/p/android/issues/detail?id=75259)
* Objects created in UI will not show up in FUSE filesystem. [Android bug #169547](https://code.google.com/p/android/issues/detail?id=169547)
The actual list of all known problems and bugs available [here](https://github.com/whoozle/android-file-transfer-linux/issues)
## Contacts
Please do not hesitate to contact me if you have any further questions, my email address is <vladimir.menshakov@gmail.com>.
## Special thanks
* All who filed bugs on github and wrote emails, many features appeared only because of your feedback. Thanks!
* Alexey [gazay](https://github.com/gazay) Gaziev for useful suggestions, support and invaluable help with MacBook and MacOSX port.
* @ssnjrthegr8 for new logo!
## License
Android File Transfer for Linux is released under [GNU LGPLv2.1 License](https://github.com/whoozle/android-file-transfer-linux/blob/master/LICENSE).
Copyright © 2015-2018 Vladimir Menshakov
theme: jekyll-theme-minimal
\ No newline at end of file
{
"id": "io.github.whoozle.android-file-transfer-linux",
"runtime": "org.kde.Platform",
"runtime-version": "5.10",
"sdk": "org.kde.Sdk",
"modules" : [
{
"name": "android-file-transfer-linux",
"buildsystem": "cmake",
"config-opts": [ "-DCMAKE_BUILD_TYPE=Release" ],
"sources": [{
"type": "git",
"tag": "v3.3",
"url": "https://github.com/whoozle/android-file-transfer-linux.git"
}]
}
]
}
find_package(Readline)
include(CheckCSourceCompiles)
set(CLI_SOURCES
Command.cpp
Session.cpp
Tokenizer.cpp
arg_lexer.l.cpp
cli.cpp)
if (READLINE_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${Readline_LIBRARY})
set(READLINE_TEST_SRC "
#include <stdio.h>
#include <readline/readline.h>
int main(int argc, char **argv) {
char *line = readline(\">\");
return 0;
}
")
check_c_source_compiles("${READLINE_TEST_SRC}" READLINE_NO_CURSES_TEST)
if (NOT READLINE_NO_CURSES_TEST)
message(STATUS "readline test failed - some systems expect you to link with termcap or curses libraries")
message(STATUS "please find an example there: https://bugzilla.redhat.com/show_bug.cgi?id=499837")
message(STATUS "trying to find and link curses library...")
# set(CURSES_NEED_NCURSES TRUE)
include(FindCurses)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
check_c_source_compiles("${READLINE_TEST_SRC}" READLINE_CURSES_TEST)
if (READLINE_CURSES_TEST)
list(APPEND Readline_LIBRARY ${CURSES_LIBRARIES})
else()
set(READLINE_FOUND FALSE) #disabling readline completely
endif()
endif()
set(CMAKE_REQUIRED_LIBRARIES)
endif()
if (READLINE_FOUND)
list(APPEND CLI_SOURCES CommandLine.cpp)
list(APPEND CLI_LIBRARIES ${Readline_LIBRARY})
else()
list(APPEND CLI_SOURCES CommandLineStub.cpp)
message(WARNING "no readline library found, using stub")
endif()
add_executable(aft-mtp-cli ${CLI_SOURCES})
target_link_libraries(aft-mtp-cli ${MTP_LIBRARIES} ${CLI_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS aft-mtp-cli RUNTIME DESTINATION bin)
/*
This file is part of Android File Transfer For Linux.
Copyright (C) 2015-2018 Vladimir Menshakov
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <cli/Command.h>
#include <cli/Session.h>
namespace cli
{
void impl::Completer<Path>::Complete(CompletionContext & ctx)
{ ctx.Session.CompletePath(ctx.Prefix, ctx.Result); }
void impl::Completer<StoragePath>::Complete(CompletionContext & ctx)
{ ctx.Session.CompleteStoragePath(ctx.Prefix, ctx.Result); }
}
/*
This file is part of Android File Transfer For Linux.
Copyright (C) 2015-2018 Vladimir Menshakov
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef AFT_CLI_COMMAND_H
#define AFT_CLI_COMMAND_H
#include <cli/Tokens.h>
#include <cli/MakeTuple.h>
#include <mtp/types.h>
#include <mtp/function_invoker.h>
#include <mtp/Demangle.h>
#include <functional>
#include <string>
#include <list>
namespace cli
{
class Session;
struct Path : public std::string { Path(const std::string &path = std::string()): std::string(path) { } };
struct LocalPath : public std::string { LocalPath(const std::string &path = std::string()): std::string(path) { } };
struct StoragePath : public std::string { StoragePath(const std::string &path = std::string()): std::string(path) { } };
inline std::string EscapePath(std::string name)
{
if (name.find(' ') != name.npos)
return '"' + name +'"';
else
return name;
}
typedef std::list<std::string> CompletionResult;
struct CompletionContext
{
cli::Session & Session;
size_t Index;
std::string Prefix;
CompletionResult & Result;
CompletionContext(cli::Session &s, size_t i, const std::string &p, std::list<std::string> & r):
Session(s), Index(i), Prefix(p), Result(r) { }
};
namespace impl
{
template<>
struct ValueConverter<LocalPath>
{
static LocalPath Convert(const Path &text)
{ return text; }
};
template<>
struct ValueConverter<Path>
{
static Path Convert(const Path &text)
{ return text; }
};
template<>
struct ValueConverter<StoragePath>
{
static StoragePath Convert(const Path &text)
{ return text; }
};
template<typename Type>
struct Completer
{
static void Complete(CompletionContext & ctx) { }
};
template<>
struct Completer<Path>
{
static void Complete(CompletionContext & ctx);
};
template<>
struct Completer<StoragePath>
{
static void Complete(CompletionContext & ctx);
};
template<typename ... Tail>
struct CompletionForwarder
{
static void Complete(CompletionContext & ctx, size_t index)
{ }