123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- //Target:Winform
- //RefNuGet:jacobslusser.ScintillaNET,3.5.6
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Windows.Forms;
- using ScintillaNET;
- [assembly: AssemblyProduct("Filename Vertical Editor")]
- [assembly: AssemblyTitle("Edit multi file name at one time")]
- [assembly: AssemblyCopyright("Copyright © V 2016")]
- [assembly: AssemblyVersion("1.0.0.0")]
- [assembly: AssemblyFileVersion("1.0.0.0")]
- [assembly: Guid("C7102B4E-858D-470B-A3FB-630FC730EC7E")] //for ILRepack of ScintillaNET
- namespace FilenameVerticalEditor
- {
- internal class FilesNameComparer : IComparer<string>
- {
- //from http://www.cnblogs.com/linyechengwei/p/3224200.html with modify
- public int Compare(string x, string y)
- {
- var arr1 = x.Normalize(NormalizationForm.FormKC).ToCharArray();
- var arr2 = y.Normalize(NormalizationForm.FormKC).ToCharArray();
- int i = 0, j = 0;
- while (i < arr1.Length && j < arr2.Length)
- {
- if (char.IsDigit(arr1[i]) && char.IsDigit(arr2[j]))
- {
- string s1 = "", s2 = "";
- while (i < arr1.Length && char.IsDigit(arr1[i]))
- {
- s1 += arr1[i];
- i++;
- }
- while (j < arr2.Length && char.IsDigit(arr2[j]))
- {
- s2 += arr2[j];
- j++;
- }
- int a, b;
- // ReSharper disable RedundantAssignment
- var ca = int.TryParse(s1, out a);
- Debug.Assert(ca);
- var cb = int.TryParse(s2, out b);
- Debug.Assert(cb);
- // ReSharper restore RedundantAssignment
- if (a > b)
- {
- return 1;
- }
- if (a < b)
- {
- return -1;
- }
- }
- else
- {
- if (arr1[i] > arr2[j])
- {
- return 1;
- }
- if (arr1[i] < arr2[j])
- {
- return -1;
- }
- i++;
- j++;
- }
- }
- if (arr1.Length == arr2.Length)
- {
- return 0;
- }
- return arr1.Length > arr2.Length ? 1 : -1;
- }
- }
- internal static class UtilityKeyCode
- {
- //from http://stackoverflow.com/questions/5825820/how-to-capture-the-character-on-different-locale-keyboards-in-wpf-c
- private enum MapType : uint
- {
- MapvkVkToVsc = 0x0,
- //MapvkVScToVk = 0x1,
- //MapvkVkToChar = 0x2,
- //MapvkVScToVkex = 0x3,
- }
- [DllImport("user32.dll")]
- private static extern int ToUnicode(
- uint wVirtKey,
- uint wScanCode,
- byte[] lpKeyState,
- [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)]
- StringBuilder pwszBuff,
- int cchBuff,
- uint wFlags);
- [DllImport("user32.dll")]
- private static extern bool GetKeyboardState(byte[] lpKeyState);
- [DllImport("user32.dll")]
- private static extern uint MapVirtualKey(uint uCode, MapType uMapType);
- public static char ToChar(this Keys key)
- {
- var ch = '\0';
- var virtualKey = (int)key;
- var keyboardState = new byte[256];
- GetKeyboardState(keyboardState);
- var scanCode = MapVirtualKey((uint)virtualKey, MapType.MapvkVkToVsc);
- var stringBuilder = new StringBuilder(2);
- var result = ToUnicode((uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0);
- switch (result)
- {
- case -1:
- break;
- case 0:
- break;
- case 1:
- ch = stringBuilder[0];
- break;
- default:
- ch = stringBuilder[0];
- break;
- }
- return ch;
- }
- }
- internal static class UtilityString
- {
- public static int GetByteLength(this string me)
- {
- return Encoding.Default.GetByteCount(me);
- }
- public static string PadRightByByteCount(this string me, int totalWidth, char paddingChar = ' ')
- {
- var a = totalWidth - me.GetByteLength();
- return a > 0
- ? me + "".PadRight(a)
- : me;
- }
- }
- internal class ExScintilla : Scintilla
- {
- private class SelWrap
- {
- public int Begin { get; set; }
- public int Length { get; set; }
- }
- private enum MappedAction
- {
- Delete,
- Left,
- Right,
- MoveLeft,
- MoveRight,
- IncSelLen,
- DecSelLen,
- }
- public ExScintilla()
- {
- VirtualSpaceOptions = VirtualSpace.RectangularSelection;
- }
- protected override void OnKeyDown(KeyEventArgs e)
- {
- // ReSharper disable once AssignmentInConditionalExpression
- if (e.Alt || Selections.Count < 2)
- {
- base.OnKeyDown(e);
- return;
- }
- e.SuppressKeyPress = true;
- //LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
- // >> EDITOR :: COLUMN MODE IMPLEMENT <<
- var tb = this;
- if (tb.Selections.Count < 2) return; // no in column mode
- e.SuppressKeyPress = true; //block input, handle by below code
- MappedAction? action = null;
- if (e.KeyCode == Keys.Delete && e.KeyData == Keys.Delete && e.KeyValue == 46)
- {
- action = MappedAction.Delete;
- }
- if (e.KeyCode == Keys.Left && e.KeyData == Keys.Left && e.KeyValue == 37)
- {
- action = MappedAction.Left;
- }
- if (e.KeyCode == Keys.Right && e.KeyData == Keys.Right && e.KeyValue == 39)
- {
- action = MappedAction.Right;
- }
- if (e.Shift && e.KeyData == (Keys.Shift | Keys.Left) && e.KeyCode == Keys.Left && e.KeyValue == 37)
- {
- action = MappedAction.MoveLeft;
- }
- if (e.Shift && e.KeyData == (Keys.Right | Keys.Shift) && e.KeyCode == Keys.Right && e.KeyValue == 39)
- {
- action = MappedAction.MoveRight;
- }
- if (e.Control && e.KeyData == (Keys.Control | Keys.Left) && e.KeyCode == Keys.Left && e.KeyValue == 37)
- {
- action = MappedAction.DecSelLen;
- }
- if (e.Control && e.KeyData == (Keys.Right | Keys.Control) && e.KeyCode == Keys.Right && e.KeyValue == 39)
- {
- action = MappedAction.IncSelLen;
- }
- string input;
- if (action.HasValue)
- {
- input = "\0";
- }
- else
- {
- input = e.KeyCode.ToChar().ToString();
- if (input == "\0")
- {
- //SystemSounds.Beep.Play();
- return;
- }
- }
- var selections = tb.Selections
- .OrderBy(p => p.Start)
- .Select(p => new SelWrap { Begin = p.Start, Length = p.End - p.Start })
- .ToArray();
- var contents = new string[selections.Length];
- for (var i = 0; i < contents.Length; i++)
- {
- contents[i] = input;
- }
- if (input == "\u0018" || input == "\u0003") //^X or ^C
- {
- for (var i = 0; i < selections.Length; i++)
- {
- contents[i] = tb.GetTextRange(selections[i].Begin, selections[i].Length);
- }
- Clipboard.SetText(string.Join(Environment.NewLine, contents));
- if (input == "\u0018") // ^X
- {
- for (var i = 0; i < selections.Length; i++)
- {
- contents[i] = "";
- }
- }
- else
- {
- return;
- }
- }
- if (input == "\u0016") //^V
- {
- for (var i = 0; i < selections.Length; i++)
- {
- contents[i] = "";
- }
- var clipLines = Clipboard.GetText().Split(new[] { Environment.NewLine }, StringSplitOptions.None);
- for (var i = 0; i < contents.Length && i < contents.Length; i++)
- {
- contents[i] = clipLines[i];
- }
- }
- //do process every caret(or selection)
- for (var i = 0; i < selections.Length; i++)
- {
- var item = selections[i];
- if (MappedAction.IncSelLen == action)
- {
- item.Length++;
- }
- else if (MappedAction.DecSelLen == action)
- {
- item.Length--;
- }
- else
- {
- if (action.HasValue) // before process, copy
- {
- for (var c = 0; c < selections.Length; c++)
- {
- contents[c] = tb.GetTextRange(selections[c].Begin, selections[c].Length);
- }
- }
- var removeSelected = item.Length > 0;
- if (removeSelected) //if has selected text, just clean
- {
- tb.DeleteRange(item.Begin, item.Length);
- for (var j = i + 1; j < selections.Length; j++)
- {
- selections[j].Begin -= item.Length;
- }
- }
- if (input == "\b") //backspace
- {
- if (item.Length != 0) continue;
- //delete a char before caret
- tb.DeleteRange(item.Begin - 1, 1);
- for (var j = i; j < selections.Length; j++)
- {
- selections[j].Begin--;
- }
- }
- else if (MappedAction.Delete == action)
- {
- selections[i].Length = 0;
- if (removeSelected) continue;
- //delete a char after caret
- tb.DeleteRange(item.Begin, 1);
- for (var j = i + 1; j < selections.Length; j++)
- {
- selections[j].Begin--;
- }
- }
- else if (MappedAction.Left == action || MappedAction.MoveLeft == action)
- {
- selections[i].Begin--;
- if (MappedAction.MoveLeft == action)
- {
- selections[i].Length = contents[i].Length;
- tb.InsertText(item.Begin, contents[i]);
- }
- else
- {
- tb.InsertText(item.Begin + 1, contents[i]);
- }
- for (var j = i + 1; j < selections.Length; j++) selections[j].Begin += contents[i].Length;
- }
- else if (MappedAction.Right == action || MappedAction.MoveRight == action)
- {
- selections[i].Begin++;
- if (MappedAction.MoveRight == action)
- {
- selections[i].Length = contents[i].Length;
- tb.InsertText(item.Begin, contents[i]);
- }
- else
- {
- tb.InsertText(item.Begin - 1, contents[i]);
- }
- for (var j = i + 1; j < selections.Length; j++) selections[j].Begin += contents[i].Length;
- }
- else
- {
- //just insert that
- tb.InsertText(item.Begin, contents[i]);
- item.Begin++;
- for (var j = i + 1; j < selections.Length; j++) selections[j].Begin += contents[i].Length;
- }
- }
- }
- //restore select status
- tb.ClearSelections();
- tb.SetSelection(selections[0].Begin, selections[0].Begin + selections[0].Length);
- for (var i = 1; i < selections.Length; i++)
- {
- var item = selections[i];
- tb.AddSelection(item.Begin, item.Begin + item.Length);
- }
- }
- private int _maxLineNumberCharLength1;
- protected override void OnTextChanged(EventArgs e)
- {
- var maxLineNumberCharLength = Lines.Count.ToString().Length;
- if (maxLineNumberCharLength == _maxLineNumberCharLength1)
- return;
- const int padding = 2;
- Margins[0].Width = TextWidth(Style.LineNumber, new string('9', maxLineNumberCharLength + 1)) + padding;
- _maxLineNumberCharLength1 = maxLineNumberCharLength;
- base.OnTextChanged(e);
- }
- }
- internal class MainForm : Form
- {
- [STAThread]
- private static void Main()
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new MainForm());
- }
- private MainForm()
- {
- InitUi();
- }
- private void InitUi()
- {
- //LLLLLLLLLLLLLL
- // >> FORMCNF <<
- ClientSize = new Size(640, 480);
- Text = Application.ProductName;
- AllowDrop = true;
- //LLLLLLLLLLLLLL
- // >> EDITOR <<
- var editor = new ExScintilla
- {
- Dock = DockStyle.Fill,
- Text = "<<Drag a *dir* in to here>>",
- };
- Controls.Add(editor);
- editor.Margins[0].Width = 16;
- editor.Margins[0].Type = MarginType.Number;
- editor.ReadOnly = true;
- editor.Styles[Style.Cpp.Default].Font = "fixedsys";
- editor.Styles[Style.Cpp.Default].Size = 12;
- //LLLLLLLLLLLLLL
- // >> TOOLBAR <<
- var toolbar = new ToolStrip { Dock = DockStyle.Top, GripStyle = ToolStripGripStyle.Hidden, RenderMode = ToolStripRenderMode.System };
- Controls.Add(toolbar);
- toolbar.Items.Add(new ToolStripLabel("Usage: Drop >> Edit >> Click ") { Font = new Font(Font, FontStyle.Italic | FontStyle.Bold) });
- toolbar.Items.Add(new ToolStripLabel("Go!") { Font = new Font(Font, FontStyle.Italic | FontStyle.Bold | FontStyle.Underline) });
- toolbar.Items.Add(new ToolStripLabel(" >> Click ") { Font = new Font(Font, FontStyle.Italic | FontStyle.Bold) });
- toolbar.Items.Add(new ToolStripLabel("Reset") { Font = new Font(Font, FontStyle.Italic | FontStyle.Bold | FontStyle.Underline) });
- toolbar.Items.Add(new ToolStripLabel(" for again") { Font = new Font(Font, FontStyle.Italic | FontStyle.Bold) });
- var mnuReset = new ToolStripButton("Reset");
- toolbar.Items.Add(mnuReset);
- mnuReset.Alignment = ToolStripItemAlignment.Right;
- mnuReset.Font = new Font(mnuReset.Font, FontStyle.Underline);
- var mnuGo = new ToolStripButton("Go!");
- toolbar.Items.Add(mnuGo);
- mnuGo.Alignment = ToolStripItemAlignment.Right;
- mnuGo.Font = new Font(mnuGo.Font, FontStyle.Underline);
- mnuReset.Click += delegate
- {
- editor.ReadOnly = false;
- editor.Text = "<<Drag a *dir* in to here>>";
- editor.ClearSelections();
- editor.ScrollRange(0, 0);
- editor.ReadOnly = true;
- };
- mnuGo.Click += delegate
- {
- if (editor.ReadOnly)
- {
- MessageBox.Show("What?");
- return;
- }
- var outputFilename = Path.GetTempFileName();
- var batFilename = outputFilename + ".bat";
- File.WriteAllText(batFilename, editor.Text, new UTF8Encoding(false));
- var p = new Process
- {
- StartInfo = new ProcessStartInfo()
- {
- FileName = "cmd",
- Arguments = $"/c chcp {Encoding.UTF8.CodePage} && prompt $G && {batFilename} > {outputFilename} 2>&1",
- CreateNoWindow = true,
- UseShellExecute = false,
- WindowStyle = ProcessWindowStyle.Hidden,
- }
- };
- p.Start();
- p.WaitForExit();
- File.Delete(batFilename);
- editor.Text = File.ReadAllText(outputFilename, Encoding.UTF8);
- File.Delete(outputFilename);
- editor.ReadOnly = true;
- };
- //LLLLLLLLLLLLLL
- // >> DRAGEVT <<
- DragEnter += delegate (object s, DragEventArgs e)
- {
- string[] items;
- e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop)
- && (items = (string[])e.Data.GetData(DataFormats.FileDrop)).Length == 1
- && Directory.Exists(items[0])
- ? DragDropEffects.Link
- : DragDropEffects.None;
- };
- DragDrop += delegate (object s, DragEventArgs e)
- {
- var dir = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
- var files = Directory.GetFiles(dir, "*", SearchOption.AllDirectories)
- .Select(p => p.Substring(dir.Length + 1))
- .ToArray();
- Array.Sort(files, new FilesNameComparer());
- var lines = new List<string>(files.Length + 5)
- {
- $"@cd /d \"{dir}\"",
- ""
- };
- var width = files.Max(p => p.GetByteLength());
- lines.AddRange(files.Select(item => $"move \"{("" + item + "\"").PadRightByByteCount(width + 1)} \"{item}\""));
- editor.ReadOnly = false;
- editor.Text = string.Join(Environment.NewLine, lines);
- };
- }
- }
- }
|