@@ -821,6 +821,17 @@ protected JMenu buildEditMenu() {
821
821
editMenuUpdatable .add (action );
822
822
menu .add (item );
823
823
824
+ item = new JMenuItem ("Move Selected Lines Up" );
825
+ item .setAccelerator (KeyStroke .getKeyStroke (KeyEvent .VK_UP , InputEvent .ALT_DOWN_MASK ));
826
+ item .addActionListener (e -> handleMoveLines (true ));
827
+ menu .add (item );
828
+
829
+ item = new JMenuItem ("Move Selected Lines Down" );
830
+ item .setAccelerator (KeyStroke .getKeyStroke (KeyEvent .VK_DOWN , InputEvent .ALT_DOWN_MASK ));
831
+ item .addActionListener (e -> handleMoveLines (false ));
832
+ menu .add (item );
833
+
834
+
824
835
// Update copy/cut state on selection/de-selection
825
836
menu .addMenuListener (new MenuListener () {
826
837
// UndoAction and RedoAction do this for themselves.
@@ -1865,6 +1876,7 @@ protected void handleCommentUncomment() {
1865
1876
}
1866
1877
1867
1878
1879
+
1868
1880
public void handleIndent () {
1869
1881
handleIndentOutdent (true );
1870
1882
}
@@ -1918,6 +1930,84 @@ public void handleIndentOutdent(boolean indent) {
1918
1930
stopCompoundEdit ();
1919
1931
sketch .setModified (true );
1920
1932
}
1933
+ /**
1934
+ * Moves the selected lines up or down in the text editor.
1935
+ *
1936
+ * <p>If {@code moveUp} is true, the selected lines are moved up. If false, they move down.</p>
1937
+ * <p>This method ensures proper selection updates and handles edge cases like moving
1938
+ * the first or last line.</p>
1939
+ *
1940
+ * @param moveUp {@code true} to move the selection up, {@code false} to move it down.
1941
+ */
1942
+ public void handleMoveLines (boolean moveUp ) {
1943
+ startCompoundEdit ();
1944
+
1945
+ int startLine = textarea .getSelectionStartLine ();
1946
+ int stopLine = textarea .getSelectionStopLine ();
1947
+
1948
+ // Adjust selection if the last line isn't fully selected
1949
+ if (startLine != stopLine &&
1950
+ textarea .getSelectionStop () == textarea .getLineStartOffset (stopLine )) {
1951
+ stopLine --;
1952
+ }
1953
+
1954
+ int replacedLine = moveUp ? startLine - 1 : stopLine + 1 ;
1955
+ if (replacedLine < 0 || replacedLine >= textarea .getLineCount ()) {
1956
+ stopCompoundEdit ();
1957
+ return ;
1958
+ }
1959
+
1960
+ final String source = textarea .getText (); // Get full text from textarea
1961
+
1962
+ int replaceStart = textarea .getLineStartOffset (replacedLine );
1963
+ int replaceEnd = textarea .getLineStopOffset (replacedLine );
1964
+ if (replaceEnd > source .length ()) {
1965
+ replaceEnd = source .length ();
1966
+ }
1967
+
1968
+ int selectionStart = textarea .getLineStartOffset (startLine );
1969
+ int selectionEnd = textarea .getLineStopOffset (stopLine );
1970
+ if (selectionEnd > source .length ()) {
1971
+ selectionEnd = source .length ();
1972
+ }
1973
+
1974
+ String replacedText = source .substring (replaceStart , replaceEnd );
1975
+ String selectedText = source .substring (selectionStart , selectionEnd );
1976
+
1977
+ if (replacedLine == textarea .getLineCount () - 1 ) {
1978
+ replacedText += "\n " ;
1979
+ selectedText = selectedText .substring (0 , Math .max (0 , selectedText .length () - 1 ));
1980
+ } else if (stopLine == textarea .getLineCount () - 1 ) {
1981
+ selectedText += "\n " ;
1982
+ replacedText = replacedText .substring (0 , Math .max (0 , replacedText .length () - 1 ));
1983
+ }
1984
+
1985
+ int newSelectionStart , newSelectionEnd ;
1986
+ if (moveUp ) {
1987
+ textarea .select (selectionStart , selectionEnd );
1988
+ textarea .setSelectedText (replacedText ); // Use setSelectedText()
1989
+
1990
+ textarea .select (replaceStart , replaceEnd );
1991
+ textarea .setSelectedText (selectedText );
1992
+
1993
+ newSelectionStart = textarea .getLineStartOffset (startLine - 1 );
1994
+ newSelectionEnd = textarea .getLineStopOffset (stopLine - 1 );
1995
+ } else {
1996
+ textarea .select (replaceStart , replaceEnd );
1997
+ textarea .setSelectedText (selectedText );
1998
+
1999
+ textarea .select (selectionStart , selectionEnd );
2000
+ textarea .setSelectedText (replacedText );
2001
+
2002
+ newSelectionStart = textarea .getLineStartOffset (startLine + 1 );
2003
+ newSelectionEnd = stopLine + 1 < textarea .getLineCount ()
2004
+ ? Math .min (textarea .getLineStopOffset (stopLine + 1 ), source .length ())
2005
+ : textarea .getLineStopOffset (stopLine ); // Prevent out-of-bounds
2006
+ }
2007
+
2008
+ textarea .select (newSelectionStart , newSelectionEnd );
2009
+ stopCompoundEdit ();
2010
+ }
1921
2011
1922
2012
1923
2013
static public boolean checkParen (char [] array , int index , int stop ) {
0 commit comments