diff --git a/src/browser.c b/src/browser.c index 83d60fcf..12c3670d 100644 --- a/src/browser.c +++ b/src/browser.c @@ -38,6 +38,8 @@ static int longest = 0; /* The number of columns in the longest filename in the list. */ static size_t selected = 0; /* The currently selected filename in the list; zero-based. */ +static listing_type listing_mode = DIRECTORY; + /* Whether we are listing files or open buffers. */ /* Our main file browser function. path is the tilde-expanded path we * start browsing from. */ @@ -58,6 +60,7 @@ char *do_browser(char *path) read_directory_contents: /* We come here when we refresh or select a new directory. */ + if (listing_mode == DIRECTORY) { path = free_and_assign(path, get_full_path(path)); if (path != NULL) @@ -96,11 +99,15 @@ char *do_browser(char *path) } else selected = 0; - old_selected = (size_t)-1; - present_path = mallocstrcpy(present_path, path); titlebar(path); + } else { + selected = 0; + list_current_buffers(); + } + + old_selected = (size_t)-1; while (TRUE) { lastmessage = HUSH; @@ -223,7 +230,7 @@ char *do_browser(char *path) selected = 0; } else if (func == do_last_file) { selected = filelist_len - 1; - } else if (func == goto_dir_void) { + } else if (func == goto_dir_void && listing_mode == DIRECTORY) { /* Ask for the directory to go to. */ int i = do_prompt(TRUE, FALSE, MGOTODIR, NULL, NULL, /* TRANSLATORS: This is a prompt. */ @@ -267,6 +274,10 @@ char *do_browser(char *path) } else if (func == do_enter) { struct stat st; + /* If listing only current buffers, return NULL*/ + if (listing_mode == BUFFERS) + return NULL; + /* It isn't possible to move up from the root directory. */ if (strcmp(filelist[selected], "/..") == 0) { statusline(ALERT, _("Can't move up a directory")); @@ -329,13 +340,29 @@ char *do_browser(char *path) free(path); + if (listing_mode == DIRECTORY) { free_chararray(filelist, filelist_len); filelist = NULL; + } + filelist_len = 0; return retval; } +/* Browse current buffers. */ +char *do_browse_current(void) +{ + char *ret; + + listing_mode = BUFFERS; + do_browser(NULL); + ret = filelist[selected]; + free(filelist); + filelist = NULL; + return ret; +} + /* The file browser front end. We check to see if inpath has a * directory in it. If it does, we start do_browser() from there. * Otherwise, we start do_browser() from the current directory. */ @@ -345,6 +372,8 @@ char *do_browse_from(const char *inpath) char *path; /* This holds the tilde-expanded version of inpath. */ + listing_mode = DIRECTORY; + path = real_dir_from_tilde(inpath); /* Perhaps path is a directory. If so, we'll pass it to @@ -454,6 +483,53 @@ void read_the_list(const char *path, DIR *dir) width = (COLS + 2) / (longest + 2); } +/* Fills filelist with a list current buffers. + * Also sets 'longest' and 'width'. */ +void list_current_buffers() +{ + int count = 0; + openfilestruct *first = openfile, *current = openfile; + + filelist_len = 0; + longest = 0; + + do { + filelist_len++; + current = current->next; + } while (first != current); + + filelist = (char **)nmalloc(filelist_len * sizeof(char *)); + + current = openfile; + + do { + size_t len; + char *filename = current->filename; + + filelist[count++] = filename; + + len = filename[0] == '\0' ? strlen(_("New Buffer")) : + strlen(filename); + + if (len > longest) + longest = len; + + current = current->next; + } while (first != current); + + longest += 10; + + if (longest < 15) + longest = 15; + + if (longest > COLS) + longest = COLS; + + qsort(filelist, filelist_len, sizeof(char *), diralphasort); + + width = (COLS + 2) / (longest + 2); +} + /* Return the function that is bound to the given key, accepting certain * plain characters too, for compatibility with Pico. */ functionptrtype parse_browser_input(int *kbinput) @@ -506,7 +582,9 @@ void browser_refresh(void) char *info; /* The additional information that we'll display about a file. */ + if (listing_mode == DIRECTORY) titlebar(present_path); + blank_edit(); wmove(edit, 0, 0); @@ -515,7 +593,9 @@ void browser_refresh(void) for (; i < filelist_len && row < editwinrows; i++) { struct stat st; - const char *thename = tail(filelist[i]); + const char *thename = listing_mode == DIRECTORY ? tail(filelist[i]) : + filelist[i][0] == '\0' ? _("New Buffer") : + filelist[i]; /* The filename we display, minus the path. */ size_t namelen = strlenpt(thename); /* The length of the filename in columns. */ @@ -551,6 +631,7 @@ void browser_refresh(void) col += longest; + if (listing_mode == DIRECTORY) { /* Show information about the file: "--" for symlinks (except when * they point to a directory) and for files that have disappeared, * "(dir)" for directories, and the file size for normal files. */ @@ -605,12 +686,13 @@ void browser_refresh(void) mvwaddstr(edit, row, col - infolen, info); + free(info); + } + /* If this is the selected item, finish its highlighting. */ if (i == selected) wattroff(edit, interface_color_pair[SELECTED_TEXT]); - free(info); - /* Add some space between the columns. */ col += 2; diff --git a/src/files.c b/src/files.c index cdd9f2cd..58d83663 100644 --- a/src/files.c +++ b/src/files.c @@ -596,6 +596,12 @@ void switch_to_adjacent_buffer(bool to_next) /* Switch to the next or previous file buffer. */ openfile = to_next ? openfile->next : openfile->prev; + switch_to_buffer(openfile); +} + +void switch_to_buffer(openfilestruct *target) +{ + openfile = target; #ifndef NANO_TINY /* When not in softwrap mode, make sure firstcolumn is zero. It might diff --git a/src/global.c b/src/global.c index 12c2cbc1..8c374aa2 100644 --- a/src/global.c +++ b/src/global.c @@ -284,6 +284,9 @@ void gototext_void(void) void to_files_void(void) { } +void to_current_void(void) +{ +} void goto_dir_void(void) { } @@ -664,6 +667,7 @@ void shortcut_init(void) const char *discardbuffer_gist = N_("Close buffer without saving it"); #ifdef ENABLE_BROWSER const char *tofiles_gist = N_("Go to file browser"); + const char *tocurrent_gist = N_("Browse current buffers"); const char *exitbrowser_gist = N_("Exit from the file browser"); const char *firstfile_gist = N_("Go to the first file in the list"); const char *lastfile_gist = N_("Go to the last file in the list"); @@ -1050,6 +1054,9 @@ void shortcut_init(void) add_to_funcs(to_files_void, MWRITEFILE|MINSERTFILE, N_("To Files"), WITHORSANS(tofiles_gist), TOGETHER, VIEW); + add_to_funcs(to_current_void, MGOTOLINE, + N_("Current buffers"), WITHORSANS(tocurrent_gist), TOGETHER, VIEW); + add_to_funcs(do_page_up, MBROWSER, prevpage_tag, WITHORSANS(prevpage_gist), TOGETHER, VIEW); add_to_funcs(do_page_down, MBROWSER, @@ -1340,6 +1347,7 @@ void shortcut_init(void) /* In restricted mode, don't allow entering the file browser. */ if (!ISSET(RESTRICTED)) add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files_void, 0); + add_to_sclist(MGOTOLINE, "^R", 0, to_current_void, 0); #endif add_to_sclist(MHELP|MBROWSER, "^C", 0, do_exit, 0); /* Allow exiting from the file browser and the help viewer with @@ -1660,6 +1668,8 @@ sc *strtosc(const char *input) else if (!strcasecmp(input, "tofiles") || !strcasecmp(input, "browser")) s->scfunc = to_files_void; + else if (!strcasecmp(input, "tocurrent")) + s->scfunc = to_current_void; else if (!strcasecmp(input, "gotodir")) s->scfunc = goto_dir_void; else if (!strcasecmp(input, "firstfile")) diff --git a/src/nano.h b/src/nano.h index 7ce36646..148d45dd 100644 --- a/src/nano.h +++ b/src/nano.h @@ -175,6 +175,10 @@ typedef enum { JOIN, PASTE, INSERT, ENTER, OTHER } undo_type; +typedef enum { + DIRECTORY, BUFFERS +} listing_type; + /* Structure types. */ #ifdef ENABLE_COLOR typedef struct colortype { diff --git a/src/proto.h b/src/proto.h index 2232e269..18f55736 100644 --- a/src/proto.h +++ b/src/proto.h @@ -183,7 +183,9 @@ typedef void (*functionptrtype)(void); /* Most functions in browser.c. */ #ifdef ENABLE_BROWSER char *do_browse_from(const char *inpath); +char *do_browse_current(void); void read_the_list(const char *path, DIR *dir); +void list_current_buffers(); functionptrtype parse_browser_input(int *kbinput); void browser_refresh(void); void browser_select_dirname(const char *needle); @@ -277,6 +279,7 @@ void prepare_for_display(void); #ifdef ENABLE_MULTIBUFFER void switch_to_prev_buffer(void); void switch_to_next_buffer(void); +void switch_to_buffer(openfilestruct *target); bool close_buffer(void); #endif void read_file(FILE *f, int fd, const char *filename, bool undoable, @@ -699,6 +702,7 @@ void flip_replace(void); void gototext_void(void); #ifdef ENABLE_BROWSER void to_files_void(void); +void to_current_void(void); void goto_dir_void(void); #endif #ifndef NANO_TINY diff --git a/src/search.c b/src/search.c index 43e816d8..4f5bcec4 100644 --- a/src/search.c +++ b/src/search.c @@ -823,6 +823,17 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer, /* Retain what the user typed so far and switch to searching. */ search_init(TRUE, TRUE); do_search(); + } else if (func == to_current_void) { + openfilestruct *current = openfile; + char *chosen = do_browse_current(); + + do { + if (current->filename == chosen) + break; + current = current->next; + } while (current != openfile); + + switch_to_buffer(current); } /* If a function was executed, we're done here. */