[Date Prev][Date Next][Thread Prev][Thread Next][Author Index][Date Index][Thread Index]
Re: PATCH: Shear function and useful selection operations
- To: zzdev@xxxxxxxxxx
- Subject: Re: PATCH: Shear function and useful selection operations
- From: Mark-Jason Dominus <mjd@xxxxxxxxxx>
- Date: Fri, 30 Oct 1998 16:01:57 -0500
- In-reply-to: Your message of "Thu, 29 Oct 1998 02:14:49 EST." <19981029071449.18612.qmail@xxxxxxxxxx>
- Reply-to: zzdev@xxxxxxxxxx
Ahem. This time for sure.
--- zigzag.55 Tue Oct 27 22:55:17 1998
+++ zigzag.shearselect Fri Oct 30 15:58:33 1998
@@ -29,7 +29,7 @@
#
# $Log: zigzag,v $
# Revision 0.55 1998/10/26 05:37:32 xanni
-# Change default file extension and incorporate EDITOR selection patch
+# Change default file extension and incorporate $EDITOR selection patch
# from Mark-Jason Dominus <mjd@xxxxxxxxxx>
#
# Revision 0.54 1998/10/08 03:56:21 xanni
@@ -88,6 +88,7 @@
my $CELLS_PER_WIN = 5; # Number of cells displayed across each window
my $CURSOR_HOME = 10; # NOTE! This assumes it stays fixed!
my $DELETE_HOME = 99; # NOTE! This assumes it stays fixed!
+my $SELECT_HOME = 21; # NOTE! This assumes it stays fixed!
my $EDITOR = choose_editor();
my $FILENAME = "zigzag.zz"; # Default filename for initial slice
my $TEMP_FILE = "/tmp/zigzag-$<-$^T"; # Filename used for external editing
@@ -171,8 +172,10 @@
"N" => 'cell_create(0);',
&KEY_IC => 'cell_create(0);',
"n" => 'cell_create(1);',
- "M" => 'atcursor_mark(0);',
- "m" => 'atcursor_mark(1);',
+ "M" => 'atcursor_select(0);',
+ "m" => 'atcursor_select(1);',
+ &meta_key("m") => 'rotate_selection()',
+ &meta_key("M") => 'push_selection()',
"Q" => 'view_quadrant_toggle(0);',
"q" => 'view_quadrant_toggle(1);',
"R" => 'view_reset(0);',
@@ -236,6 +239,7 @@
10 => "Cursor home",
"10+d.1" => 1,
"10+d.2" => 11,
+ "10-d.1" => 21,
11 => "Action",
"11+d.1" => 12,
"11-d.2" => 10,
@@ -268,6 +272,10 @@
"19+d.1" => 20,
20 => "I",
"20-d.1" => 19,
+ 21 => "Selection",
+ "21+d.1" => 10,
+ "21+d.2" => 21,
+ "21-d.2" => 21,
30 => "#Edit\natcursor_edit(1);",
"30+d.1" => 35,
"30-d.2" => 0,
@@ -313,9 +321,12 @@
"55+d.1" => 56,
56 => "#O-break\natcursor_break_link(1, 'O');",
"56-d.1" => 55,
- 60 => "#Mark\natcursor_mark(1);",
+ 60 => "#Select\natcursor_select(1);",
"60-d.2" => 50,
"60+d.2" => 70,
+ "60+d.1" => 61,
+ 61 => "#Rot.Selection\nrotate_selection();",
+ "61-d.1" => 60,
70 => "#L-Hop\natcursor_hop(1, 'L');",
"70+d.1" => 71,
"70-d.2" => 60,
@@ -334,9 +345,18 @@
"74+d.1" => 75,
75 => "#O-Hop\natcursor_hop(1, 'O');",
"75-d.1" => 74,
- 80 => "#Shear",
+ 80 => "#Shear -^\natcursor_shear(1, 'D', 'L')",
"80-d.2" => 70,
"80+d.2" => 85,
+ "80+d.1" => 81,
+ 81 => "#Shear -v\natcursor_shear(1, 'U', 'L')",
+ "81-d.1" => 80,
+ "81+d.1" => 82,
+ 82 => "#Shear ^+\natcursor_shear(1, 'D', 'R')",
+ "82-d.1" => 81,
+ "82+d.1" => 83,
+ 83 => "#Shear v+\natcursor_shear(1, 'U', 'R')",
+ "83-d.1" => 82,
85 => "#Chug",
"85-d.2" => 80,
"85+d.2" => 90,
@@ -427,10 +447,11 @@
return (defined($ZZ{"$cell-d.clone"}) || defined($ZZ{"$cell+d.clone"}));
}
-sub is_marked($)
+sub is_selected($)
{
my $cell = shift;
- return (defined($ZZ{"$cell-d.mark"}) || defined($ZZ{"$cell+d.mark"}));
+ my $headcell = get_lastcell($cell, '-d.mark');
+ return $headcell == $SELECT_HOME && $cell != $SELECT_HOME;
}
@@ -454,6 +475,15 @@
# Retrieving Information
# Named get_*
#
+
+sub get_accursed($)
+# Get the cell that is accursed in the specified window
+# or by the specified cursor
+{
+ my $n = shift;
+ &get_lastcell(&get_cursor($n), "-d.cursor");
+}
+
sub get_lastcell($$)
# Find the last cell along a given dimension
{
@@ -625,6 +655,79 @@
return @_;
}
+#
+# Multiple-cell operations
+# Named do_*
+#
+sub do_shear($$$;$$)
+# Given a row of cells starting at $first_cell,
+# move them all $n cells in the $dir direction.
+# Cells that were linked in the $link direction
+# have their links broken and relinked to new cells.
+#
+# Before: do_shear(A1, d.1, d.2, 1);
+#
+# ---> d.1
+# V d.2
+#
+# A1 --- B1 --- C1 --- D1 --- E1
+# | | | |
+# A2 B2 C2 D2 E2
+#
+# After:
+#
+# A1 --- B1 --- C1 --- D1 --- E1
+# | | |
+# A2 B2 C2 D2 E2
+#
+# Optional fourth argument $n defaults to 1.
+# Optional fifth argument $hang says whether the cell on the end
+# should be linked back at the beginning or whether it should just
+# be left hanging. $hang=false: Back at beginning.
+# $hang = true: Leave hanging. Default: false.
+{
+ my ($first_cell, $dir, $link, $n, $hang) = @_;
+ $n = 1 unless defined $n;
+ $hang = 0 unless defined $hang;
+
+ my $cell;
+ my ($prev_cell, $prev_linked);
+ my $first_linked = $ZZ{"$first_cell$link"};
+
+ my @shear_cells = &cells_row($first_cell, $dir);
+ my @linked_cells = map {$ZZ{"$_$link"}} @shear_cells;
+
+ my @new_link = @linked_cells;
+ # Move some of these from the beginning
+ my @x = splice(@new_link, 0, $n);
+ # And put them back at the end.
+ push @new_link, @x;
+
+ my $i;
+ my $linkno = 0;
+ my $last_linked;
+ # Break all the links
+ for ($i=0; $i < @shear_cells; $i++) {
+ my $old_link = $linked_cells[$i];
+ next unless defined $old_link;
+ my $shear_cell = $shear_cells[$i];
+ link_break($shear_cell, $old_link, $link);
+ }
+
+ $linkno = 0;
+ for ($i=0; $i < @shear_cells; $i++) {
+ my $new_link = $new_link[$i];
+ next unless defined $new_link;
+ next if $i == $#shear_cells && $hang;
+ my $shear_cell = $shear_cells[$i];
+ link_make($shear_cell, $new_link, $link);
+ }
+
+ foreach (@Window_Dirty)
+ {
+ $_ = $TRUE;
+ }
+}
#
# Functions that operate on links between cells
@@ -841,25 +944,52 @@
}
}
-sub atcursor_mark($)
-# mark the current cell
+sub atcursor_select($)
+# select or unselect the current cell
{
my $curs = &get_cursor($_[0]);
my $cell = &get_lastcell($curs, "-d.cursor");
- my $new = $ZZ{"n"}++;
- $ZZ{$new} = "mark";
- &cell_insert($new, $cell, "+d.mark");
- &status_draw("Marked cell $cell");
+ if (&is_selected($cell)) {
+ &cell_excise($cell, "d.mark");
+ &status_draw("Selected cell $cell");
+ } else {
+ &cell_insert($cell, $SELECT_HOME, "+d.mark");
+ &status_draw("Selected cell $cell");
+ }
#&cursor_move_dimension($curs, "+d.mark");
-
foreach (@Window_Dirty)
{
$_ = $TRUE;
}
}
+sub rotate_selection ()
+# Exchange the current selection with one of the saved selections. If
+# there's an input buffer, it holds the number of the desired
+# selection, so shear all the selections +d.2ward by that many.
+# (Selection #0 is currently active.) Otherwise, just shear by 1.
+{
+ my $shear_count = (defined($Input_Buffer) ? $Input_Buffer : 1);
+# my $num_selections = &cells_row($SELECT_HOME, "+d.2");
+
+ do_shear($SELECT_HOME, '-d.2', '+d.mark', $shear_count);
+}
+
+sub push_selection()
+# Push the current selection onto the selection stack.
+# All saved selections move +d.2ward one step.
+# The current selection is now empty.
+{
+ my $new_sel = $ZZ{"n"}++;
+ my $num_selections = &cells_row($SELECT_HOME, "+d.2");
+ $ZZ{$new_sel} = "Selection #$num_selections";
+ cell_insert($new_sel, $SELECT_HOME, "+d.2");
+ do_shear($SELECT_HOME, "+d.2", "+d.mark", 1);
+}
+
+
sub atcursor_insert($$)
# Insert a new cell at a given cursor in a given direction
{
@@ -988,6 +1118,25 @@
}
}
+sub atcursor_shear($$$)
+# Arguments: $curs = cursor/window number
+# $sheardir = direction and +/-
+# $linkdir = direction and +/-
+# directions name axes. They get turned into dimensions
+# for the do_shear call.
+# Head cell of the shear is the accursed cell
+{
+ my ($number, $shear_dir, $link_dir) = @_;
+
+ my $cursor = &get_cursor($number);
+ my $shear_dim = &get_dimension($cursor, $shear_dir);
+ my $link_dim = &get_dimension($cursor, $link_dir);
+
+ my $headcell = &get_accursed($number);
+
+ &do_shear($headcell, $shear_dim, $link_dim, 1);
+}
+
sub atcursor_edit($)
# Invoke an external text editor to edit the cell under a given cursor
{
@@ -1156,6 +1305,22 @@
unlink $TEMP_FILE;
}
+sub cells_row($$)
+# Final all the cells in the row starting from $cell
+# in the $dir dimension. Return a list or a count
+# depending on calling context.
+{
+ my ($cell1, $dir) = @_;
+ my $cell;
+ my @result = ($cell1);
+ for ($cell = $ZZ{"$cell1$dir"};
+ defined($cell) && $cell != $cell1;
+ $cell = $ZZ{"$cell$dir"}
+ ) {
+ push @result, $cell;
+ }
+ @result;
+}
#
# Functions that operate on the whole screen
@@ -1299,8 +1464,8 @@
if (!$LOTS_OF_COLOURS && &is_clone($cell))
{ addch($win, $row - 1, $col, "c"); }
- # Display marked-cell flag if we aren't using lots of colours
- if (!$LOTS_OF_COLOURS && &is_marked($cell))
+ # Display selected-cell flag if we aren't using lots of colours
+ if (!$LOTS_OF_COLOURS && &is_selected($cell))
{ addch($win, $row - 1, $col, "m"); }
# Display dimension guide
@@ -1509,9 +1674,9 @@
# Clone cells get a special colour in high-colour mode
attron($win, COLOR_PAIR(2) | A_BOLD)
if $LOTS_OF_COLOURS && &is_clone($cell);
- # Ditto marked cells
+ # Ditto selected cells
attron($win, COLOR_PAIR(3) | A_BOLD)
- if $LOTS_OF_COLOURS && &is_marked($cell);
+ if $LOTS_OF_COLOURS && &is_selected($cell);
# Colour/highlight the cursors
attron($win, $Display_Has_Colour ? COLOR_PAIR(6) : A_UNDERLINE) if $number == 1;
@@ -1907,4 +2072,3 @@
#
# End.
#
-