# Exporting code/copying code/ code management

**URL:** <https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673>\
**Category:** Processing\
**Created:** [July 11, 2019, 6:04pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673 "2019-07-11T18:04:18Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [July 11, 2019, 6:04pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/1 "2019-07-11T18:04:18Z")

</div>

I like to use multiple tabs to organise my code in processing, and was wandering if there was a simple way to grab all the code and paste it anywhere else, without having to check through all the tabs.

Also is there a feature which I can enable which would enable me to close/open large brackets of code, most software allows this but processing ide does not seem to;

Thanks guys

---

<div class="post-metadata">

**Author:** ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)\
**Post date:** [July 11, 2019, 6:23pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/2 "2019-07-11T18:23:39Z")

</div>

The easiest way to bring all the code from the different tabs together (if they are pure Processing code) is to export your sketch. Then you can visit the exported folder, search for the .java file generated. Keep in mind that Processing can also handle .java files in its tab system. These Java files are not merged in the exporting process as they are considered top classes.

For folding text in the editor, I don’t think it is possible at the moment. It is a nice feature request.

I would like to add that there is a tab manager tool, in case this could be of any use for your current work flow.

Kf

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [July 11, 2019, 6:41pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/3 "2019-07-11T18:41:37Z")

</div>

Yes these features would be greatly appreciated…

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [July 12, 2019, 1:17am UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/4 "2019-07-12T01:17:58Z")

</div>

> [@paulgoux](#):
>
> use multiple tabs to organise my code in processing, and was wandering if there was a simple way to grab all the code and paste it anywhere else

but the  
/ File / Save As / [ctrl][shift][s]  
is exactly doing that?

* * *

a nice lite editor is GEANY  
[Marking code parts - #4 by kll](https://discourse.processing.org/t/marking-code-parts/6655/4) ,

i use in Raspberry Pi for python ( and processing )  
also for windows 7 ( about 100MB )

> **[Geany - Soft Famous](https://softfamous.com/geany/)**
>
> This is a small-size application designed with Integrated Development Environment (IDE) with unique features that act as a desktop environment. It usually runs in runtime libraries which is compatible with all Operating Systems. It is a tool which...

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [July 12, 2019, 10:16am UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/5 "2019-07-12T10:16:24Z")

</div>

I shall check out geany thanks, however the ctrl shift s, only save a copy of the project to a target location, it separates all tabs into there own entities.

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [July 12, 2019, 10:28am UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/6 "2019-07-12T10:28:56Z")

</div>

> [@paulgoux](#):
>
> it separates all tabs into there own entities.

well, they ARE, did you want to concat all .PDE and .JAVA files into one file?  
i see no use of that unless for the purpose

- to post it here at the forum as one CODE?
- backup more easy? ( Processing / Tools / Archive Sketch works well )

but with smarter editor ( color marking, folding …)  
no need to use multiple TAB / .PDE files.  
but with one file you might loose the modular structure / re-usability  
( of your classes and functions )  
but as long you think in / use the project structure ( directory / pde files… )  
both ways should be ok.

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [July 12, 2019, 10:41am UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/7 "2019-07-12T10:41:20Z")

</div>

hit the nail on the head with the first bullet point

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [July 13, 2019, 2:41pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/8 "2019-07-13T14:41:16Z")

</div>

Exporting was mentioned already…

There are occasions where my Processing application crashes and I did not do a recent save.

I look into the %temp% folder and can find the last \*.java file that Processing generated which is the same as an export (for working code). If I had a lot of tabs it is “a chore to restore”. 🙂

These \*.java and other files are also generated for every sketch and in the %temp% folder.

For example:

```auto
import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class XY_Perlin_00 extends PApplet {

//Perlin noise used to generate a line
//Gives a nice "warbling" effect

float xoff1, xoff2, xoff3;

public void setup()
  {
  
  }

public void draw()
  {
  background(220);
  stroke(102, 0, 230);  
  strokeWeight(10);
  
  translate(-40, 0);
  rotate(-TAU/128);
  scale(.8f, 1);
  float p = .019f;

// I see patterns here and could replace with a for loop:
  circle(300, height - 300 +20, .019f);
  circle(500, height - 500 +20, .020f);
  circle(700, height - 700 +20, .021f); 

  lineX(100, 100, 800);
  lineY(100, 100, 800);  
  lineXY(100, 100, 800); 
  }

public void circle(int x, int y, float rand)
  {
  for (float th = -TAU/20 +TAU/2; th < 3*TAU/2 + TAU/20; th += TAU/500)
    {
    xoff1 = xoff1 + rand;
    random(10);
    float r = 40 + 10*noise(xoff1);
// println(noise(xoff1));
    point( r*cos(th)+x, r*sin(th)+y);
    }
  }  
  
// These could be consolidated into one method and called from draw();  

public void lineX(int x1, int y1, int l)
  {
  for (float i = 0; i<l; i+=1)
    {
    xoff2 = xoff2 + .02f;
    point(i + x1, height - y1 + 10*noise(xoff2));
    }
  }  

public void lineY(int x1, int y1, int l)
  {
  for (float i = 0; i<l; i+=1)
    {
    xoff2 = xoff2 + .02f;
    point(x1 + 10*noise(xoff2), i + y1 + 10*noise(xoff2));
    }
  } 

public void lineXY(int x1, int y1, int l)
  {
  for (float i = 0; i<l; i+=1)
    {
    xoff3 = xoff3 + .02f;
    point(i + x1 + 10*noise(xoff3), height -i - y1 + 10*noise(xoff3));
    }
} 
  
  public void settings() { size(800, 1000, P2D); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "XY_Perlin_00" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

```

If comment the “extras” that were added it will run as Processing sketch:

```auto
//import processing.core.*; 
//import processing.data.*; 
//import processing.event.*; 
//import processing.opengl.*; 

//import java.util.HashMap; 
//import java.util.ArrayList; 
//import java.io.File; 
//import java.io.BufferedReader; 
//import java.io.PrintWriter; 
//import java.io.InputStream; 
//import java.io.OutputStream; 
//import java.io.IOException; 

//public class XY_Perlin_00 extends PApplet {

//Perlin noise used to generate a line
//Gives a nice "warbling" effect

float xoff1, xoff2, xoff3;

public void setup()
  {
  
  }

public void draw()
  {
  background(220);
  stroke(102, 0, 230);  
  strokeWeight(10);
  
  translate(-40, 0);
  rotate(-TAU/128);
  scale(.8f, 1);
  float p = .019f;

// I see patterns here and could replace with a for loop:
  circle(300, height - 300 +20, .019f);
  circle(500, height - 500 +20, .020f);
  circle(700, height - 700 +20, .021f); 

  lineX(100, 100, 800);
  lineY(100, 100, 800);  
  lineXY(100, 100, 800); 
  }

public void circle(int x, int y, float rand)
  {
  for (float th = -TAU/20 +TAU/2; th < 3*TAU/2 + TAU/20; th += TAU/500)
    {
    xoff1 = xoff1 + rand;
    random(10);
    float r = 40 + 10*noise(xoff1);
// println(noise(xoff1));
    point( r*cos(th)+x, r*sin(th)+y);
    }
  }  
  
// These could be consolidated into one method and called from draw();  

public void lineX(int x1, int y1, int l)
  {
  for (float i = 0; i<l; i+=1)
    {
    xoff2 = xoff2 + .02f;
    point(i + x1, height - y1 + 10*noise(xoff2));
    }
  }  

public void lineY(int x1, int y1, int l)
  {
  for (float i = 0; i<l; i+=1)
    {
    xoff2 = xoff2 + .02f;
    point(x1 + 10*noise(xoff2), i + y1 + 10*noise(xoff2));
    }
  } 

public void lineXY(int x1, int y1, int l)
  {
  for (float i = 0; i<l; i+=1)
    {
    xoff3 = xoff3 + .02f;
    point(i + x1 + 10*noise(xoff3), height -i - y1 + 10*noise(xoff3));
    }
} 
  
  public void settings() { size(800, 1000, P2D); }
// static public void main(String[] passedArgs) {
// String[] appletArgs = new String[] { "XY_Perlin_00" };
// if (passedArgs != null) {
// PApplet.main(concat(appletArgs, passedArgs));
// } else {
// PApplet.main(appletArgs);
// }
// }
//}

```

---

<div class="post-metadata">

**Author:** ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)\
**Post date:** [July 14, 2019, 5:42pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/9 "2019-07-14T17:42:25Z")

</div>

If you intention is to post all your code (which distributed in different tabs) here in the forum, my recommendation is not to do that. You will lose structure and it will make the code hard to read, hence less appealing for anyone o help. I can see two purpose for you to post all your code here: you are looking for help or you are sharing your work. For the former, you should provide a [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) instead of providing all the code.

In any case, a better alternative for your case would be to post your code in an online repo like github. Anybody will be able to check your code directly in github and then could clone it into their local machine to run it. This is the best option as this would keep the integrity of your code structure and this will guarantee to run in any PDE.

Kf

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [July 15, 2019, 3:32pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/10 "2019-07-15T15:32:22Z")

</div>

> [@kfrajer](#):
>
> For folding text in the editor

Just mentioning that has been requested for over a decade, and is almost certainly not happening.

Concating your sketch files seems like a reasonable thing to want sometimes. It could be a simple script / droplet. What OS are you on?

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [July 15, 2019, 7:47pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/11 "2019-07-15T19:47:39Z")

</div>

Strange that a basic feature in almost all text-editors has been left out by choice, it however impedes code organisation, as it means I have to look elsewhere if my code is going to be lengthy . Geany seems to be the answer here though that does not resolve concatenation. I am currently using windows 10.

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [July 15, 2019, 7:58pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/12 "2019-07-15T19:58:00Z")

</div>

Thanks for all your replies, Geany appears to do everything I want a and try and make a script for concatenation there also appears to be a [atom.io](http://atom.io) alternative, which is perfect as its currently my go to editor. Also there appears to be possibilities using visual studio.

> **[A hackable text editor for the 21st Century](https://atom.io/)**
>
> At GitHub, we’re building the text editor we’ve always wanted: hackable to the core, but approachable on the first day without ever touching a config file. We can’t wait to see what you build with it.

  

> **[r/processing - Unable to use processing with Atom or Visual studio code.](https://www.reddit.com/r/processing/comments/79qh55/unable_to_use_processing_with_atom_or_visual/)**
>
> 1 vote and 2 comments so far on Reddit

> **[A hackable text editor for the 21st Century](https://atom.io/packages/search?q=processing)**
>
> At GitHub, we’re building the text editor we’ve always wanted: hackable to the core, but approachable on the first day without ever touching a config file. We can’t wait to see what you build with it.

visual studio

> **[Processing 2.x and 3.x Forum](https://forum.processing.org/two/discussion/20239/visual-studio-code-for-processing-and-p5)**
>
> Processing is an electronic sketchbook, a language and a worldwide community. This is its forum.

[https://marketplace.visualstudio.com/items?itemName=Tobiah.language-pde](https://marketplace.visualstudio.com/items?itemName=Tobiah.language-pde)

Seems there are plenty of alternatives.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [July 15, 2019, 9:40pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/13 "2019-07-15T21:40:24Z")

</div>

here is a sketch that joins pde files and saves as txt file

```auto
// JOIN all pde in a folder

// user selects folder

// **************************************************************
// alter these values:
boolean CHECK_ONLY_FILES_CONTAINING = true; // we can search for a certain file type only e.g. ".pde"
String ALLOWED_ENDING = ".pde"; // e.g. ".pde" when CHECK_ONLY_FILES_CONTAINING = true 
// **************************************************************

//
//states 
final int stateWaitForFolder = 0; // consts  
final int stateDone = 1;
final int stateBreak = 2;  
int state = stateWaitForFolder; // current

String folderGlobal = "";  

boolean firstTime=true; 

// result 
String[] temp2 = {}; 

void setup() {
  size (1100, 700); 
  background(111);
  selectFolder("Select a folder to join pdes (Cancel to abort).", 
    "folderSelected");
}

void draw() {
  // 
  switch (state) {

  case stateWaitForFolder:
    // waiting until folder has been selected
    background(111);
    text("Please choose a folder. Hit Cancel to abort.", 
      33, 33);    

    // THE WAIT IS OVER 
    if (!folderGlobal.equals("")) {
      searchFolder( folderGlobal); 
      println("");
    } // if 
    break;

  case stateDone:
    background(111);
    text("DONE: " + folderGlobal, 
      33, 33);
    showButtons();
    if (firstTime) {
      firstTime=false;
    }
    break;

  case stateBreak:
    background(111);
    text("Window was closed or the user hit cancel.", 33, 33); 
    showButtons(); 
    break; 

  default:
    // error
    println ("error 91"); 
    exit();
    break;
    //
  } // switch
} // func 

// -----------------------------------------------------------------------------

void searchFolder(String folderLocal) {
  //  
  // println (folderLocal);

  String[] strList;

  // https://docs.oracle.com/javase/7/docs/api/java/io/File.html 

  File f = dataFile(folderLocal); 
  strList = f.list();
  if (strList!=null) {
    println ("files in total: " + strList.length);
    int i = 0;
    for (File f1 : f.listFiles()) {
      if (f1.isFile()) {
        // is a file 
        if ( checkFileName(f1.getName()) ) {
          // is pde 
          String[] temp1 = loadStrings(f1.getAbsolutePath());
          temp2 = (String[]) concat ( temp2, temp1 ) ;
        }
      }
    } // for

    println("");
    saveStrings("r"+timeStamp()+".txt", temp2); 
    state = stateDone; // next state
  }//if
}//func

boolean checkFileName(String fileName) {
  // depending on CHECK_ONLY_FILES_CONTAINING it returns true or it returns whether the file name contains a file ending ALLOWED_ENDING
  if (CHECK_ONLY_FILES_CONTAINING)
    return fileName.contains(ALLOWED_ENDING); 
  else 
  return true;
}//func 

// -----------------------------------------------------------------
// file handling 

void folderSelected(File selection) {
  // the 'callback' function.
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
    state=stateBreak;
  } else {
    println("User selected " + selection.getAbsolutePath());
    folderGlobal = selection.getAbsolutePath();
  } // else
}//func 

// ----------------------------------------------------------------
// Input 

void mousePressed() {
  if (state==stateDone||state==stateBreak) {
    if (dist(mouseX, mouseY, 133, 133) < 66) {
      // reset / restart
      folderGlobal=""; 
      selectFolder("Select a folder to rename files (Cancel to abort):", 
        "folderSelected");
      state=stateWaitForFolder;
    }//if
    else if (dist(mouseX, mouseY, 233, 133) < 66) {
      exit();
    }//else if
  }//if
}//func 

//-------------------------------------------------------------------
//Tools

void showButtons() {
  // set mode for text and rect 
  textAlign(CENTER, CENTER);
  rectMode(CENTER);

  // rects 
  noFill();  
  rect(133-5, 133+3, 84, 23);
  rect(233-1, 133+3, 84, 23);

  // text 
  fill(255); 
  text ( "Next folder", 133, 133);
  text ( "Quit", 233, 133);

  // reset 
  textAlign(LEFT);
  rectMode(CORNER); // The default mode is rectMode(CORNER)
}//func 

//-------------------------------------------------------------------

String timeStamp() {
  return todaysDate () 
    + "_" 
    + timeNow () ;
}

String todaysDate () {

  int d = day(); // Values from 1 - 31
  int m = month(); // Values from 1 - 12
  int y = year(); // 2003, 2004, 2005, etc.

  String Result = 
    nf(y, 2)+
    nf(m, 2)+
    nf(d, 2); 
  return( Result );
}

String timeNow () {

  int h = hour(); // Values from 1 - 23
  int m = minute(); // Values from 1 - 60
  int s = second(); // 1-60

  String Result = nf(h, 2) + "" + 
    nf(m, 2) + "" + 
    nf(s, 2); 
  return( Result );
}
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [July 16, 2019, 1:16pm UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/14 "2019-07-16T13:16:32Z")

</div>

new version

- with a line of ` **************** ` between the single pde-files and
- the main file (pde with setup and draw that has the same name as the folder) **is listed first**.
- Starts notepad with the resulting file.

Chrisir

```auto
// JOIN all pde in a folder

// user selects folder

// **************************************************************
// alter these values:
boolean CHECK_ONLY_FILES_CONTAINING = true; // we can search for a certain file type only e.g. ".pde"
String ALLOWED_ENDING = ".pde"; // e.g. ".pde" when CHECK_ONLY_FILES_CONTAINING = true 
// **************************************************************

//
//states 
final int stateWaitForFolder = 0; // consts  
final int stateDone = 1;
final int stateBreak = 2;  
int state = stateWaitForFolder; // current

String folderGlobal = "";  

final String stars = " ********************************************************************************";

int linesInTotal=0; 

// result 
String[] resultingStringArray = {}; 

String FileWithFolderName=""; 

// ------------------------------------------------------------

void setup() {
  size (1100, 700); 
  background(111);
  selectFolder("Select a folder to join pdes (Cancel to abort).", 
    "folderSelected");
}

void draw() {
  // 
  switch (state) {

  case stateWaitForFolder:
    // waiting until folder has been selected
    background(111);
    text("Please choose a folder. Hit Cancel to abort.", 
      33, 33);    

    // THE WAIT IS OVER 
    if (!folderGlobal.equals("")) {
      searchFolder( folderGlobal); 
      println("");
    } // if 
    break;

  case stateDone:
    background(111);
    text("DONE: " + folderGlobal, 
      33, 33);
    showButtons();
    break;

  case stateBreak:
    background(111);
    text("Window was closed or the user hit cancel.", 33, 33); 
    showButtons(); 
    break; 

  default:
    // error
    println ("error 91"); 
    exit();
    break;
    //
  } // switch
} // func 

// -----------------------------------------------------------------------------

void searchFolder(String folderLocal) {
  //  
  // println (folderLocal);

  String[] strList;

  // https://docs.oracle.com/javase/7/docs/api/java/io/File.html 

  resultingStringArray = new String[0]; 
  resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;
  resultingStringArray = (String[]) append ( resultingStringArray, "// "+stars ) ;
  resultingStringArray = (String[]) append ( resultingStringArray, "// joined pde-file of folder " + folderLocal ) ;
  resultingStringArray = (String[]) append ( resultingStringArray, "// "+stars ) ;
  resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;

  // first handle only the file which name is the name of the folder (in processing that's the main file)
  findFileWithFolderName(folderLocal);

  File f = dataFile(folderLocal); 
  strList = f.list();
  if (strList!=null) {
    println ("files in total: " + strList.length);
    int i = 0;
    for (File f1 : f.listFiles()) {
      if (f1.isFile()) {
        // is a file 
        if ( checkFileName(f1.getName()) && !FileWithFolderName.equals(f1.getName()) ) {
          // is pde 

          // write intro for that file / tab 
          resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;
          resultingStringArray = (String[]) append ( resultingStringArray, "// "+stars ) ;
          resultingStringArray = (String[]) append ( resultingStringArray, "// tab: " + f1.getName() ) ;
          resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;

          // write content
          String[] temp1 = loadStrings(f1.getAbsolutePath());
          linesInTotal += temp1.length; 
          resultingStringArray = (String[]) concat ( resultingStringArray, temp1 ) ;
        }
      }
    } // for

    resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;
    resultingStringArray = (String[]) append ( resultingStringArray, "// End of joined file. "+stars ) ;
    resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;
    //println("");
    println("Lines in total: "
      +linesInTotal);
    String fileNameTarget="result"+timeStamp()+".txt";
    saveStrings(fileNameTarget, 
      resultingStringArray);

    // open  
    openInNotepad(sketchPath("")+fileNameTarget); 

    state = stateDone; // next state
  }//if
}//func

void findFileWithFolderName(String folderLocal) {

  // first handle only the file which name is the name of the folder (in processing that's the main file)

  String[] strList;

  File f = dataFile(folderLocal); 
  strList = f.list();
  if (strList!=null) {
    println ("files in total: " + strList.length);
    int i = 0;
    for (File f1 : f.listFiles()) {
      if (f1.isFile()) {
        // is a file 
        if ( checkFileName(f1.getName()) && f1.getName().equals(f.getName()+ALLOWED_ENDING) ) {
          // is pde 

          println("findFileWithFolderName says "
            + f1.getName());

          // write intro for that file / tab
          resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;
          resultingStringArray = (String[]) append ( resultingStringArray, "// "+stars ) ;
          resultingStringArray = (String[]) append ( resultingStringArray, "// tab: " + f1.getName() +" main file (file name is folder name)") ;
          resultingStringArray = (String[]) append ( resultingStringArray, "" ) ;

          // write content
          String[] temp1 = loadStrings(f1.getAbsolutePath());
          linesInTotal = temp1.length; 
          resultingStringArray = (String[]) concat ( resultingStringArray, temp1 ) ;

          // store name of the FileWithFolderName globally and leave here
          FileWithFolderName = f1.getName(); 
          return;
        }
      }
    } // for
  }
}

boolean checkFileName(String fileName) {
  // depending on CHECK_ONLY_FILES_CONTAINING it returns true or it returns whether the file name contains a file ending ALLOWED_ENDING
  if (CHECK_ONLY_FILES_CONTAINING)
    return fileName.contains(ALLOWED_ENDING); 
  else 
  return true;
}//func 

// -----------------------------------------------------------------
// file handling 

void folderSelected(File selection) {
  // the 'callback' function.
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
    state=stateBreak;
  } else {
    println("User selected " + selection.getAbsolutePath());
    folderGlobal = selection.getAbsolutePath();
  } // else
}//func 

// ----------------------------------------------------------------
// Input 

void mousePressed() {
  if (state==stateDone||state==stateBreak) {
    if (dist(mouseX, mouseY, 133, 133) < 66) {
      // reset / restart
      folderGlobal=""; 
      FileWithFolderName=""; 
      linesInTotal=0; 
      resultingStringArray = null;
      selectFolder("Select a folder to rename files (Cancel to abort):", 
        "folderSelected");
      state=stateWaitForFolder;
    }//if
    else if (dist(mouseX, mouseY, 233, 133) < 66) {
      exit();
    }//else if
  }//if
}//func 

//-------------------------------------------------------------------
//Tools

void showButtons() {
  // set mode for text and rect 
  textAlign(CENTER, CENTER);
  rectMode(CENTER);

  // rects 
  noFill();  
  rect(133-5, 133+3, 84, 23);
  rect(233-1, 133+3, 84, 23);

  // text 
  fill(255); 
  text ( "Next folder", 133, 133);
  text ( "Quit", 233, 133);

  // reset 
  textAlign(LEFT);
  rectMode(CORNER); // The default mode is rectMode(CORNER)
}//func 

//-------------------------------------------------------------------

String timeStamp() {
  return todaysDate () 
    + "_" 
    + timeNow () ;
}

String todaysDate () {

  int d = day(); // Values from 1 - 31
  int m = month(); // Values from 1 - 12
  int y = year(); // 2003, 2004, 2005, etc.

  String Result = 
    nf(y, 2)+
    nf(m, 2)+
    nf(d, 2); 
  return( Result );
}

String timeNow () {

  int h = hour(); // Values from 1 - 23
  int m = minute(); // Values from 1 - 60
  int s = second(); // 1-60

  String Result = nf(h, 2) + "" + 
    nf(m, 2) + "" + 
    nf(s, 2); 
  return( Result );
}

// ---------------------------------------------------------
// open in notepad

void openInNotepad(String currentFile) {
  // open in notepad

  if (currentFile.equals("")) {
    //return; // leave here (not necessary)
  }

  try
  {
    ProcessBuilder pb = new ProcessBuilder("notepad.exe", currentFile);
    Process p = pb.start();
  }
  catch ( Exception /* IOException, URISyntaxException */ e )
  {
    e.printStackTrace();
  }//catch
}
//

```

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [July 19, 2019, 11:02am UTC](https://discourse.processing.org/t/exporting-code-copying-code-code-management/12673/15 "2019-07-19T11:02:54Z")

</div>

I have decided to stick with [atom.io](http://atom.io) as it currently does everything that I need it to do. You can still have multiple tabs or sketch files in one project folder if so desired. However this was mainly to counter the issue of bracket folding.

for the language

> **[processing-language](https://atom.io/packages/processing-language)**
>
> Add syntax highlighting and snippets to Processing (.pde) files in Atom.

for syntax management

> **[A hackable text editor for the 21st Century](https://atom.io/themes/search?utf8=%25E2%259C%2593&q=keyword%3Apde)**
>
> At GitHub, we’re building the text editor we’ve always wanted: hackable to the core, but approachable on the first day without ever touching a config file. We can’t wait to see what you build with it.

just add your processing install folder to the “path” variables in your system config, and your good to go, press ctrl + alt + b to start the processing sketch. Its that easy.
