SciTE Hints and Tips

These are a collection of hints and tips for the SciTE editor.

Swap header
Show trailing whitespace

Swap C / Header

First - something simple but very useful for C/C++ programmers - keyboard-based switching between source and header file. Open the .SciTEUser.properties - which is availible from the SciTE menu

Options -> Open User Options File

and insert something like this:

  1. command.name.1.*=Swap C / Header
  2. command.1.*=dofile /home/gusnan/scripts/scite/swapheader.lua
  3. command.subsystem.1.*=3
  4. command.mode.1.*=savebefore:no
  5. command.shortcut.1.*=F11

This means we will have a new menu entry with 'Swap C / Header', which when activated will run the LUA script

/home/gusnan/scripts/scite/swapheader.lua

And that we also have a keyboard shortcut, key F11.

For an example on how to use a SciTE startup LUA script, and run all functions from there, see the other "Show trailing whitespace" example.

Point the file at line 2 to a file that contains the following:
(I have called it swapheader.lua)

  1. function exists(file)
  2. res=false;
  3.  
  4. f=io.open(file);
  5. if (f~=nil) then
  6. io.close(f);
  7. res=true;
  8. end
  9.  
  10. return res;
  11. end
  12.  
  13. local cpp_ext = 'cpp'
  14. local cpp_ext2 = 'cc'
  15. local c_ext='c'
  16. local h_ext = 'h'
  17. local f = props['FileName'] -- e.g 'test'
  18. local ext = props['FileExt'] -- e.g 'cpp'
  19. local path = props['FileDir'] -- e.g. '/home/steve/progs'
  20.  
  21. local filename=path..'/'..f..'.'..ext;
  22.  
  23. if ext==cpp_ext or ext==c_ext or ext==cpp_ext2 then
  24. ext=h_ext
  25. elseif ext==h_ext then
  26. ext=cpp_ext
  27. filename=path..'/'..f..'.'..ext
  28. if (exists(filename)~=true) then
  29. ext=c_ext
  30. filename=path..'/'..f..'.'..ext
  31. if (exists(filename)~=true) then
  32. ext=cpp_ext2
  33. filename=path..'/'..f..'.'..ext
  34. if (exists(filename)~=true) then
  35.  
  36. end
  37. end
  38. end
  39. end
  40.  
  41. filename=path..'/'..f..'.'..ext
  42.  
  43. -- if the file exists, open it!
  44. if (exists(filename)==true) then
  45. scite.Open(filename)
  46. end
  47.  
Show trailing whitespace

I have been using Emacs some lately, and there it is possible to make trailing whitespace clearly visible in a simple way. (I don't remember if I needed some plugin to make it possible, but that is beside the point). I want the same possibility in my favourite editor SciTE, and have because of this made some scripting (with initial help from the great SciTE developer Neil Hodgson).

My solution gives a keyboard combination to show / hide the trailing whitespace clearly with red boxes, and it is done this way:

First, we need a keyboard combination (and I add a menu item for it), which is added by adding the following to your users SciTEUser.properties:

  1. command.name.4.*=Find trailing whitespace
  2. command.4.*=switch_trailing_whitespace
  3. command.subsystem.4.*=3
  4. command.mode.4.*=savebefore:no
  5. command.shortcut.4.*=Ctrl+Alt+F
  6.  

This instructs SciTE to run the function switch_trailing_whitespace when Ctrl+Alt+F is pressed. This function needs to be located in a file that is loaded upon SciTE start, so I place it in findtext.lua, a put this into my SciTEUser.properties:

ext.lua.startup.script=/home/gusnan/scripts/scite/startup.lua

In this file startup.lua we need to include the file containing the code to find the whitespace, and also some event handlers for when keys are pressed. This makes the whitespace checker update each time a key is pressed. Our keyboard shortcut Ctrl+Alt+F which we defined above simply switches a boolean for whether to check for trailing whitespace or not.

  1.  
  2. dofile "/home/gusnan/scripts/scite/find_trailing_whitespace.lua"
  3.  
  4. --------------------------------------------------------------------------------
  5. --
  6. --------------------------------------------------------------------------------
  7. function OnKey()
  8. find_trailing_whitespace();
  9.  
  10. -- return false to give other extensions a chance to handle the
  11. -- same event
  12. return false;
  13. end
  14.  
  15.  
  16. function OnChar()
  17. find_trailing_whitespace();
  18.  
  19. -- return false to give other extensions a chance to handle the
  20. -- same event
  21. return false;
  22. end
  23.  

Then, our find_trailing_whitespace.lua looks like this:

  1. --------------------------------------------------------------------------------
  2. --
  3. --------------------------------------------------------------------------------
  4. local show_trailing_whitespace = false;
  5.  
  6. local indicator = 2;
  7.  
  8. --------------------------------------------------------------------------------
  9. --
  10. --------------------------------------------------------------------------------
  11. function trim(s)
  12. return (s:gsub("^%s*(.-)%s*$", "%1"))
  13. end
  14.  
  15. --------------------------------------------------------------------------------
  16. --
  17. --------------------------------------------------------------------------------
  18. function only_whitespace(test_string)
  19. result = false;
  20.  
  21. if (trim(test_string)=="") then
  22. result=true;
  23. end
  24.  
  25. return result;
  26. end
  27.  
  28. --------------------------------------------------------------------------------
  29. --
  30. --------------------------------------------------------------------------------
  31. function fill_trailing()
  32. --show_trailing_whitespace = true;
  33. s,e = editor:findtext("[ \t]+$", SCFIND_REGEXP, 0);
  34.  
  35. while s do
  36.  
  37. if (s ~= nil) then
  38.  
  39. local line = editor:LineFromPosition(s);
  40. local line_contents= editor:GetLine(line);
  41.  
  42. -- If the line contains trailing whitespace, and not ONLY
  43. -- whitespace, mark it red.
  44. if only_whitespace(line_contents)~=true then
  45.  
  46. scite.SendEditor(SCI_SETINDICATORCURRENT, indicator);
  47. scite.SendEditor(SCI_INDICATORFILLRANGE, s, e - s)
  48. end
  49.  
  50. end
  51. s,e = editor:findtext("[ \t]+$",SCFIND_REGEXP, e + 1)
  52. end
  53.  
  54. end
  55.  
  56. --------------------------------------------------------------------------------
  57. --
  58. --------------------------------------------------------------------------------
  59. function clear_trailing()
  60.  
  61. -- begin with clearing all on current line
  62. local position = editor.CurrentPos;
  63. local what_line = editor:LineFromPosition(position);
  64.  
  65. local position1 = editor:PositionFromLine(what_line - 1);
  66. local position2 = editor:PositionFromLine(what_line + 1);
  67.  
  68. scite.SendEditor(SCI_SETINDICATORCURRENT, indicator);
  69. scite.SendEditor(SCI_INDICATORCLEARRANGE, position1, position2-position1);
  70.  
  71. s,e = editor:findtext("[ \t]+$", SCFIND_REGEXP, 0);
  72.  
  73. while s do
  74. scite.SendEditor(SCI_SETINDICATORCURRENT, indicator);
  75. scite.SendEditor(SCI_INDICATORCLEARRANGE, s, e - s)
  76.  
  77. s,e = editor:findtext("[ \t]+$",SCFIND_REGEXP, e + 1)
  78. end
  79. end
  80.  
  81. --------------------------------------------------------------------------------
  82. --
  83. --------------------------------------------------------------------------------
  84. function find_trailing_whitespace()
  85.  
  86. if (show_trailing_whitespace~=false) then
  87. scite.SendEditor(SCI_INDICSETSTYLE, indicator, INDIC_STRAIGHTBOX);
  88. scite.SendEditor(SCI_INDICSETFORE, indicator, 0x0000ff); -- (red)
  89. scite.SendEditor(SCI_INDICSETOUTLINEALPHA, indicator, 0xff); -- (red)
  90. scite.SendEditor(SCI_INDICSETALPHA, indicator, 0xff)
  91.  
  92. -- remove the old fills
  93. clear_trailing();
  94.  
  95. -- and update with the new
  96. fill_trailing();
  97. else
  98. --clear_trailing();
  99. end
  100.  
  101. end
  102.  
  103.  
  104. --------------------------------------------------------------------------------
  105. --
  106. --------------------------------------------------------------------------------
  107. function switch_trailing_whitespace()
  108.  
  109. if (show_trailing_whitespace ~= true) then
  110.  
  111. show_trailing_whitespace = true;
  112. find_trailing_whitespace();
  113. else
  114. show_trailing_whitespace = false;
  115. clear_trailing();
  116. end
  117. end
  118.  

Deleting the whitespace that my functions here find can be done in a similar way, using editor:remove - for example, see http://lua-users.org/wiki/SciteCleanDocWhitespace for one way to do it.

There are a whole lot of useful stuff on http://lua-users.org/, well worth checking out.