and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
+### Removed
+* Expansion of `%` to the current opened URI for `:shellcmd` was removed
+ because it breaks the `x-hint-command` with URIs containing '%'. But it is
+ still possible to use `$VIMB_URI` for the `:shellcmd` which has the same
+ effect.
## [3.6.0] - 2020-01-02
### Added
static gboolean parse_command_name(Client *c, const char **input, ExArg *arg);
static gboolean parse_bang(const char **input, ExArg *arg);
static gboolean parse_lhs(const char **input, ExArg *arg);
-static gboolean parse_rhs(Client *c, const char **input, ExArg *arg);
+static gboolean parse_rhs(const char **input, ExArg *arg);
static void skip_whitespace(const char **input);
static void free_cmdarg(ExArg *arg);
static VbCmdResult execute(Client *c, const ExArg *arg);
}
/* parse the rhs if this is available */
skip_whitespace(input);
- parse_rhs(c, input, arg);
+ parse_rhs(input, arg);
if (**input) {
(*input)++;
* command can contain any char accept of the newline, else the right hand
* side end on the first none escaped | or newline.
*/
-static gboolean parse_rhs(Client *c, const char **input, ExArg *arg)
+static gboolean parse_rhs(const char **input, ExArg *arg)
{
int expflags, flags;
gboolean cmdlist;
cmdlist = (arg->flags & EX_FLAG_CMD) != 0;
expflags = (arg->flags & EX_FLAG_EXP)
- ? UTIL_EXP_TILDE|UTIL_EXP_DOLLAR|UTIL_EXP_SPECIAL
+ ? UTIL_EXP_TILDE|UTIL_EXP_DOLLAR
: 0;
flags = expflags;
* EX_FLAG_CMD is not set also on | */
while (**input && **input != '\n' && (cmdlist || **input != '|')) {
/* check for expansion placeholder */
- util_parse_expansion(c->state, input, arg->rhs, flags, "|\\");
+ util_parse_expansion(input, arg->rhs, flags, "|\\");
if (VB_IS_SEPARATOR(**input)) {
/* add tilde expansion for next loop needs to be first char or to
case EX_SAVE: /* Fallthrough */
case EX_SOURCE:
- found = util_filename_fill_completion(c->state, store, token);
+ found = util_filename_fill_completion(store, token);
break;
#ifdef FEATURE_AUTOCMD
/* Prepare the path to save the download. */
if (path && *path) {
- file = util_build_path(c->state, path, download_path);
+ file = util_build_path(path, download_path);
/* if file is an directory append a file name */
if (g_file_test(file, (G_FILE_TEST_IS_DIR))) {
g_free(dir);
}
} else {
- file = util_build_path(c->state, suggested_filename, download_path);
+ file = util_build_path(suggested_filename, download_path);
}
g_free(basename);
*
* Returned path must be freed.
*/
-char *util_build_path(State state, const char *path, const char *dir)
+char *util_build_path(const char *path, const char *dir)
{
char *fullPath = NULL, *fexp, *dexp, *p;
int expflags = UTIL_EXP_TILDE|UTIL_EXP_DOLLAR;
/* if the path could be expanded */
- if ((fexp = util_expand(state, path, expflags))) {
+ if ((fexp = util_expand(path, expflags))) {
if (*fexp == '/') {
/* path is already absolute, no need to use given dir - there is
* no need to free fexp, because this should be done by the caller
fullPath = fexp;
} else if (dir && *dir) {
/* try to expand also the dir given - this may be ~/path */
- if ((dexp = util_expand(state, dir, expflags))) {
+ if ((dexp = util_expand(dir, expflags))) {
/* use expanded dir and append expanded path */
fullPath = g_build_filename(dexp, fexp, NULL);
g_free(dexp);
*
* Returned path must be g_freed.
*/
-char *util_expand(State state, const char *src, int expflags)
+char *util_expand(const char *src, int expflags)
{
const char **input = &src;
char *result;
int flags = expflags;
while (**input) {
- util_parse_expansion(state, input, dst, flags, "\\");
+ util_parse_expansion(input, dst, flags, "\\");
if (VB_IS_SEPARATOR(**input)) {
/* after space the tilde expansion is allowed */
flags = expflags;
* Fills file path completion entries into given list store for also given
* input.
*/
-gboolean util_filename_fill_completion(State state, GtkListStore *store, const char *input)
+gboolean util_filename_fill_completion(GtkListStore *store, const char *input)
{
gboolean found = FALSE;
GError *error = NULL;
input_basename = last_slash ? last_slash + 1 : input;
input_dirname = g_strndup(input, input_basename - input);
real_dirname = util_expand(
- state,
*input_dirname ? input_dirname : ".",
- UTIL_EXP_TILDE|UTIL_EXP_DOLLAR|UTIL_EXP_SPECIAL
+ UTIL_EXP_TILDE|UTIL_EXP_DOLLAR
);
dir = g_dir_open(real_dirname, 0, &error);
* @quoteable: String of chars that are additionally escapable by \.
* Returns TRUE if input started with expandable pattern.
*/
-gboolean util_parse_expansion(State state, const char **input, GString *str,
+gboolean util_parse_expansion(const char **input, GString *str,
int flags, const char *quoteable)
{
GString *name;
/* variable are expanded even if they do not exists */
expanded = TRUE;
g_string_free(name, TRUE);
- } else if (flags & UTIL_EXP_SPECIAL && **input == '%') {
- if (state.uri) {
- /* TODO check for modifiers like :h:t:r:e */
- g_string_append(str, state.uri);
- expanded = TRUE;
- }
}
if (!expanded) {
} else if (strchr(quoteable, **input)
|| (flags & UTIL_EXP_TILDE && **input == '~')
|| (flags & UTIL_EXP_DOLLAR && **input == '$')
- || (flags & UTIL_EXP_SPECIAL && **input == '%')
) {
/* escaped char becomes only char */
g_string_append_c(str, **input);
enum {
UTIL_EXP_TILDE = 0x01, /* ~/ and ~user expansion */
UTIL_EXP_DOLLAR = 0x02, /* $ENV and ${ENV} expansion */
- UTIL_EXP_SPECIAL = 0x04, /* expand % to current URI */
};
typedef void *(*Util_Content_Func)(const char*, const char*);
-char *util_build_path(State state, const char *path, const char *dir);
+char *util_build_path(const char *path, const char *dir);
void util_cleanup(void);
gboolean util_create_dir_if_not_exists(const char *dirpath);
gboolean util_create_tmp_file(const char *content, char **file);
-char *util_expand(State state, const char *src, int expflags);
+char *util_expand(const char *src, int expflags);
gboolean util_file_append(const char *file, const char *format, ...);
gboolean util_file_prepend(const char *file, const char *format, ...);
void util_file_prepend_line(const char *file, const char *line,
GList *util_strv_to_unique_list(char **lines, Util_Content_Func func,
guint max_items);
gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src);
-gboolean util_filename_fill_completion(State state, GtkListStore *store, const char *input);
+gboolean util_filename_fill_completion(GtkListStore *store, const char *input);
char *util_js_result_as_string(WebKitJavascriptResult *result);
double util_js_result_as_number(WebKitJavascriptResult *result);
-gboolean util_parse_expansion(State state, const char **input, GString *str,
- int flags, const char *quoteable);
+gboolean util_parse_expansion(const char **input, GString *str, int flags,
+ const char *quoteable);
char *util_sanitize_filename(char *filename);
char *util_sanitize_uri(const char *uri_str);
char *util_strcasestr(const char *haystack, const char *needle);
#include <gtk/gtk.h>
#include <src/util.h>
-static void check_expand(State state, const char *str, const char *expected)
+static void check_expand(const char *str, const char *expected)
{
- char *result = util_expand(state, str, UTIL_EXP_DOLLAR|UTIL_EXP_TILDE|UTIL_EXP_SPECIAL);
+ char *result = util_expand(str, UTIL_EXP_DOLLAR|UTIL_EXP_TILDE);
g_assert_cmpstr(result, ==, expected);
g_free(result);
}
static void test_expand_evn(void)
{
- State state = {0};
/* set environment var for testing expansion */
g_setenv("VIMB_VAR", "value", true);
- check_expand(state, "$VIMB_VAR", "value");
- check_expand(state, "$VIMB_VAR", "value");
- check_expand(state, "$VIMB_VAR$VIMB_VAR", "valuevalue");
- check_expand(state, "${VIMB_VAR}", "value");
- check_expand(state, "my$VIMB_VAR", "myvalue");
- check_expand(state, "'$VIMB_VAR'", "'value'");
- check_expand(state, "${VIMB_VAR}s ", "values ");
+ check_expand("$VIMB_VAR", "value");
+ check_expand("$VIMB_VAR", "value");
+ check_expand("$VIMB_VAR$VIMB_VAR", "valuevalue");
+ check_expand("${VIMB_VAR}", "value");
+ check_expand("my$VIMB_VAR", "myvalue");
+ check_expand("'$VIMB_VAR'", "'value'");
+ check_expand("${VIMB_VAR}s ", "values ");
g_unsetenv("UNKNOWN");
- check_expand(state, "$UNKNOWN", "");
- check_expand(state, "${UNKNOWN}", "");
- check_expand(state, "'$UNKNOWN'", "''");
+ check_expand("$UNKNOWN", "");
+ check_expand("${UNKNOWN}", "");
+ check_expand("'$UNKNOWN'", "''");
}
static void test_expand_escaped(void)
{
- State state = {0};
g_setenv("VIMB_VAR", "value", true);
- check_expand(state, "\\$VIMB_VAR", "$VIMB_VAR");
- check_expand(state, "\\${VIMB_VAR}", "${VIMB_VAR}");
- check_expand(state, "\\~/", "~/");
- check_expand(state, "\\~/vimb", "~/vimb");
- check_expand(state, "\\~root", "~root");
- check_expand(state, "\\%", "%");
- check_expand(state, "\\\\$VIMB_VAR", "\\value"); /* \\$VAR becomes \ExpandedVar */
- check_expand(state, "\\\\\\$VIMB_VAR", "\\$VIMB_VAR"); /* \\\$VAR becomes \$VAR */
+ check_expand("\\$VIMB_VAR", "$VIMB_VAR");
+ check_expand("\\${VIMB_VAR}", "${VIMB_VAR}");
+ check_expand("\\~/", "~/");
+ check_expand("\\~/vimb", "~/vimb");
+ check_expand("\\~root", "~root");
+ check_expand("\\\\$VIMB_VAR", "\\value"); /* \\$VAR becomes \ExpandedVar */
+ check_expand("\\\\\\$VIMB_VAR", "\\$VIMB_VAR"); /* \\\$VAR becomes \$VAR */
}
static void test_expand_tilde_home(void)
{
- State state = {0};
char *dir;
const char *home = g_get_home_dir();
- check_expand(state, "~", "~");
- check_expand(state, "~/", home);
- check_expand(state, "foo~/bar", "foo~/bar");
- check_expand(state, "~/foo", (dir = g_strdup_printf("%s/foo", home)));
+ check_expand("~", "~");
+ check_expand("~/", home);
+ check_expand("foo~/bar", "foo~/bar");
+ check_expand("~/foo", (dir = g_strdup_printf("%s/foo", home)));
g_free(dir);
- check_expand(state, "foo ~/bar", (dir = g_strdup_printf("foo %s/bar", home)));
+ check_expand("foo ~/bar", (dir = g_strdup_printf("foo %s/bar", home)));
g_free(dir);
- check_expand(state, "~/~", (dir = g_strdup_printf("%s/~", home)));
+ check_expand("~/~", (dir = g_strdup_printf("%s/~", home)));
g_free(dir);
- check_expand(state, "~/~/", (dir = g_strdup_printf("%s/~/", home)));
+ check_expand("~/~/", (dir = g_strdup_printf("%s/~/", home)));
g_free(dir);
}
static void test_expand_tilde_user(void)
{
- State state = {0};
const char *user = g_get_user_name();
const char *home;
char *in, *out;
/* don't expand within words */
in = g_strdup_printf("foo~%s/bar", user);
- check_expand(state, in, in);
+ check_expand(in, in);
g_free(in);
- check_expand(state, (in = g_strdup_printf("foo ~%s", user)), (out = g_strdup_printf("foo %s", home)));
+ check_expand((in = g_strdup_printf("foo ~%s", user)), (out = g_strdup_printf("foo %s", home)));
g_free(in);
g_free(out);
- check_expand(state, (in = g_strdup_printf("~%s", user)), home);
+ check_expand((in = g_strdup_printf("~%s", user)), home);
g_free(in);
- check_expand(state, (in = g_strdup_printf("~%s/bar", user)), (out = g_strdup_printf("%s/bar", home)));
+ check_expand((in = g_strdup_printf("~%s/bar", user)), (out = g_strdup_printf("%s/bar", home)));
g_free(in);
g_free(out);
}
-static void test_expand_speacial(void)
-{
- State state = {.uri = "http://fanglingsu.github.io/vimb/"};
-
- check_expand(state, "%", "http://fanglingsu.github.io/vimb/");
- check_expand(state, "'%'", "'http://fanglingsu.github.io/vimb/'");
-}
-
static void test_strcasestr(void)
{
g_assert_nonnull(util_strcasestr("Vim like Browser", "browser"));
g_test_add_func("/test-util/expand-escaped", test_expand_escaped);
g_test_add_func("/test-util/expand-tilde-home", test_expand_tilde_home);
g_test_add_func("/test-util/expand-tilde-user", test_expand_tilde_user);
- g_test_add_func("/test-util/expand-spacial", test_expand_speacial);
g_test_add_func("/test-util/strcasestr", test_strcasestr);
g_test_add_func("/test-util/str_replace", test_str_replace);
g_test_add_func("/test-util/wildmatch-simple", test_wildmatch_simple);