diff --git a/callbacks.c b/callbacks.c index 2f9bf63..8c299a6 100644 --- a/callbacks.c +++ b/callbacks.c @@ -20,7 +20,6 @@ void buffer_changed(girara_session_t* session) { g_return_if_fail(session != NULL); - g_return_if_fail(Zathura.UI.statusbar.buffer != NULL); char* buffer = girara_buffer_get(session); @@ -28,4 +27,7 @@ buffer_changed(girara_session_t* session) girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, buffer); free(buffer); } + else { + girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, ""); + } } diff --git a/completion.c b/completion.c index 6c3efe1..6bfa583 100644 --- a/completion.c +++ b/completion.c @@ -1 +1,66 @@ /* See LICENSE file for license and copyright information */ + +#include +#include +#include + +#include "completion.h" +#include "utils.h" + +girara_completion_t* +cc_print(girara_session_t* session, char* input) +{ + girara_completion_t* completion = girara_completion_init(); + girara_completion_group_t* group = girara_completion_group_create(session, NULL); + + if(!session || !input || !completion || !group) + return NULL; + + girara_completion_add_group(completion, group); + + char* const list_printers[] = { + "lpstat", "-v", NULL + }; + + char* output; + if(!execute_command(list_printers, &output)) { + girara_completion_free(completion); + return false; + } + + /* parse single lines */ + unsigned int prefix_length = strlen("device for "); + char* p = strtok(output, "\n"); + char* q; + + while(p) + { + if(!(p = strstr(p, "device for ")) || !(q = strchr(p, ':'))) { + p = strtok(NULL, "\n"); + continue; + } + + unsigned int printer_length = q - p - prefix_length; + char* printer_name = malloc(sizeof(char) * printer_length); + + if(!printer_name) { + p = strtok(NULL, "\n"); + continue; + } + + strncpy(printer_name, p + prefix_length, printer_length - 1); + printer_name[printer_length - 1] = '\0'; + + /* add printer */ + girara_completion_group_add_element(group, printer_name, NULL); + + free(printer_name); + + /* next line */ + p = strtok(NULL, "\n"); + } + + free(output); + + return completion; +} diff --git a/completion.h b/completion.h index ea9c0a2..81800e9 100644 --- a/completion.h +++ b/completion.h @@ -3,4 +3,8 @@ #ifndef COMPLETION_H #define COMPLETION_H +#include + +girara_completion_t* cc_print(girara_session_t* session, char* input); + #endif // COMPLETION_H diff --git a/config.c b/config.c index c8ce721..f44025b 100644 --- a/config.c +++ b/config.c @@ -1,5 +1,7 @@ /* See LICENSE file for license and copyright information */ +#include "commands.h" +#include "completion.h" #include "shortcuts.h" #include "zathura.h" @@ -75,4 +77,13 @@ config_load_default() girara_shortcut_add(Zathura.UI.session, 0, 0, "zI", sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL); girara_shortcut_add(Zathura.UI.session, 0, 0, "zO", sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL); girara_shortcut_add(Zathura.UI.session, 0, 0, "z0", sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL); + + /* define default inputbar commands */ + girara_inputbar_command_add(Zathura.UI.session, "bmark", NULL, cmd_bookmark_create, NULL, "Add a bookmark"); + girara_inputbar_command_add(Zathura.UI.session, "bdelete", NULL, cmd_bookmark_delete, NULL, "Delete a bookmark"); + girara_inputbar_command_add(Zathura.UI.session, "blist", NULL, cmd_bookmark_open, NULL, "List all bookmarks"); + girara_inputbar_command_add(Zathura.UI.session, "close", NULL, cmd_close, NULL, "Close current file"); + girara_inputbar_command_add(Zathura.UI.session, "info", NULL, cmd_info, NULL, "Show file information"); + girara_inputbar_command_add(Zathura.UI.session, "print", NULL, cmd_print, cc_print, "Print document"); + girara_inputbar_command_add(Zathura.UI.session, "save", NULL, cmd_save, NULL, "Save document"); } diff --git a/utils.c b/utils.c index 9938900..5737152 100644 --- a/utils.c +++ b/utils.c @@ -2,10 +2,15 @@ #include #include +#include #include +#include +#include #include "utils.h" +#define BLOCK_SIZE 64 + bool file_exists(const char* path) { @@ -38,3 +43,80 @@ file_get_extension(const char* path) return path + i + 1; } + +bool +execute_command(char* const argv[], char** output) +{ + if(!output) { + return false; + } + + int p[2]; + if(pipe(p)) + return -1; + + pid_t pid = fork(); + + if(pid == -1) { // failure + return false; + } + else if(pid == 0) { // child + dup2(p[1], 1); + close(p[0]); + + if(execvp(argv[0], argv) == -1) { + return false; + } + } + else { // parent + dup2(p[0], 0); + close(p[1]); + + /* read output */ + unsigned int bc = BLOCK_SIZE; + unsigned int i = 0; + char* buffer = malloc(sizeof(char) * bc); + *output = NULL; + + if(!buffer) { + close(p[0]); + return false; + } + + char c; + while(1 == read(p[0], &c, 1)) { + buffer[i++] = c; + + if(i == bc) { + bc += BLOCK_SIZE; + char* tmp = realloc(buffer, sizeof(char) * bc); + + if(!tmp) { + free(buffer); + close(p[0]); + return false; + } + + buffer = tmp; + } + } + + char* tmp = realloc(buffer, sizeof(char) * (bc + 1)); + if(!tmp) { + free(buffer); + close(p[0]); + return false; + } + + buffer = tmp; + buffer[i] = '\0'; + + *output = buffer; + + /* wait for child to terminate */ + waitpid(pid, NULL, 0); + close(p[0]); + } + + return true; +} diff --git a/utils.h b/utils.h index bacc9b8..c10ea26 100644 --- a/utils.h +++ b/utils.h @@ -7,5 +7,6 @@ bool file_exists(const char* path); const char* file_get_extension(const char* path); +bool execute_command(char* const argv[], char** output); #endif // UTILS_H