jed-users mailing list

[2007 Date Index] [2007 Thread Index] [Other years]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]

Re: is there an subversion-svn-mode for jed available


John E. Davis schrieb:
Joachim Schmitz <js@xxxxxxxxxxxxx> wrote:
is there a svn-mode for jed like the csv.sl found here:
http://jsnell.iki.fi/software/

The same author of cvs.sl has provided this patch, which he admits has
not been tested much.  Let me know if this works out.  Thanks, --John

I applied the patch and modified some other details, the result is attached.
It still has some quirks especially, when using it in split-windows with multiple buffers.

For example opening a file in xjed, split the buffer and invoke

File --> CVS --> Open directory list

asks for the directory in the mini buffer upon return , lists the svn output in the
*CSV directory list* buffer:
like so:

Exec: /usr/bin/svn "status" 2>&1
Dir: /home/perry/Zope/Products/WAeUP_SRP/

?      profiles/default/actions.xsl
....

and inserts:

Commands:
 Affect selected file:    a:Add  c:Commit  d:Diff  u:Update
                          m:Toggle mark r:revert
 Affect all marked files: A:Add  C:Commit  D:Diff  U:Update
 Other:                   M:Unmark all  q:Close this window

into the files-buffer.

First how can we make a "standard" svn.sl, in the jed svn-repostitory,so that we can work on improving further this mode ?
Second, where and how to report problems for this mode ?


--

Gruß Joachim
% -*- mode: slang; mode: folding -*-
%
% (Standard MIT/X11 license follows)
% 
% Copyright (c) 2003,2006 Juho Snellman
% 
% Permission is hereby granted, free of charge, to any person obtaining
% a copy of this software and associated documentation files (the
% "Software"), to deal in the Software without restriction, including
% without limitation the rights to use, copy, modify, merge, publish,
% distribute, sublicense, and/or sell copies of the Software, and to
% permit persons to whom the Software is furnished to do so, subject to
% the following conditions:
% 
% The above copyright notice and this permission notice shall be
% included in all copies or substantial portions of the Software.
% 
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
% LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
% OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
% WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
% 
% Utilities for CVS access from jed. 
% 
%    ** Installation **
% 
% Add this file into a directory that's in your JED_LIBRARY path 
% (the lib-directory of your jed install is a good bet, if you haven't
% manually set the library path). After that, just add the following line
% into your .jedrc: 
% 
%  () = evalfile("cvs");
% 
% 
%    ** Functionality **
%   
% Only the most common (for me) CVS operations are supported (add, commit,
% diff, update). The operations can be targeted at a single buffer,
% a bunch of files that have been marked, or at whole directories.
% 
%    * Operations on buffers *
%
%   In general, the buffer operations will save the buffer before
%   doing the operation.
%   
%     C-c a    'cvs add'    file
%     C-c c    'cvs commit' file
%     C-c u    'cvs update' file
%     C-c d    'cvs diff'   file
%     C-c m m  Mark the file for batch operations
%     
%     
%    * Operations on marked files *
%   
%   The easiest way to operate on marked files is to use the following
%   command to open the marked file list buffer, from where you can easily
%   start the other operations using keybindings specific to that
%   buffer.
%   
%     C-c l  show list of marked files
%   
%   The commands for operating on marked files are also available as
%   general keyboard commands, for those who find them more convenient.
%   
%     C-c m a    'cvs add'    all marked files
%     C-c m c    'cvs commit' all marked files
%     C-c m u    'cvs update' all marked files
%     C-c m d    'cvs diff'   all marked files
%     
%   For convenience, committing all marked files also unmarks the files.
%   
%     
%    * Operation on directories *
%    
%   The directory operations ask the user for a directory before
%   executing. The question defaults to the previous directory given.
%     
%     C-c C-a    'cvs add'    directory
%     C-c C-c    'cvs commit' directory
%     C-c C-u    'cvs update' directory
%     
%     C-c C-l    open directory view (basically a 'cvs -qnf update')
%     
%   Directory level commit is not supported.
%     
%     
%    * Diff/directory views *
% 
%   Operations on single/marked files can also be applied from inside
%   a *CVS diff* or *CVS dirlist* buffer, using the same keybindings
%   as in a *CVS marked files* buffer. These views are probably the 
%   most convenient methods for committing a large number of files,
%   or doing only selective updates on a project.
% 
% 
% Most of the above commands are also accessible from the File/CVS 
% menu.
%
%
%    ** Customization **
%  
% The following variables are available for modifying the behaviour
% of this module.
%      
%   cvs_executable:  [/usr/bin/cvs/] 
%     The location of the cvs executable
%     
%   cvs_set_reserved_keybindings: [1]
%     By default, the initialization routines set up global keybindings,
%     using the reserved prefix (defaults to C-c). Giving setting this 
%     variable to zero *before the file is evaluated* prevents the 
%     keybindings from being created.
%   
%   cvs_help: [1]
%     Setting this variable to 0 disables showing the keyboard help
%     in the marked files, diff, and directory list views.
%     
%    
%    ** Todo **
% 
%  - Document most public variables/functions
%  - Add support for 'diff -r HEAD'
%    
%
%    ** Changelog **
% 
% 2003-05-31 / Juho Snellman <jsnell@xxxxxx>
%   * First public release
%   
% 2003-05-31 / Juho Snellman <jsnell@xxxxxx>
%   * Run diff with -q
%   * Protect the Cvs_Mark_Type declaration inside a "!if (reloading)"
%   
% 2003-06-02 / Juho Snellman <jsnell@xxxxxx>
%   * Switch the commands affecting selected file to lowercase letters,
%     since they seem to get used a lot more.
%   * Add revert (cvs update -C)
%   
% 2003-12-09 / Juho Snellman <jsnell@xxxxxx>
%   * Fix find_marked_common_root
%   
% 2006-11-21 / Juho Snellman <jsnell@xxxxxx>
%   * Rough SVN port
%   
   
_debug_info=1; _traceback=1; _slangtrace=1;
% Uncomment these for bug hunting
% _debug_info=1; _traceback=1; _slangtrace=1;

% requirements
autoload("reload_buffer", "bufutils"); % jedmodes.sf.net/mode/bufutils/

%% Variables %{{{
if (_featurep(__FILE__)) {
    use_namespace("cvs"); 1;
} else {
    implements("cvs"); 0;
}
provide(__FILE__);
private variable reloading = ();

custom_variable("cvs_executable", "/usr/bin/svn");
custom_variable("cvs_set_reserved_keybindings", 1);
custom_variable("cvs_help", 1);

private variable message_buffer = " *CVS output*";
private variable diff_buffer = " *CVS diff*";
private variable list_buffer = " *CVS marked files*";
private variable dirlist_buffer = " *CVS directory list*";
variable project_root = "";
%}}}

%% Prototypes %{{{

public define cvs_add_buffer();

private define setbuf_unmodified();
private define killbuf();
private define setbuf_ro();
private define save_buffer_if_modified();
private define otherwindow_if_messagebuffer_active();
private define buffer_filename(buf);
private define buffer_dirname(buf);
private define require_buffer_dir_in_cvs();
private define entries_contains_filename(entries, filename);
private define require_buffer_file_in_cvs();
private define escape (str);
private define make_line_mark ();
private define mark_file(file);
private define unmark_file(file);
private define init_diff_buffer(new_window);
private define extract_filename();
private define insert_help();
private define update_diff_buffer (mark);
private define diff_extract_root();
private define diff_extract_filename();
private define postprocess_diff_buffer();
private define list_extract_filename();
private define init_list_buffer(erase);
private define update_list_buffer (mark);
private define dirlist_extract_filename();
private define update_dirlist_buffer (mark);
private define array_concat(a, b);
private define find_marked_common_root();
private define get_op_dir();
private define menu_init();
private define keymap_init();
%}}}

%% Manipulating buffers/windows %{{{

private define setbuf_unmodified() { %{{{
    setbuf_info( getbuf_info() & ~1 );
}
%}}}

private define killbuf() { %{{{
    setbuf_unmodified();
    delbuf(whatbuf());
}
%}}}

private define setbuf_ro() { %{{{
    setbuf_unmodified();
    set_readonly(1);
}
%}}}

private define save_buffer_if_modified() { %{{{
    variable flags;
    (,,,flags) =  getbuf_info();
    
    if (flags & 1) {
        save_buffer();
    }
}
%}}}

%% Actually, experience shows that this was a really bad idea. Code
%% not deleted in case someone actually wants to use it.
private define otherwindow_if_messagebuffer_active() { %{{{
    variable file; 
    (file,,,) = getbuf_info();
    
    % For the user's convenience. If we're currently in the CVS
    % output buffer (for example due to scrolling through a cvs diff), and 
    % there's exactly one other window visible, switch to that window 
    % and continue. 
    if (file == "") {
        if (nwindows != 2) {
            error("Active buffer doesn't contain a file. Can't execute CVS functions.");
        } 
        otherwindow();
        
        (file,,,) = getbuf_info();        
        if (file == "") {
            otherwindow();
            error("No visible window contains a file. Can't execute CVS functions.");
        }
    }
}

%}}}

private define buffer_filename(buf) { %{{{
    if (bufferp(buf)) {
        variable file, dir;
        (file, dir,,) = getbuf_info(buf);
        return path_concat(dir, file);
    } else {
        return "";
    }
}
%}}}

private define buffer_dirname(buf) { %{{{
    if (bufferp(buf)) {
        variable file, dir;
        (, dir,,) = getbuf_info(buf);
        return dir;
    } else {
        return "";
    }
}
%}}}


%}}}


%% Executing CVS commands %{{{

private define require_buffer_dir_in_cvs() { %{{{
    %% otherwindow_if_messagebuffer_active();
    
    variable file, dir; 
    (file, dir,,) = getbuf_info ( whatbuf() );
    
    if (file == Null_String or file == "") {
        error("Can't do CVS operations on buffers that don't contain a file.");
    }
    
    variable cvs_dir = path_concat(dir, ".svn");
    variable entries = path_concat(cvs_dir, "entries");
    
    if (file_status(cvs_dir) != 2) {
        error("Working directory " + dir + " lacks .svn/ subdirectory");
    }
    
    if (file_status(entries) != 1) {
        error("Working directory " + dir + " lacks .svn/entries");
    }
    
    return (file, dir);
}
%}}}

private define entries_contains_filename(entries, filename) { %{{{
    variable origbuf = whatbuf();
    
    setbuf(" *Entries*");
    erase_buffer();
    insert_file(entries);
    bob();
    
    variable found = fsearch("name=\"" + filename + "\"");
    
    erase_buffer();
    killbuf();
    setbuf(origbuf);
    
    return found;
}
%}}}

private define require_buffer_file_in_cvs() { %{{{
    variable file, dir; 
    (file, dir) = require_buffer_dir_in_cvs();
    
    variable cvs_dir = path_concat(dir, ".svn");
    variable entries = path_concat(cvs_dir, "entries");

    !if (entries_contains_filename(entries, file)) {
        variable res = 0;
        
        while (res != 'y' and res != 'n') {
            res = get_mini_response("File " + file +
                                    " not found in .svn/entries. Add it [yn]? ");
        }
        
        if (res == 'y') {
            cvs_add_buffer();
        } else {
            error("Unable to proceed");
        }
    }
    
    return (file, dir);
}
%}}}

private define escape (str) { %{{{
    return "\"" + str_quote_string(str, "\\\"$@", '\\') + "\"";
}
%}}}

define do_cvs (args, dir, use_default_buf, signal_error) { %{{{
    variable cmd = cvs_executable + " " +
      strjoin(array_map(String_Type, &escape, args), " ");        
    
#ifdef OS2 UNIX
    cmd += " 2>&1";    % re-direct stderr
#endif
    
    if (use_default_buf) {
        pop2buf(message_buffer);
        set_readonly(0);
        erase_buffer();
    }
    
    if (chdir(dir)) {
        error("Couldn't chdir to '" + dir + "': " + errno_string(errno));
    }
    
    insert("Exec: " + cmd + "\nDir: " + dir + "\n\n");
    variable ret = run_shell_cmd(cmd);
    bob();
    setbuf_ro();
    
    otherwindow();
    
    if (ret and signal_error) {
        error(sprintf("cvs returned error code %d", ret));
    }
}
%}}}


%}}}


%% Marking files %{{{

!if (reloading) {
    typedef struct {
        filename, diff_line_mark, list_line_mark, dirlist_line_mark
    } Cvs_Mark_Type;
}

variable marks = Assoc_Type [];

private define make_line_mark () { %{{{
    return create_line_mark(color_number("menu_selection"));
}
%}}}

private define mark_file(file) { %{{{
    variable new = @Cvs_Mark_Type;
    new.filename = file;
    
    variable orig_buf = whatbuf();
    
    update_list_buffer(new);
    update_diff_buffer(new);
    update_dirlist_buffer(new);
    setbuf(orig_buf);
    
    marks[file] = new;
    %% recenter(0);
    call("redraw");
    message("Marked " + file);    
}
%}}}

private define unmark_file(file) { %{{{
    assoc_delete_key(marks, file);
    %% recenter(0);
    call("redraw");
    message("Unmarked " + file);
}
%}}}

public define cvs_unmark_all() { %{{{
    marks = Assoc_Type [];
}
%}}}

public define cvs_mark_buffer() { %{{{
    %% otherwindow_if_messagebuffer_active();  
    mark_file(buffer_filename(whatbuf()));
}
%}}}

public define cvs_unmark_buffer() { %{{{
    %% otherwindow_if_messagebuffer_active();    
    unmark_file(buffer_filename(whatbuf()));
}
%}}}

define have_marked_files() { %{{{
    return length(assoc_get_keys(marks));
}
%}}}

define toggle_marked_file(file) { %{{{
    if (file != Null_String) {        
        if (assoc_key_exists(marks, file)) {
            unmark_file(file);
        } else {
            mark_file(file);
        }
    }
}
%}}}

%}}}


%% CVS operations on a single buffer %{{{

public define cvs_add_buffer() { %{{{
    variable file, dir;
    (file, dir) = require_buffer_dir_in_cvs();
    do_cvs([ "add", file ], dir, 1, 1);
}
%}}}

public define cvs_commit_buffer() { %{{{
    variable file, dir;
    (file, dir) = require_buffer_file_in_cvs();
    save_buffer_if_modified();
    
    variable message = read_mini("Committing '" + file +"'. Log message: ", "", "");
    
    do_cvs([ "commit", "-m", message, file ], dir, 1, 1);
    reload_buffer();
}
%}}}

public define cvs_diff_buffer() { %{{{
    variable file, dir;
    (file, dir) = require_buffer_file_in_cvs();
    save_buffer_if_modified();
    
    init_diff_buffer(1);
    
    do_cvs([ "diff", file ], dir, 0, 0);
    
    postprocess_diff_buffer();
}
%}}}

public define cvs_update_buffer() { %{{{
    variable file, dir;
    (file, dir) = require_buffer_file_in_cvs();
    save_buffer_if_modified();
    
    do_cvs([ "update", file ], dir, 1, 1);
    
    if (bol_fsearch("retrieving")) {
        message("Updated");
    } else {
        message("Not updated (no new version available)");
    }
    
    find_file(path_concat(dir, file));    
}
%}}}

%}}}


%% Functions common to the marked files, diff, and directory list buffers %{{{

private define extract_filename() { %{{{
    if (whatbuf() == diff_buffer) {
        return diff_extract_filename();
    } else if (whatbuf() == list_buffer) {
        return list_extract_filename();
    }if (whatbuf() == dirlist_buffer) {
        return dirlist_extract_filename();
    } else {
        error("that can only be done in buffers *CVS diff* and *CVS marked files*");
    }
}
%}}}

define toggle_marked() { %{{{
    variable file, dir;
    (file, dir) = extract_filename();    
    toggle_marked_file(path_concat(file, dir));
}
%}}}

private define insert_help() { %{{{
    if (cvs_help) {
        insert("Commands:\n" +
               "  Affect selected file:    a:Add  c:Commit  d:Diff  u:Update\n" +
               "                           m:Toggle mark r:revert\n" +
               "  Affect all marked files: A:Add  C:Commit  D:Diff  U:Update\n" +
               "  Other:                   M:Unmark all  q:Close this window\n\n");
    }
}
%}}}

%}}}


%% "CVS diff" view %{{{

private variable diff_filenames = Assoc_Type [];

private define init_diff_buffer(new_window) { %{{{
    if (new_window)
      pop2buf(diff_buffer);
    else
      sw2buf(diff_buffer);
    
    use_keymap("cvs-list");
    set_readonly(0);
    erase_buffer();
    diff_filenames = Assoc_Type [];
}
%}}}

private define update_diff_buffer (mark) { %{{{
   variable orig_buf = whatbuf();
   setbuf(diff_buffer);
   if (assoc_key_exists(diff_filenames, mark.filename)) {
      variable line = diff_filenames [mark.filename];
      push_spot();
      goto_line(line);
      mark.diff_line_mark = make_line_mark();
      pop_spot();
    }
   setbuf(orig_buf);
}
%}}}

private define diff_extract_root() { %{{{
    push_spot();
    bob();
    () = down(1);
    
    EXIT_BLOCK {
        pop_spot();
    }
    
    !if (looking_at("Dir: ")) {
        error("Buffer doesn't contain a 'Dir: '-line on the second line");
    }
    
    return line_as_string()[[5:]];
}
%}}}

private define diff_extract_filename() { %{{{
    push_spot();
    
    EXIT_BLOCK {
        pop_spot();
    }
    
    if (bol_bsearch("Index: ")) {
        variable filename = line_as_string()[[7:]];
        variable dir = diff_extract_root();
        
        return (dir, filename);        
    }
    
    error("No file selected (try redoing the command between 'Index: '- lines)");
}
%}}}

private define postprocess_diff_buffer() { %{{{
    pop2buf(diff_buffer);
    push_spot();
    bob();
    () = down(2);
    
    set_readonly(0);
    insert_help();
    
    while (bol_fsearch("Index: ")) {
        variable filename = line_as_string()[[7:]];
        variable dir = diff_extract_root();
                
        if (dir != NULL) {
            filename = path_concat(dir, filename);        
            diff_filenames[filename] = what_line();
        
            if (assoc_key_exists(marks, filename)) {
                update_diff_buffer(marks[filename]);
            }
        }
        () = down(1);
    }    
    set_readonly(1);
    
    pop_spot();
}
%}}}

private define diff_extract_linenumber() { %{{{
    push_spot();
    EXIT_BLOCK {
        pop_spot();    
    }
    
    if (andelse {bol_bsearch("@@ ")}
        {ffind_char('+')}) 
    {
        push_mark();
        ffind_char(',');
        return integer(bufsubstr());
    } else {
        return 0;
    }
}
%}}}

%}}}


%% "CVS marked files" view %{{{

private define list_extract_filename() %{{{
{    
    push_spot();
    EXIT_BLOCK {
        pop_spot();
    }
    
    variable line = line_as_string();
    
    if (andelse  {line != ""}
        {line[[0]] != " "}
        {path_is_absolute(line)})
    {
        return (path_dirname(line), path_basename(line));
    }
    
    error("Line doesn't contain a valid filename\n");
}
%}}}

private define init_list_buffer(erase) { %{{{
    set_mode("cvs-list", 0);
    use_keymap("cvs-list");
    set_readonly(0);
    
    if (erase)
      erase_buffer();
    
    push_spot();
    bob();
    
    if (eobp()) {
        insert("The following files have been marked by CVS mode. ");
        insert_help();
    } else {
        pop_spot();
    }
}
%}}}

public define cvs_list_marked() { %{{{
    pop2buf(list_buffer);
    
    init_list_buffer(1);
    
    insert("  ----- \n");

    push_spot();
    foreach (marks) using ("keys") {
        variable file = ();
        marks[file].list_line_mark = make_line_mark();
        insert(file + "\n");            
    }
    pop_spot();
    
    set_readonly(1);
}
%}}}

private define update_list_buffer (mark) { %{{{
    setbuf(list_buffer);
    init_list_buffer(0);
    
    push_spot();
    bob();
    if (re_fsearch("^" + mark.filename + "$")) {
        mark.list_line_mark = make_line_mark();
    } else {
        eob();
        mark.list_line_mark = make_line_mark();
        insert(mark.filename + "\n");
    }
    pop_spot();
    
    set_readonly(1);    
}
%}}}

%}}}


%% "CVS directory list" view %{{{

private variable dirlist_filenames = Assoc_Type [];

private define dirlist_valid_filename(line) { %{{{
    return andelse {strlen(line) > 2} {line[[0]] != " "} {line[[1]] == " "};
}
%}}}

private define dirlist_extract_filename() %{{{
{    
    push_spot();
    EXIT_BLOCK {
        pop_spot();
    }
    
    variable line = line_as_string();
    
    if (dirlist_valid_filename(line))
    {
        variable file = line[[2:]];
        variable dir = diff_extract_root();
        
        return (dir, file);
    }
    
    error("Line doesn't contain a valid filename\n");
}
%}}}

private define update_dirlist_buffer(mark) { %{{{
    setbuf(dirlist_buffer);
    push_spot();
    
    if (assoc_key_exists(dirlist_filenames, mark.filename)) {
        variable line = dirlist_filenames [mark.filename];

        push_spot();
        goto_line(line);
        mark.dirlist_line_mark = make_line_mark();
        pop_spot();
    }    
}
%}}}

private define postprocess_dirlist_buffer() { %{{{
    push_spot();
    bob();
    () = down(2);
    
    set_readonly(0);
    insert_help();
    
    while (down(1)) {
        if (dirlist_valid_filename(line_as_string())) {
            variable filename, dir;
            (dir, filename) = dirlist_extract_filename();
            
            filename = path_concat(dir, filename);
            dirlist_filenames[filename] = what_line();
            
            if (assoc_key_exists(marks, filename)) {
                update_dirlist_buffer(marks[filename]);
            }
        }
    }    
    set_readonly(1);
    
    pop_spot();
}

%}}}

public define cvs_list_dir() { %{{{
    variable dir = get_op_dir();
    
    sw2buf(dirlist_buffer);
    use_keymap("cvs-list");
    set_readonly(0);
    erase_buffer();
    
    do_cvs(["status"], dir, 0, 0);
    
    postprocess_dirlist_buffer();
}
%}}}

%}}}


%% Operations on all marked files %{{{

% I refuse to believe there's no easier way merge two arrays...
private define array_concat(a, b) { %{{{
    variable lena = length(a);
    variable lenb = length(b);
    variable new = String_Type [lena + lenb];
    variable i;
    
    for (i = 0; i < lena; i++) {
        new[i] = a[i];
    }
    
    for (i = 0; i < lenb; i++) {
        new[i + lena] = b[i];
    }
    
    return new;
}
%}}}

private define find_marked_common_root() { %{{{
    variable afiles = assoc_get_keys(marks);
    if (length(afiles) == 0) {
        error("No files marked");
    }
    
    variable dirs = array_map(String_Type, &path_dirname, afiles);
    variable rfiles = String_Type [length(afiles)];
    
    variable prefix = "";
    
    foreach (dirs) {
        variable dir = ();
        
        if (strcmp(dir, "") != 0) {
            if (strcmp(prefix, "") == 0) {
                prefix = dir;
            } else {
                while (strcmp(dir, prefix) != 0 and
                       strlen(prefix) > 1) {
                    if (strlen(dir) == strlen(prefix)) {
                        prefix = path_dirname(prefix);
                        dir = path_dirname(dir);
                    } else if (strlen(dir) < strlen(prefix)) {
                        prefix = path_dirname(prefix);
                    } else {
                        dir = path_dirname(dir);
                    }
                }
            }
        }
    }
    
    % +1 to get rid of leading slash in unix. This assumption might
    % be invalid on other platforms
    variable prefixlen = strlen(prefix) + 1;
    
    variable i;
    for (i = 0; i < length(rfiles); i++) { 
        rfiles[i] = afiles[i][[prefixlen:]];
    }
    
    return (dir, rfiles);
}
%}}}

public define cvs_add_marked() { %{{{
    variable dir, rfiles;    
    (dir, rfiles) = find_marked_common_root();
    
    do_cvs(array_concat( ["add"], rfiles ), dir, 1, 1);
}
%}}}

public define cvs_commit_marked() { %{{{
    variable dir, rfiles;    
    (dir, rfiles) = find_marked_common_root();
    
    variable message = read_mini("Committing all marked files. Log message: ", "", "");
    
    do_cvs(array_concat( ["commit", "-m", message], rfiles ), dir, 1, 1);
    
    cvs_unmark_all();
}
%}}}

public define cvs_diff_marked() { %{{{
    variable dir, rfiles;    
    (dir, rfiles) = find_marked_common_root();
    
    init_diff_buffer(1);
    
    do_cvs(array_concat( ["diff"], rfiles ), dir, 0, 0);
    postprocess_diff_buffer();

    sw2buf(diff_buffer);
}
%}}}

public define cvs_update_marked() { %{{{
    variable dir, rfiles;    
    (dir, rfiles) = find_marked_common_root();
    
    do_cvs(array_concat( ["update"], rfiles ), dir, 1, 1);
}
%}}}

%}}}


%% Operations on single files (valid only in marked files, diff, or 
%% directory list buffers). %{{{

public define cvs_add_selected() { %{{{
    variable dir, file;
    (dir, file) = extract_filename();    
    do_cvs(["add", file], dir, 1, 1);
}
%}}}

public define cvs_commit_selected() { %{{{
    variable dir, file;
    (dir, file) = extract_filename();    
    variable message = read_mini("Committing '" + file + "'. Log message: ", "", "");
    
    do_cvs(["commit", "-m", message, file], dir, 1, 1);
}
%}}}

public define cvs_diff_selected() { %{{{
    variable dir, file;
    (dir, file) = extract_filename();
    init_diff_buffer(1);
    do_cvs(["diff", file], dir, 0, 0);
    postprocess_diff_buffer();
}
%}}}

public define cvs_update_selected() { %{{{
    variable dir, file;
    (dir, file) = extract_filename();
    do_cvs(["update", file], dir, 1, 1);
}
%}}}

public define cvs_revert_selected() { %{{{
    variable dir, file;
    (dir, file) = extract_filename();
    
    variable a = ' ';
    
    while (a != 'y' and a != 'n') {
        a = get_mini_response("Revert '" + file + "' [ny]?");    
    } 
    
    if (a == 'y') {    
        do_cvs(["revert", file], dir, 1, 1);
    }
}
%}}}

public define cvs_open_selected() { %{{{
    variable dir, file, linenum;
    (dir, file) = extract_filename();
    
    if (whatbuf() == diff_buffer) {
        linenum = diff_extract_linenumber();
    } else {
        linenum = 0; 
    }
    
    otherwindow();
    find_file(path_concat(dir, file));
    if (linenum) {
        goto_line(linenum);
    }
}
%}}}


%}}}


%% CVS directory-level operations %{{{

private define get_op_dir() { %{{{
    variable default = project_root;
    
    if (default == "") {
        default = getcwd();
    } 
    
    % Filename completion wants to use the directory of the current
    % buffer as a prefix, even if a default value is given. Use
    % this massive kludge as a workaround. (We also need tinker with
    % cwd for the same reason).
    
    variable orig_buf = whatbuf();
    ERROR_BLOCK {
        sw2buf(orig_buf);    
    }
    
    sw2buf(" *Kludge*");
    setbuf_info("", "", " *Kludge*", 0);
    chdir(default);
    
    variable dir = read_with_completion("Enter dir for operation: ", 
                                        Null_String, Null_String, 'f');

    sw2buf(orig_buf);
    
    project_root = dir;
    
    return project_root;
}
%}}}

public define cvs_add_dir() { %{{{ 
    %% Kludge to get rid of a possible trailing separator
    variable dir = path_dirname(path_concat(get_op_dir(), "foo"));
    variable parent = path_dirname(dir);
    variable name = path_basename(dir);
    
    do_cvs(["add", name], parent, 1, 1);
}
%}}}

public define cvs_diff_dir() { %{{{
    variable dir = get_op_dir();
    
    init_diff_buffer(0);
        
    do_cvs(["diff"], dir, 0, 0);    
    postprocess_diff_buffer();
}
%}}}

public define cvs_update_dir() { %{{{
    variable dir = get_op_dir();
    do_cvs(["-q", "update"], dir, 1, 1);
}
%}}}

%}}}


%% Internal development helpers %{{{

public define cvs_re_eval() { %{{{
   () = evalfile("cvs");
}
%}}}

%}}}


%% Initialization %{{{

private define menu_init() { %{{{
    if (reloading) {
        return;
    }      
    
    %() = evalfile("popups");
    variable menu = "Global.&File";
    
    menu_insert_popup("Canc&el Operation", menu, "C&VS");
    menu_insert_separator("Canc&el Operation", menu);
    
    menu = "Global.&File.C&VS";
    menu_append_item(menu, "&Add buffer", "cvs_add_buffer");
    menu_append_item(menu, "&Commit buffer", "cvs_commit_buffer");
    menu_append_item(menu, "&Diff buffer", "cvs_diff_buffer");
    menu_append_item(menu, "&Mark buffer", "cvs_mark_buffer");
    menu_append_item(menu, "Unmark buffer", "cvs_unmark_buffer");
    menu_append_item(menu, "&Update buffer", "cvs_update_buffer");
    menu_append_separator(menu);
    
    menu_append_item(menu, "&List marked", "cvs_list_marked");
    menu_append_item(menu, "Add marked", "cvs_add_marked");
    menu_append_item(menu, "Commit marked", "cvs_commit_marked");
    menu_append_item(menu, "Diff marked", "cvs_diff_marked");
    menu_append_item(menu, "Unmark all", "cvs_unmark_all");
    menu_append_item(menu, "Update marked", "cvs_update_marked");
    menu_append_separator(menu);
    
    menu_append_item(menu, "Add directory", "cvs_add_dir");
    menu_append_item(menu, "Diff directory", "cvs_diff_dir");
    menu_append_item(menu, "Update directory", "cvs_update_dir");
    menu_append_item(menu, "Open directory list", "cvs_list_dir");
}
%}}}

private define keymap_init() { %{{{
    if (cvs_set_reserved_keybindings) {
        setkey_reserved( "cvs_add_buffer", "a");
        setkey_reserved( "cvs_add_marked", "ma");
        setkey_reserved( "cvs_add_dir", "^a");
    
        setkey_reserved( "cvs_commit_buffer", "c");
        setkey_reserved( "cvs_commit_marked", "mc");
    
        setkey_reserved( "cvs_diff_buffer", "d");
        setkey_reserved( "cvs_diff_marked", "md");
        setkey_reserved( "cvs_diff_dir", "^d");
        
        setkey_reserved( "cvs_list_marked", "l");
        setkey_reserved( "cvs_list_marked", "ml");
        setkey_reserved( "cvs_list_dir", "^l");
        
        setkey_reserved( "cvs_mark_buffer", "mm");
        setkey_reserved( "cvs_unmark_buffer", "m^m");
        setkey_reserved( "cvs_unmark_all", "m^u");
        
        setkey_reserved( "cvs_update_buffer", "u");
        setkey_reserved( "cvs_update_marked", "mu");
        setkey_reserved( "cvs_update_dir", "^u");
        
        setkey_reserved( "cvs_re_eval", "r");
    }
    
    variable kmap = "cvs-list";
    
    !if (keymap_p(kmap)) {
        make_keymap(kmap);
        definekey("cvs_add_marked", "A", kmap);
        definekey("cvs_commit_marked", "C", kmap);
        definekey("cvs_diff_marked", "D", kmap);
        definekey("cvs_update_marked", "U", kmap);
        
        definekey("cvs_add_selected", "a", kmap);
        definekey("cvs_commit_selected", "c", kmap);
        definekey("cvs_diff_selected", "d", kmap);
        definekey("cvs_update_selected", "u", kmap);
        definekey("cvs_open_selected", "o", kmap);
        definekey("cvs_revert_selected", "r", kmap);
        
        definekey("cvs->toggle_marked", "m", kmap);
        definekey("cvs->toggle_marked", " ", kmap);
        definekey("cvs->toggle_marked", "\r", kmap);
        definekey("cvs_unmark_all", "M", kmap);
        definekey("delete_window", "q", kmap);
        
    }
    
}
%}}}

menu_init();
keymap_init();

%}}}


[2007 date index] [2007 thread index]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]