/* Utils.em - a small collection of useful editing macros */
/*-------------------------------------------------------------------------
I N S E R T H E A D E R
Inserts a comment header block at the top of the current function.
This actually works on any type of symbol, not just functions.
To use this, define an environment variable "MYNAME" and set it
to your email name. eg. set MYNAME=raygr
-------------------------------------------------------------------------*/
macro InsertHeader()
{
// Get the owner's name from the environment variable: MYNAME.
// If the variable doesn't exist, then the owner field is skipped.
szMyName = getenv(MyName)
// Get a handle to the current file buffer and the name
// and location of the current symbol where the cursor is.
hbuf = GetCurrentBuf()
szFunc = GetCurSymbol()
ln = GetSymbolLine(szFunc)
InsBufLine(hbuf, ln, "/************************************************************");
ln = ln +1
// begin assembling the title string
sz = "** 函数名称: "
/* convert symbol name to T E X T L I K E T H I S */
cch = strlen(szFunc)
ich = 0
while (ich < cch)
{
ch = szFunc[ich]
if (ich > 0)
if (isupper(ch))
sz = cat(sz, " ")
else
sz = cat(sz, " ")
sz = Cat(sz, toupper(ch))
ich = ich + 1
}
InsBufLine(hbuf, ln, sz)
ln = ln + 1
InsBufLine(hbuf, ln, "** 功能描述: ")
ln = ln + 1
InsBufLine(hbuf, ln, "** 输入参数:")
ln = ln + 1
InsBufLine(hbuf, ln, "** 输出参数: ")
ln = ln + 1
InsBufLine(hbuf, ln, "** 返 回 值 :")
ln = ln + 1
/* if owner variable exists, insert Owner: name */
if (strlen(szMyName) > 0)
{
InsBufLine(hbuf, ln, "** 作 者 : @szMyName@")
}
else
{
InsBufLine(hbuf, ln, "** 作 者 : ")
}
ln = ln + 1
// Get current time
szTime = GetSysTime(1)
Day = szTime.Day
Month = szTime.Month
Year = szTime.Year
if (Day < 10)
szDay = "0@Day@"
else
szDay = Day
InsBufLine(hbuf, ln, "** 日 期 : @Year@年@Month@月@szDay@日")
ln = ln + 1
InsBufLine(hbuf, ln, "** 版 本 : 1.0")
ln = ln + 1
InsBufLine(hbuf, ln, "** 修改日期 版本号 修改人 修改内容")
ln = ln + 1
InsBufLine(hbuf, ln, "**************************************************************/")
}
/* InsertFileHeader:
Inserts a comment header block at the top of the current function.
This actually works on any type of symbol, not just functions.
To use this, define an environment variable "MYNAME" and set it
to your email name. eg. set MYNAME=raygr
*/
macro InsertFileHeader()
{
szMyName = getenv(MyName)
hbuf = GetCurrentBuf()
InsBufLine(hbuf, 0, "/***************************************************************************")
InsBufLine(hbuf, 1, "** 版权所有: Copyright (c) 2003-2008 ******************** ")
filename = GetBufName(hbuf)
InsBufLine(hbuf, 2, "** 文件名称: @filename@")
InsBufLine(hbuf, 3, "** 文件标识: ")
InsBufLine(hbuf, 4, "** 内容摘要: ")
InsBufLine(hbuf, 5, "** 当前版本: v1.0")
/* if owner variable exists, insert Owner: name */
if (strlen(szMyName) > 0)
{
sz = "** 作 者 : @szMyName@"
}
else
{
sz = "** 作 者 :"
}
InsBufLine(hbuf, 6, sz)
// Get current time
szTime = GetSysTime(1)
Day = szTime.Day
Month = szTime.Month
Year = szTime.Year
if (Day < 10)
szDay = "0@Day@"
else
szDay = Day
InsBufLine(hbuf, 7, "** 完成日期: @Year@年@Month@月@szDay@日")
InsBufLine(hbuf, 8, "** 修改记录: ")
InsBufLine(hbuf, 9, "** 修改记录: ")
InsBufLine(hbuf, 10, "** 修改日期: ")
InsBufLine(hbuf, 11, "** 版本号 : ")
InsBufLine(hbuf, 12, "** 修改人 : ")
InsBufLine(hbuf, 13, "** 修改内容: ")
InsBufLine(hbuf, 14, "***************************************************************************/")
}
/* A U T O E X P A N D */
/*-------------------------------------------------------------------------
Automatically expands C statements like if, for, while, switch, etc..
To use this macro,
1. Add this file to your project or your Base project.
2. Run the Options->Key Assignments command and assign a
convenient keystroke to the "AutoExpand" command.
3. After typing a keyword, press the AutoExpand keystroke to have the
statement expanded. The expanded statement will contain a ### string
which represents a field where you are supposed to type more.
The ### string is also loaded in to the search pattern so you can
use "Search Forward" to select the next ### field.
For example:
1. you type "for" + AutoExpand key
2. this is inserted:
for (###; ###; ###)
{
###
}
3. and the first ### field is selected.
-------------------------------------------------------------------------*/
macro AutoExpand()
{
// get window, sel, and buffer handles
hwnd = GetCurrentWnd()
if (hwnd == 0)
stop
sel = GetWndSel(hwnd)
if (sel.ichFirst == 0)
stop
hbuf = GetWndBuf(hwnd)
// get line the selection (insertion point) is on
szLine = GetBufLine(hbuf, sel.lnFirst);
// parse word just to the left of the insertion point
wordinfo = GetWordLeftOfIch(sel.ichFirst, szLine)
ln = sel.lnFirst;
chTab = CharFromAscii(9)
// prepare a new indented blank line to be inserted.
// keep white space on left and add a tab to indent.
// this preserves the indentation level.
ich = 0
while (szLine[ich] == ' ' || szLine[ich] == chTab)
{
ich = ich + 1
}
szLine = strmid(szLine, 0, ich) # " "
sel.lnFirst = sel.lnLast
sel.ichFirst = wordinfo.ich
sel.ichLim = wordinfo.ich
// expand szWord keyword...
if (wordinfo.szWord == "if" ||
wordinfo.szWord == "while" ||
wordinfo.szWord == "elseif")
{
SetBufSelText(hbuf, " (###)")
InsBufLine(hbuf, ln + 1, "@szLine@" # "{");
InsBufLine(hbuf, ln + 2, "@szLine@" # "###");
InsBufLine(hbuf, ln + 3, "@szLine@" # "}");
}
else if (wordinfo.szWord == "for")
{
SetBufSelText(hbuf, " (###; ###; ###)")
InsBufLine(hbuf, ln + 1, "@szLine@" # "{");
InsBufLine(hbuf, ln + 2, "@szLine@" # "###");
InsBufLine(hbuf, ln + 3, "@szLine@" # "}");
}
else if (wordinfo.szWord == "switch")
{
SetBufSelText(hbuf, " (###)")
InsBufLine(hbuf, ln + 1, "@szLine@" # "{")
InsBufLine(hbuf, ln + 2, "@szLine@" # "case ###:")
InsBufLine(hbuf, ln + 3, "@szLine@" # chTab # "###")
InsBufLine(hbuf, ln + 4, "@szLine@" # chTab # "break;")
InsBufLine(hbuf, ln + 5, "@szLine@" # "}")
}
else if (wordinfo.szWord == "do")
{
InsBufLine(hbuf, ln + 1, "@szLine@" # "{")
InsBufLine(hbuf, ln + 2, "@szLine@" # "###");
InsBufLine(hbuf, ln + 3, "@szLine@" # "} while (###);")
}
else if (wordinfo.szWord == "case")
{
SetBufSelText(hbuf, " ###:")
InsBufLine(hbuf, ln + 1, "@szLine@" # "###")
InsBufLine(hbuf, ln + 2, "@szLine@" # "break;")
}
else
stop
SetWndSel(hwnd, sel)
LoadSearchPattern("###", true, false, false);
Search_Forward
}
/* G E T W O R D L E F T O F I C H */
/*-------------------------------------------------------------------------
Given an index to a character (ich) and a string (sz),
return a "wordinfo" record variable that describes the
text word just to the left of the ich.
Output:
wordinfo.szWord = the word string
wordinfo.ich = the first ich of the word
wordinfo.ichLim = the limit ich of the word
-------------------------------------------------------------------------*/
macro GetWordLeftOfIch(ich, sz)
{
wordinfo = "" // create a "wordinfo" structure
chTab = CharFromAscii(9)
// scan backwords over white space, if any
ich = ich - 1;
if (ich >= 0)
while (sz[ich] == " " || sz[ich] == chTab)
{
ich = ich - 1;
if (ich < 0)
break;
}
// scan backwords to start of word
ichLim = ich + 1;
asciiA = AsciiFromChar("A")
asciiZ = AsciiFromChar("Z")
while (ich >= 0)
{
ch = toupper(sz[ich])
asciiCh = AsciiFromChar(ch)
if ((asciiCh < asciiA || asciiCh > asciiZ) && !IsNumber(ch))
break // stop at first non-identifier character
ich = ich - 1;
}
ich = ich + 1
wordinfo.szWord = strmid(sz, ich, ichLim)
wordinfo.ich = ich
wordinfo.ichLim = ichLim;
return wordinfo
}
// Closes all but the most recently visited windows and files.
// Any dirty files are kept open.
macro CloseOldWindows()
{
var hwnd
var cWnd
// This is the number of recent windows to keep open. You may change
// this constant to suit your needs.
var NumberOfWindowsToKeep; NumberOfWindowsToKeep = 4
hwnd = GetCurrentWnd()
cWnd = 0
// skip the most recently visited windows in the z-order
while (hwnd != hNil && cWnd < NumberOfWindowsToKeep)
{
cWnd = cWnd + 1
hwnd = GetNextWnd(hwnd)
}
// close the remaining windows
while (hwnd != hNil)
{
var hwndNext
hwndNext = GetNextWnd(hwnd)
// only close the window if the file is not edited
if (!IsBufDirty(GetWndBuf(hwnd)))
CloseWnd(hwnd)
hwnd = hwndNext
}
// close all files that are not visible in a window anymore
var cBuf
cBuf = BufListCount()
while (cBuf > 0)
{
var hbuf
cBuf = cBuf - 1
hbuf = BufListItem(cBuf)
if (GetWndHandle(hbuf) == hNil)
CloseBuf(hbuf)
}
}
// Convert spaces to tabs and save the file
macro Save_Spaces_To_Tabs()
{
hbuf = GetCurrentBuf()
if (hbuf != hNil)
{
Spaces_To_Tabs()
SaveBuf(hbuf)
}
}
// Convert tabs to spaces and save the file
macro Save_Tabs_To_Spaces()
{
hbuf = GetCurrentBuf()
if (hbuf != hNil)
{
Tabs_To_Spaces()
SaveBuf(hbuf)
}
}
//----------------------------------------------------------------------------
// Function: Spaces_To_Tabs
//
// Description:
// Convert all sets of two or more spaces in the current buffer into the
// appropriate number of tab characters.
//
macro Spaces_To_Tabs()
{
hbuf = GetCurrentBuf()
hwnd = GetCurrentWnd()
srSave = GetWndSel(hwnd)
// Phase 1: convert the spaces at the beginning of lines
//
Leading_Spaces_To_Tabs()
// Phase 2: convert the spaces NOT at the beginning of lines
//
sr = SearchInBuf(hbuf, " +", 0, 0, 1, 1, 0)
while (sr != "")
{
SetWndSel(hwnd, sr)
ReTab_Current_Line()
sr = GetWndSel(hwnd)
sr = SearchInBuf(hbuf, " +", sr.lnLast, sr.ichLim, 1, 1, 0)
}
SetBufIns(hbuf, srSave.lnFirst, srSave.ichFirst)
}
//----------------------------------------------------------------------------
// Function: Tabs_To_Spaces
//
// Description:
// Convert all tab characters in the current buffer into the appropriate
// number of spaces.
//
macro Tabs_To_Spaces()
{
hbuf = GetCurrentBuf()
hwnd = GetCurrentWnd()
srSave = GetWndSel(hwnd)
// Phase 1: convert the tabs at the beginning of lines
//
Leading_Tabs_To_Spaces()
// Phase 2: convert the tabs NOT at the beginning of lines
//
sr = SearchInBuf(hbuf, "//t", 0, 0, 1, 1, 0)
while (sr != "")
{
SetWndSel(hwnd, sr)
DeTab_Current_Line()
sr = GetWndSel(hwnd)
sr = SearchInBuf(hbuf, "//t", sr.lnLast, sr.ichLim, 1, 1, 0)
}
SetBufIns(hbuf, srSave.lnFirst, srSave.ichFirst)
}
//----------------------------------------------------------------------------
// Function: Leading_Spaces_To_Tabs
//
// Description:
// Convert all sets of two or more spaces in the current buffer into the
// appropriate number of tab characters.
//
macro Leading_Spaces_To_Tabs()
{
hbuf = GetCurrentBuf()
iConsecutiveTabs = 0
while (iConsecutiveTabs < 15)
{
ReplaceInBuf(hbuf, "^//(//t*//) ", "//1//t", 0,
GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
iConsecutiveTabs = iConsecutiveTabs + 1
}
}
//----------------------------------------------------------------------------
// Function: Leading_Tabs_To_Spaces
//
// Description:
// Convert all tab characters at line beginnings in the current buffer
// into the appropriate number of spaces. Brute force method.
//
macro Leading_Tabs_To_Spaces()
{
hbuf = GetCurrentBuf()
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
ReplaceInBuf(hbuf, "^//t",
" ",
0, GetBufLineCount(hbuf) + 1, 1, 1, 0, 0)
}
//----------------------------------------------------------------------------
// Function: DeTab_Current_Line
//
// Description:
// Convert all tabs in the current line into the appropriate number of
// spaces, based upon line position. Good for up to 25 consecutive tabs.
//
macro DeTab_Current_Line()
{
szSpaces = " "
tabSize = 4
hbuf = GetCurrentBuf()
iLine = GetBufLnCur(hbuf)
cLines = GetBufLineCount(hbuf)
szLine = GetBufLine(hbuf, iLine)
cchLine = strlen(szLine)
ichL = 0
ichR = 0
icoL = 0
icoR = 0
ichLine = 0
icoLine = 0
inTabs = '<'
szNewLine = ""
while (ichLine < cchLine)
{
if (szLine[ichLine] == "/t")
{
if (inTabs == 'N')
{
szNewLine = cat(szNewLine, strmid(szLine, ichL, ichR + 1))
icoL = icoLine
}
icoLine = (((icoLine + tabSize) / tabSize) * tabSize)
icoR = icoLine
inTabs = 'Y'
}
else
{
if (inTabs == 'Y')
{
cSpaces = icoR - icoL
szNewLine = cat(szNewLine, strtrunc(szSpaces, cSpaces))
ichL = ichLine
ichR = ichLine
}
else
{
ichR = ichLine
}
icoLine = icoLine + 1
inTabs = 'N'
}
ichLine = ichLine + 1
}
if (inTabs == 'Y')
{
cSpaces = icoR - icoL
szNewLine = cat(szNewLine, strtrunc(szSpaces, cSpaces))
}
else
{
szNewLine = cat(szNewLine, strmid(szLine, ichL, ichR + 1))
}
PutBufLine(hbuf, iLine, szNewLine)
// Work around weirdness of PutBufLine(); it moves UP one line when
// putting the last line in the buffer!
//
if (iLine + 1 == cLines)
{
Cursor_Down
}
End_Of_Line
}
//----------------------------------------------------------------------------
// Function: ReTab_Current_Line
//
// Description:
// Convert all sets of two or more spaces in the current line into the
// appropriate number of tab and space characters, based upon line
// position. Good for indentations up to 100 columns.
//
macro ReTab_Current_Line()
{
szTabs = " ";
szSpaces = " " // As many spaces as value of tabSize
tabSize = 4
hbuf = GetCurrentBuf()
iLine = GetBufLnCur(hbuf)
cLines = GetBufLineCount(hbuf)
szLine = GetBufLine(hbuf, GetBufLnCur(hbuf))
cchLine = strlen(szLine)
ichL = 0
ichR = 0
icoL = 0
icoR = 0
ichLine = 0
icoLine = 0
inText = '<'
quotes = 'N'
szNewLine = ""
while (ichLine < cchLine)
{
if (szLine[ichLine] == "/t")
{
if (quotes == 'N')
{
if (inText == 'Y')
{
szNewLine = cat(szNewLine, strmid(szLine, ichL, ichR + 1))
icoL = icoLine
}
else if (inText == '?')
{
ichR = ichR - 1
szNewLine = cat(szNewLine, strmid(szLine, ichL, ichR + 1))
}
inText = 'N'
}
icoLine = (((icoLine + tabSize) / tabSize) * tabSize)
icoR = icoLine
}
else if (szLine[ichLine] == " ")
{
if (quotes == 'N')
{
if (inText == 'Y')
{
icoL = icoLine
ichR = ichLine
inText = '?'
}
else if (inText == '?')
{
ichR = ichR - 1
szNewLine = cat(szNewLine, strmid(szLine, ichL, ichR + 1))
inText = 'N'
}
else
{
inText = 'N'
}
}
icoLine = icoLine + 1
icoR = icoLine
}
else
{
if (inText == 'N')
{
cTabs = (icoR / tabSize) - (icoL / tabSize)
if (cTabs > 0)
{
szNewLine = cat(szNewLine, strtrunc(szTabs, cTabs))
cSpaces = icoR - ((icoR / tabSize) * tabSize)
}
else
{
cSpaces = icoR - icoL
}
if (cSpaces > 0)
{
szNewLine = cat(szNewLine, strtrunc(szSpaces, cSpaces))
}
ichL = ichLine
ichR = ichLine
}
else
{
ichR = ichLine
}
if (szLine[ichLine] == "/"")
{
if (quotes == 'N')
{
quotes = 'Y'
}
else if (szLine[ichLine - 1] != "//")
{
quotes = 'N'
}
}
icoLine = icoLine + 1
inText = 'Y'
}
ichLine = ichLine + 1
}
if ((inText == 'Y') || (inText == '?'))
{
szNewLine = cat(szNewLine, strmid(szLine, ichL, ichR + 1))
}
else if (inText == 'N')
{
cTabs = (icoR / tabSize) - (icoL / tabSize)
if (cTabs > 0)
{
szNewLine = cat(szNewLine, strtrunc(szTabs, cTabs))
cSpaces = icoR - ((icoR / tabSize) * tabSize)
}
else
{
cSpaces = icoR - icoL
}
if (cSpaces > 0)
{
szNewLine = cat(szNewLine, strtrunc(szSpaces, cSpaces))
}
}
PutBufLine(hbuf, iLine, szNewLine)
// Work around weirdness of PutBufLine(); it moves UP one line when
// putting the last line in the buffer!
//
if (iLine + 1 == cLines)
{
Cursor_Down
}
End_Of_Line
}
/*
* 代替SourceInsight原有的Backspace功能(希望如此)
* 增加了对双字节汉字的支持,在删除汉字的时候也能同时删除汉字的高字节而缓解半个汉字问题
* 能够对光标在汉字中间的情况进行自动修正
*
* 安装:
* ① 复制入SourceInsight安装目录;
* ② Project→Open Project,打开Base项目;
* ③ 将复制过去的SuperBackspace.em添加入Base项目?
* ④ 重启SourceInsight;
* ⑤ Options→Key Assignments,将Marco: SuperBackspace绑定到BackSpace键;
* ⑥ Enjoy!!
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
macro SuperBackspace()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
stop; // empty buffer
// get current cursor postion
ipos = GetWndSelIchFirst(hwnd);
// get current line number
ln = GetBufLnCur(hbuf);
if ((GetBufSelText(hbuf) != "") || (GetWndSelLnFirst(hwnd) != GetWndSelLnLast(hwnd))) {
// sth. was selected, del selection
SetBufSelText(hbuf, " "); // stupid & buggy sourceinsight :(
// del the " "
SuperBackspace(1);
stop;
}
// copy current line
text = GetBufLine(hbuf, ln);
// get string length
len = strlen(text);
// if the cursor is at the start of line, combine with prev line
if (ipos == 0 || len == 0) {
if (ln <= 0)
stop; // top of file
ln = ln - 1; // do not use "ln--" for compatibility with older versions
prevline = GetBufLine(hbuf, ln);
prevlen = strlen(prevline);
// combine two lines
text = cat(prevline, text);
// del two lines
DelBufLine(hbuf, ln);
DelBufLine(hbuf, ln);
// insert the combined one
InsBufLine(hbuf, ln, text);
// set the cursor position
SetBufIns(hbuf, ln, prevlen);
stop;
}
num = 1; // del one char
if (ipos >= 1) {
// process Chinese character
i = ipos;
count = 0;
while (AsciiFromChar(text[i - 1]) >= 160) {
i = i - 1;
count = count + 1;
if (i == 0)
break;
}
if (count > 0) {
// I think it might be a two-byte character
num = 2;
// This idiot does not support mod and bitwise operators
if ((count / 2 * 2 != count) && (ipos < len))
ipos = ipos + 1; // adjust cursor position
}
}
// keeping safe
if (ipos - num < 0)
num = ipos;
// del char(s)
text = cat(strmid(text, 0, ipos - num), strmid(text, ipos, len));
DelBufLine(hbuf, ln);
InsBufLine(hbuf, ln, text);
SetBufIns(hbuf, ln, ipos - num);
stop;
}
/*2、删除——SuperDelete.em*/
macro SuperDelete()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
stop; // empty buffer
// get current cursor postion
ipos = GetWndSelIchFirst(hwnd);
// get current line number
ln = GetBufLnCur(hbuf);
if ((GetBufSelText(hbuf) != "") || (GetWndSelLnFirst(hwnd) != GetWndSelLnLast(hwnd))) {
// sth. was selected, del selection
SetBufSelText(hbuf, " "); // stupid & buggy sourceinsight :(
// del the " "
SuperDelete(1);
stop;
}
// copy current line
text = GetBufLine(hbuf, ln);
// get string length
len = strlen(text);
if (ipos == len || len == 0) {
totalLn = GetBufLineCount (hbuf);
lastText = GetBufLine(hBuf, totalLn-1);
lastLen = strlen(lastText);
if (ipos == lastLen)// end of file
stop;
ln = ln + 1; // do not use "ln--" for compatibility with older versions
nextline = GetBufLine(hbuf, ln);
nextlen = strlen(nextline);
// combine two lines
text = cat(text, nextline);
// del two lines
DelBufLine(hbuf, ln-1);
DelBufLine(hbuf, ln-1);
// insert the combined one
InsBufLine(hbuf, ln-1, text);
// set the cursor position
SetBufIns(hbuf, ln-1, len);
stop;
}
num = 1; // del one char
if (ipos > 0) {
// process Chinese character
i = ipos;
count = 0;
while (AsciiFromChar(text[i-1]) >= 160) {
i = i - 1;
count = count + 1;
if (i == 0)
break;
}
if (count > 0) {
// I think it might be a two-byte character
num = 2;
// This idiot does not support mod and bitwise operators
if (((count / 2 * 2 != count) || count == 0) && (ipos < len-1))
ipos = ipos + 1; // adjust cursor position
}
// keeping safe
if (ipos - num < 0)
num = ipos;
}
else {
i = ipos;
count = 0;
while(AsciiFromChar(text[i]) >= 160) {
i = i + 1;
count = count + 1;
if(i == len-1)
break;
}
if(count > 0) {
num = 2;
}
}
text = cat(strmid(text, 0, ipos), strmid(text, ipos+num, len));
DelBufLine(hbuf, ln);
InsBufLine(hbuf, ln, text);
SetBufIns(hbuf, ln, ipos);
stop;
}
/*3、左移键——SuperCursorLeft.em*/
macro IsComplexCharacter()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
return 0;
//当前位置
pos = GetWndSelIchFirst(hwnd);
//当前行数
ln = GetBufLnCur(hbuf);
//得到当前行
text = GetBufLine(hbuf, ln);
//得到当前行长度
len = strlen(text);
//从头计算汉字字符的个数
if(pos > 0)
{
i=pos;
count=0;
while(AsciiFromChar(text[i-1]) >= 160)
{
i = i - 1;
count = count+1;
if(i == 0)
break;
}
if((count/2)*2==count|| count==0)
return 0;
else
return 1;
}
return 0;
}
macro moveleft()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
stop; // empty buffer
ln = GetBufLnCur(hbuf);
ipos = GetWndSelIchFirst(hwnd);
if(GetBufSelText(hbuf) != "" || (ipos == 0 && ln == 0)) // 第0行或者是选中文字,则不移动
{
SetBufIns(hbuf, ln, ipos);
stop;
}
if(ipos == 0)
{
preLine = GetBufLine(hbuf, ln-1);
SetBufIns(hBuf, ln-1, strlen(preLine)-1);
}
else
{
SetBufIns(hBuf, ln, ipos-1);
}
}
macro SuperCursorLeft()
{
moveleft();
if(IsComplexCharacter())
moveleft();
}
/*4、右移键——SuperCursorRight.em*/
macro moveRight()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
stop; // empty buffer
ln = GetBufLnCur(hbuf);
ipos = GetWndSelIchFirst(hwnd);
totalLn = GetBufLineCount(hbuf);
text = GetBufLine(hbuf, ln);
if(GetBufSelText(hbuf) != "") //选中文字
{
ipos = GetWndSelIchLim(hwnd);
ln = GetWndSelLnLast(hwnd);
SetBufIns(hbuf, ln, ipos);
stop;
}
if(ipos == strlen(text)-1 && ln == totalLn-1) // 末行
stop;
if(ipos == strlen(text))
{
SetBufIns(hBuf, ln+1, 0);
}
else
{
SetBufIns(hBuf, ln, ipos+1);
}
}
macro SuperCursorRight()
{
moveRight();
if(IsComplexCharacter()) // defined in SuperCursorLeft.em
moveRight();
}
/*5、shift+右移键——ShiftCursorRight.em*/
macro IsShiftRightComplexCharacter()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
return 0;
selRec = GetWndSel(hwnd);
pos = selRec.ichLim;
ln = selRec.lnLast;
text = GetBufLine(hbuf, ln);
len = strlen(text);
if(len == 0 || len < pos)
return 1;
//Msg("@len@;@pos@;");
if(pos > 0)
{
i=pos;
count=0;
while(AsciiFromChar(text[i-1]) >= 160)
{
i = i - 1;
count = count+1;
if(i == 0)
break;
}
if((count/2)*2==count|| count==0)
return 0;
else
return 1;
}
return 0;
}
macro shiftMoveRight()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
stop;
ln = GetBufLnCur(hbuf);
ipos = GetWndSelIchFirst(hwnd);
totalLn = GetBufLineCount(hbuf);
text = GetBufLine(hbuf, ln);
selRec = GetWndSel(hwnd);
curLen = GetBufLineLength(hbuf, selRec.lnLast);
if(selRec.ichLim == curLen+1 || curLen == 0)
{
if(selRec.lnLast == totalLn -1)
stop;
selRec.lnLast = selRec.lnLast + 1;
selRec.ichLim = 1;
SetWndSel(hwnd, selRec);
if(IsShiftRightComplexCharacter())
shiftMoveRight();
stop;
}
selRec.ichLim = selRec.ichLim+1;
SetWndSel(hwnd, selRec);
}
macro SuperShiftCursorRight()
{
if(IsComplexCharacter())
SuperCursorRight();
shiftMoveRight();
if(IsShiftRightComplexCharacter())
shiftMoveRight();
}
/*6、shift+左移键——ShiftCursorLeft.em*/
macro IsShiftLeftComplexCharacter()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
return 0;
selRec = GetWndSel(hwnd);
pos = selRec.ichFirst;
ln = selRec.lnFirst;
text = GetBufLine(hbuf, ln);
len = strlen(text);
if(len == 0 || len < pos)
return 1;
//Msg("@len@;@pos@;");
if(pos > 0)
{
i=pos;
count=0;
while(AsciiFromChar(text[i-1]) >= 160)
{
i = i - 1;
count = count+1;
if(i == 0)
break;
}
if((count/2)*2==count|| count==0)
return 0;
else
return 1;
}
return 0;
}
macro shiftMoveLeft()
{
hwnd = GetCurrentWnd();
hbuf = GetCurrentBuf();
if (hbuf == 0)
stop;
ln = GetBufLnCur(hbuf);
ipos = GetWndSelIchFirst(hwnd);
totalLn = GetBufLineCount(hbuf);
text = GetBufLine(hbuf, ln);
selRec = GetWndSel(hwnd);
//curLen = GetBufLineLength(hbuf, selRec.lnFirst);
//Msg("@curLen@;@selRec@");
if(selRec.ichFirst == 0)
{
if(selRec.lnFirst == 0)
stop;
selRec.lnFirst = selRec.lnFirst - 1;
selRec.ichFirst = GetBufLineLength(hbuf, selRec.lnFirst)-1;
SetWndSel(hwnd, selRec);
if(IsShiftLeftComplexCharacter())
shiftMoveLeft();
stop;
}
selRec.ichFirst = selRec.ichFirst-1;
SetWndSel(hwnd, selRec);
}
macro SuperShiftCursorLeft()
{
if(IsComplexCharacter())
SuperCursorLeft();
shiftMoveLeft();
if(IsShiftLeftComplexCharacter())
shiftMoveLeft();
}