Termux on Android, for a Linux command line on your smartphone, for a 'killer app' to-do list
I'm going to cover this to-do list thing in a little more detail, so as to make an easier on-ramp for people who are entirely new to the Linux command line. I really think that this is an excellent implementation of a to-do list, and is now *very* useful due to the portability of everyday smartphones.
The Termux app is installable like any other, and immediately gives the user a Linux command line prompt upon launching the app. Everything covered here can be done in this environment, with only a couple of quick and easy installs of software for Linux -- tiny command-line programs that add to the overall functionality of the 'shell', as the command line is called.
Depending on how serious one wants to get about this approach to a portable computerized to-do list, one can optionally add on a couple of useful accessories that will turn your phone into a small but capable command line computer terminal, and possibly further.
For a more 'desktop' feel, one can get a mini tripod for the phone, and a small 'HTPC' external Bluetooth keyboard and trackpad -- I have the kind where the trackpad is at the top-middle, with the mini-keyboard below it. Make sure that it's a *Bluetooth* device, and not the '2.4 Ghz' kind, which is actually a wireless *USB* connection, requiring a USB dongle to be plugged into a USB port, which smartphones typically do *not* have. For that matter, one could also use a full-size Bluetooth keyboard, for a regular typing experience into the phone, if desired, and any other Bluetooth input devices, like a mouse, trackpad, or trackball, as well.
AnLinux says that you can run a graphical user interface (GUI) on top of an OS install (like Ubuntu), but I haven't tried this myself. Any OS install (like Ubuntu) is *optional* for the purposes of this tutorial, since the regular Termux ('rootkit') install is sufficient for the simple commands / software used for this to-do list approach.
I previously mentioned actually *rendering* 3D graphics scenes with Sunflow, requiring a Java install, which, as far as I can see, *isn't* possible with just the Termux rootkit -- I went ahead and installed Ubuntu, according to the directions from the AnLinux app, and was then able to install a standard OpenJDK version of Java into the Ubuntu environment.
You're going to have to move files around various filesystems since the Termux filesystem is *separate* from the existing Android internal storage -- though can be *linked* -- and is also separate from any microSD 'external' SD card / drive that you may have added to the phone.
I recommend the free 'ES File Explorer' app for Android-side file management.
Termux-sided file management requires knowing how to use a few basic Linux commands, which I'll be covering here.
The very first thing to do is to get that filesystem *link* between the Termux filesystem, and your existing Android 'internal' drive so that you can pass files back and forth as needed.
It is necessary to grant storage permission for Termux on Android 6 and higher. Use 'Settings>Apps>Termux>Permissions>Storage' and set to true.
Then use the 'termux-setup-storage' command.
If you go on to install a full Linux-type OS like Ubuntu, a 'ubuntu-fs' directory will be created in the 'storage' directory, in the Termux 'home' directory -- ~/storage/ubuntu-fs/root -- and files can be transferred to and from the Ubuntu environment through this directory, and also through to the Android 'Download' folder -- ~/storage/downloads being the Linux filepath.
As you can see, the tilde character, ~, is synonymous with the 'home' directory, which Termux defaults to.
One can switch over to the 'home' directory by *changing the directory*, 'cd', to home, '~' -- the command 'cd ~'.
You can *verify* that you're in the home directory by using the 'pwd' -- 'print working directory' -- command.
Likewise, you can change-directory to any of the *other* directories by 'cd'-ing to *those* locations: 'cd ~/storage/downloads', or 'cd ~/storage/ubuntu-fs/root' (without the single quotation marks), if you've installed Ubuntu.
The entire 'filesystem' is hierarchically ordered in this way, with folders inside of 'higher' folders, all the way up to '/', the first slash on any given filepath, which is considered to be 'root', though there's often a separate, different folder explicitly called 'root', as with the example of '~/storage/ubuntu-fs/root'. You can 'cd' to anywhere you like in the filesystem, using 'cd foldername', 'cd /path/to/folder', or 'cd ..' (two periods) to go 'up' a level in the hierarchy. Use 'pwd' anytime to get the full filepath of where you happen to be located in the hierarchy.
Perks of the command line
Along the way you may find that you're using a particular command *repeatedly* -- there's a shortcut with using the command line. Just use the 'up arrow' on the keyboard, or '↑' on the middle-right edge of the Termux window, just above the screen keyboard. Each press of the up-arrow will bring up past commands used, from recent to distant. One may also *edit* any past command, once reproduced, and then press Enter to use that command as it appears. Pro tip: Do a search over *all* past commands by referring to the entire history of commands that's stored by the operating system: cat ~/.bash_history | grep mysearchterm
Use 'ls' to *list* out the folders and files that are in the location that you're currently at. Then 'cd foldername' to change your directory to that of any folder listed. Files can't be 'cd'-ed to -- but they can be *read*, and edited. Try the cat command, 'cat filename', to *concatenate*, or *read*, the contents of any given file -- not folders. Missed it because the contents were too lengthy and most of it just scrolled up, past the viewable screen? For any given output to the screen, like that from the 'cat' command, you can 'pipe' the output to *another* command, called 'more', so as to *page* the contents, screenful-by-screenful, using the space bar. (Or line-by-line, using the Return key.) The command is then: cat filename | more
Note that the shortcut to the 'home' directory, '~', is shorthand for the full filepath of '/home/user', typically, though in this Termux rootkit installation the home directory is actually '/data/data/com.termux/files/home'.
If any given filepath feels to be too *long* in length, and unwieldy, having to type it over and over again, one can use *symlinks* to *shorten* the name needed to specify a filepath, as for commands to change to that directory, and for moving files to and from that directory.
For example, I changed to the home directory and used the 'ln -s ~/storage/downloads internal' command to specify ~/internal as being equivalent to ~/storage/downloads. (I also did 'ln -s ~/storage/ubuntu-fs/root linux', to specify ~/linux as equivalent to ~/storage/ubuntu-fs/root.)
Okay, hopefully you're a little more comfortable with how the Linux filesystem works, and how to move around in it. We can get to installing additional (command-line) software that's critical to making the 'to-do' implementation work.
In Termux the install command is 'pkg install packagename', though in Ubuntu it's 'apt install packagename'.
I'm going to recommend installing two packages, 'nano', and 'bc', plus three additional optional packages, for *compressing* folders and files into a compressed 'zip' file, for archiving and long-term file storage -- as into the Android 'Downloads' directory and beyond.
So first get online and update the software packages repository with 'pkg update', then execute the command 'pkg install nano', then 'pkg install bc' -- or one could do both with the single command, 'pkg install nano bc'.
Nano is a terminal-based *text* editor, and it works similarly to any basic text editor you may have used before elsewhere. Note that the key combination of CONTROL-S may be used to *save* your text file at any given moment, to the filename specified when you first started nano, like 'nano 210317_to-do'.
CONTROL-X is used to *exit* nano, and if you haven't already saved your text file at that point you'll be prompted to do so before nano exits. Also, CONTROL-C is generally used as a *break*, or *interrupt*, for any given process that one would like to arbitrarily stop, immediately.
'Bc' is a 'basic calculator' that does math the way one would *expect* it to -- the Linux shell itself is limited to *integers*, unfortunately, so invoking / using bc is a must, most of the time.
Compare the output from 'echo $((13 / 3))', to 'echo "scale=8; 13 / 3" | bc -l'. ('Echo' means 'print to the screen'.)
So, to wrap up, let's do a quick sample 'to-do' scenario, using everything covered so far....
At the Termux shell prompt ('$') do the command 'nano 2103xx_to-do'.
In this case I'm using 'xx' instead of the two numbers for the date of the month. After this example you can always *repurpose* this text file as a *template*, for your own needs.
In the nano text editor window go ahead and type in:
210317 210316 [ ] install Termux on my Android smartphone [PERSONAL] [PROJECT] [TO-DO] 
210317 [ ] read through the 'to-do' tutorial a second time [TO-DO] 
210317 [ ] do a search for the Linux 'copy' command [TO-DO] 
When you're done, do CONTROL-S to save the file to its filename, '2103xx_to-do'. Then do CONTROL-X to exit nano.
Now the fun begins -- by including those to-do item 'tags' (in the brackets), you've enabled a way to *group* several items together, potentially over dozens, hundreds, and thousands of items, by whatever tags you use, arbitrarily, across *all* item entries / lines, and even across multiples files, if you want.
So, for the 3 items in the text file you just created, try using the following command: 'cat 2103xx_to-do | grep 210316'.
Underwhelming, right? All you get from that command is the first line in the text file, which happens to have the search term, '210316', in it. But consider that, over time, you may be entering *several* to-do items into your file, and, after a few months, the number of entries will add up to *many*, and you may want to look back to a certain date like Tuesday, March 16, 2021. Months from now that date, or any other, may have several entries, and maybe you want to find all of the entries for the whole month of March -- try just using the YYMM part: 'cat 2103xx_to-do | grep 2103'.
Now you get all three entries, because all three are from March. Need to narrow it down some more? You can *chain* more searches together, by putting grep commands in *series*, like this: 'cat 2103xx_to-do | grep 2103 | grep Termux'. If you wanted to do two or more searches *in parallel*, then the command would be: 'cat 2103xx_to-do | grep -e 2103 -e Termux', meaning that you're looking for all entries that either contain '2103' *or* 'Termux' (or both). The *former* command reads as 'Search the 2103xx_to-do file for any lines that contain '2103', and, of those matches, search for any lines that contain the term 'Termux'.
I included the tag 'TO-DO' as a *project name*, so all three of these entries happen to be a part of this 'TO-DO' project, with the main project *item* having the additional designation of '[PROJECT]'. (So if you had several projects going on simultaneously you could find the project description of all of them just by doing a 'grep' for 'PROJECT'.
Finally, I also included a *priority* ranking for each item, in brackets, so one could start the day by searching all items / lines by *priority*, starting with '', then '', '', etc., to get to the most important items across all projects -- use 'fgrep' instead of 'grep' anytime you're searching for terms that include brackets.
As I mentioned in a previous post the '[ ]' part works like a *checkbox*, so that once an item is completed, a checkmark, '✓', may be inserted in there between the two spaces. For quasi-completed or irregularly-ended items I myself use a 'bullet' character, '•', and may just carry the item forward, into a *new* item, if appropriate. Canceled items get a forward slash, '\'.
This means that one could 'fgrep' according to *status*, for *uncompleted* items ('[ ]'), for *finished* items ('•'), or for *cancelled* items ('\') -- use: fgrep \\ Combining grep commands, in series or in parallel, would yield sophisticated searches with more precise meanings, such as 'all the completed or finished items from all projects from February'. Can you create a cat and grep command that does this specific search?
Unwitting database administration
A final technique here puts the user at the edge of handling *relational databases*, but without having to learn any database language, or even having to start up a spreadsheet -- the command is the modest 'cut' command, which serves to treat each and every line in your text file as a potential *database entry*, for further processing.
For example, let's say that I wanted to pass along the items that I did, to someone else in an email, to let them know what I happen to be working on. I *could* just copy-and-paste the lines from the text file (after being 'cat'-ed to the screen), but they have all of that particular 'to-do' stuff around the actual descriptions, and I just want the descriptions themselves.
We can treat these lines according to *any* character on the lines that serves to *break up sections* of a line into separate parts, the way that *columns* do naturally, in an actual spreadsheet. In this case I see *two* characters that could be used to programmatically isolate just the description part: ']', and '[' (closed-bracket, and open-bracket).
And here's the command: cat 2103xx_to-do | cut -d']' -f2 | cut -d'[' -f1.
What this is saying is 'Concatenate (read) the 2103xx_to-do file, and for every line look for the closed-bracket character, and use that character as a *delimiter* (divider) in the line of text, and return just the *2nd* 'field' (everything after the first ']' but before the second ']'). Since this command actually returns *too* much -- it includes the open-bracket after the description and the first tag name -- we have to use a *second* command after the first 'cut' command, to trim a little further: cut -d'[' -f1
What *this* part is saying is 'Take the output from the cat and the first cut command, and then look for all of the open-bracket characters that may be there -- use the first found open-bracket character as a *divider* (delimiter) for that text, and return the *first* 'field' -- field #1 -- from that text.
In this case 'field #1' happens to be the description itself, without any closed-brackets (stripped out with the first cut command), and without any open-brackets (stripped out with the *second* cut command), and focused on just the description part itself.
Unfortunately we're still picking up the incidental *spaces* at the beginning and end of each line, so if we wanted to be *really* fastidious we might add extra commands to do just that -- appending 'cut -c2- | rev | cut -c2- | rev', perhaps, as a way to do that. (The command says 'Cut from character #2 onward, then *reverse* the entire line to be *backwards*, and cut from the second character onwards of *that* (the actual *last* character), then reverse the line back to normal.')
In my initial post I outlined a particular *protocol* for this implementation of a to-do list, that of *copying* yesterday's to-do file, to make a copy of it for *today*, for editing. For today's date this would be: cp 210316_to-do 210317_to-do
One can then edit for *today's* date while leaving all past versions intact, for historical archiving. If one ever needs to *move* a file, without copying, or *rename* a file, the 'move' command is used for those functions, as with: mv ~/storage/downloads/incomingfile.txt ~
This reads as 'In the home folder, in the storage folder, in the downloads folder there is a file called 'incomingfile.txt' -- take that file and *move* it -- don't *copy* it -- to the home directory.'
To *rename* a file -- if I made a mistake and first did an incorrect 'copy' command: cp 210316_to-do 210318_to-do
...I could then use the 'move' command to *rename* the new file that I incorrectly named: mv 210318_to-do 210317_to-do
For *any* given command, help is always available -- just issue the command with the '-h' or '--help' flag following it, like this: mv --help
I'll end with the topic of *zipping* folders and files into a compressed *zip* file -- I'd suggest installing 'zip', 'unzip', and 'p7zip' -- pkg install zip unzip p7zip
These commands are handy for handling zip files, and they all work in slightly different ways, with '7z' being the most powerful and arguably easiest to use.
To *zip* a folder, files, or combination of folders and files, just *add* those items in your '7z' command: 7z a 210317_downloads.zip ~/storage/downloads
To *list* the items in an archive try: unzip -l archivename.zip | more
To *unzip* items from an archive, try: unzip archivename.zip