Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Tabby
提交
589b7ea4
T
Tabby
项目概览
后端镜像
/
Tabby
通知
37
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Tabby
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
589b7ea4
编写于
6月 13, 2019
作者:
E
Eugene Pankov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
bumped xterm
上级
2505ee89
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
22 addition
and
416 deletion
+22
-416
terminus-terminal/package.json
terminus-terminal/package.json
+4
-2
terminus-terminal/src/frontends/xtermAddonFit.ts
terminus-terminal/src/frontends/xtermAddonFit.ts
+0
-79
terminus-terminal/src/frontends/xtermFrontend.ts
terminus-terminal/src/frontends/xtermFrontend.ts
+5
-4
terminus-terminal/src/frontends/xtermSearchAddon.ts
terminus-terminal/src/frontends/xtermSearchAddon.ts
+0
-328
terminus-terminal/yarn.lock
terminus-terminal/yarn.lock
+13
-3
未找到文件。
terminus-terminal/package.json
浏览文件 @
589b7ea4
...
...
@@ -31,8 +31,10 @@
"runes"
:
"^0.4.2"
,
"slug"
:
"^1.1.0"
,
"uuid"
:
"^3.3.2"
,
"xterm"
:
"https://registry.npmjs.org/@terminus-term/xterm/-/xterm-3.14.1.tgz"
,
"xterm-addon-ligatures"
:
"^0.1.0-beta-2"
"xterm"
:
"https://registry.npmjs.org/@terminus-term/xterm/-/xterm-3.14.2.tgz"
,
"xterm-addon-fit"
:
"^0.1.0-beta3"
,
"xterm-addon-ligatures"
:
"^0.1.0-beta-2"
,
"xterm-addon-search"
:
"^0.1.0-beta6"
},
"peerDependencies"
:
{
"@angular/common"
:
"4.0.1"
,
...
...
terminus-terminal/src/frontends/xtermAddonFit.ts
已删除
100644 → 0
浏览文件 @
2505ee89
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/
import
{
Terminal
,
ITerminalAddon
}
from
'
xterm
'
;
interface
ITerminalDimensions
{
/**
* The number of rows in the terminal.
*/
rows
:
number
;
/**
* The number of columns in the terminal.
*/
cols
:
number
;
}
export
class
FitAddon
implements
ITerminalAddon
{
private
_terminal
:
Terminal
|
undefined
;
constructor
()
{}
public
activate
(
terminal
:
Terminal
):
void
{
this
.
_terminal
=
terminal
;
}
public
dispose
():
void
{}
public
fit
():
void
{
const
dims
=
this
.
proposeDimensions
();
if
(
!
dims
||
!
this
.
_terminal
)
{
return
;
}
// TODO: Remove reliance on private API
const
core
=
(
<
any
>
this
.
_terminal
).
_core
;
// Force a full render
if
(
this
.
_terminal
.
rows
!==
dims
.
rows
||
this
.
_terminal
.
cols
!==
dims
.
cols
)
{
core
.
_renderCoordinator
.
clear
();
this
.
_terminal
.
resize
(
dims
.
cols
,
dims
.
rows
);
}
}
public
proposeDimensions
():
ITerminalDimensions
|
undefined
{
if
(
!
this
.
_terminal
)
{
return
undefined
;
}
if
(
!
this
.
_terminal
.
element
.
parentElement
)
{
return
undefined
;
}
// TODO: Remove reliance on private API
const
core
=
(
<
any
>
this
.
_terminal
).
_core
;
const
parentElementStyle
=
window
.
getComputedStyle
(
this
.
_terminal
.
element
.
parentElement
);
const
parentElementHeight
=
parseInt
(
parentElementStyle
.
getPropertyValue
(
'
height
'
));
const
parentElementWidth
=
Math
.
max
(
0
,
parseInt
(
parentElementStyle
.
getPropertyValue
(
'
width
'
)));
const
elementStyle
=
window
.
getComputedStyle
(
this
.
_terminal
.
element
);
const
elementPadding
=
{
top
:
parseInt
(
elementStyle
.
getPropertyValue
(
'
padding-top
'
)),
bottom
:
parseInt
(
elementStyle
.
getPropertyValue
(
'
padding-bottom
'
)),
right
:
parseInt
(
elementStyle
.
getPropertyValue
(
'
padding-right
'
)),
left
:
parseInt
(
elementStyle
.
getPropertyValue
(
'
padding-left
'
))
};
const
elementPaddingVer
=
elementPadding
.
top
+
elementPadding
.
bottom
;
const
elementPaddingHor
=
elementPadding
.
right
+
elementPadding
.
left
;
const
availableHeight
=
parentElementHeight
-
elementPaddingVer
;
const
availableWidth
=
parentElementWidth
-
elementPaddingHor
-
core
.
viewport
.
scrollBarWidth
;
const
geometry
=
{
cols
:
Math
.
floor
(
availableWidth
/
core
.
_renderCoordinator
.
dimensions
.
actualCellWidth
),
rows
:
Math
.
floor
(
availableHeight
/
core
.
_renderCoordinator
.
dimensions
.
actualCellHeight
)
};
return
geometry
;
}
}
terminus-terminal/src/frontends/xtermFrontend.ts
浏览文件 @
589b7ea4
import
{
Frontend
}
from
'
./frontend
'
import
{
Terminal
,
ITheme
}
from
'
xterm
'
import
{
getCSSFontFamily
}
from
'
../utils
'
import
{
FitAddon
}
from
'
./xtermAddonF
it
'
import
{
FitAddon
}
from
'
xterm-addon-f
it
'
import
{
enableLigatures
}
from
'
xterm-addon-ligatures
'
import
{
SearchAddon
,
ISearchOptions
}
from
'
./xtermSearchAddon
'
import
{
SearchAddon
,
ISearchOptions
}
from
'
xterm-addon-search
'
import
'
./xterm.css
'
import
deepEqual
=
require
(
'
deep-equal
'
)
import
{
Attributes
,
AttributeData
,
CellData
}
from
'
xterm/src/co
re
/buffer/BufferLine
'
import
{
Attributes
,
AttributeData
,
CellData
}
from
'
xterm/src/co
mmon
/buffer/BufferLine
'
const
COLOR_NAMES
=
[
'
black
'
,
'
red
'
,
'
green
'
,
'
yellow
'
,
'
blue
'
,
'
magenta
'
,
'
cyan
'
,
'
white
'
,
...
...
@@ -83,8 +83,9 @@ export class XTermFrontend extends Frontend {
this
.
resizeHandler
=
()
=>
{
try
{
this
.
fitAddon
.
fit
()
}
catch
{
}
catch
(
e
)
{
// tends to throw when element wasn't shown yet
console
.
warn
(
'
Could not resize xterm
'
,
e
)
}
}
...
...
terminus-terminal/src/frontends/xtermSearchAddon.ts
已删除
100644 → 0
浏览文件 @
2505ee89
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/
import
{
Terminal
,
IDisposable
,
ITerminalAddon
}
from
'
xterm
'
export
interface
ISearchOptions
{
regex
?:
boolean
wholeWord
?:
boolean
caseSensitive
?:
boolean
incremental
?:
boolean
}
export
interface
ISearchResult
{
term
:
string
col
:
number
row
:
number
}
const
NON_WORD_CHARACTERS
=
'
~!@#$%^&*()+`-=[]{}|
\
;:"
\'
,./<>?
'
const
LINES_CACHE_TIME_TO_LIVE
=
15
*
1000
// 15 secs
export
class
SearchAddon
implements
ITerminalAddon
{
private
_terminal
:
Terminal
|
undefined
private
_linesCache
:
string
[]
|
undefined
private
_linesCacheTimeoutId
=
0
private
_cursorMoveListener
:
IDisposable
|
undefined
private
_resizeListener
:
IDisposable
|
undefined
public
activate
(
terminal
:
Terminal
):
void
{
this
.
_terminal
=
terminal
}
public
dispose
():
void
{}
public
findNext
(
term
:
string
,
searchOptions
?:
ISearchOptions
):
boolean
{
if
(
!
this
.
_terminal
)
{
throw
new
Error
(
'
Cannot use addon until it has been loaded
'
)
}
if
(
!
term
||
term
.
length
===
0
)
{
this
.
_terminal
.
clearSelection
()
return
false
}
let
startCol
:
number
=
0
let
startRow
=
this
.
_terminal
.
buffer
.
viewportY
if
(
this
.
_terminal
.
hasSelection
())
{
const
incremental
=
searchOptions
?
searchOptions
.
incremental
:
false
// Start from the selection end if there is a selection
// For incremental search, use existing row
const
currentSelection
=
this
.
_terminal
.
getSelectionPosition
()
!
startRow
=
incremental
?
currentSelection
.
startRow
:
currentSelection
.
endRow
startCol
=
incremental
?
currentSelection
.
startColumn
:
currentSelection
.
endColumn
}
this
.
_initLinesCache
()
// A row that has isWrapped = false
let
findingRow
=
startRow
// index of beginning column that _findInLine need to scan.
let
cumulativeCols
=
startCol
// If startRow is wrapped row, scan for unwrapped row above.
// So we can start matching on wrapped line from long unwrapped line.
let
currentLine
=
this
.
_terminal
.
buffer
.
getLine
(
findingRow
)
while
(
currentLine
&&
currentLine
.
isWrapped
)
{
cumulativeCols
+=
this
.
_terminal
.
cols
currentLine
=
this
.
_terminal
.
buffer
.
getLine
(
--
findingRow
)
}
// Search startRow
let
result
=
this
.
_findInLine
(
term
,
findingRow
,
cumulativeCols
,
searchOptions
)
// Search from startRow + 1 to end
if
(
!
result
)
{
for
(
let
y
=
startRow
+
1
;
y
<
this
.
_terminal
.
buffer
.
baseY
+
this
.
_terminal
.
rows
;
y
++
)
{
// If the current line is wrapped line, increase index of column to ignore the previous scan
// Otherwise, reset beginning column index to zero with set new unwrapped line index
result
=
this
.
_findInLine
(
term
,
y
,
0
,
searchOptions
)
if
(
result
)
{
break
}
}
}
// Search from the top to the startRow (search the whole startRow again in
// case startCol > 0)
if
(
!
result
)
{
for
(
let
y
=
0
;
y
<
findingRow
;
y
++
)
{
result
=
this
.
_findInLine
(
term
,
y
,
0
,
searchOptions
)
if
(
result
)
{
break
}
}
}
// Set selection and scroll if a result was found
return
this
.
_selectResult
(
result
)
}
public
findPrevious
(
term
:
string
,
searchOptions
?:
ISearchOptions
):
boolean
{
if
(
!
this
.
_terminal
)
{
throw
new
Error
(
'
Cannot use addon until it has been loaded
'
)
}
if
(
!
term
||
term
.
length
===
0
)
{
this
.
_terminal
.
clearSelection
()
return
false
}
const
isReverseSearch
=
true
let
startRow
=
this
.
_terminal
.
buffer
.
viewportY
+
this
.
_terminal
.
rows
-
1
let
startCol
=
this
.
_terminal
.
cols
if
(
this
.
_terminal
.
hasSelection
())
{
// Start from the selection start if there is a selection
const
currentSelection
=
this
.
_terminal
.
getSelectionPosition
()
!
startRow
=
currentSelection
.
startRow
startCol
=
currentSelection
.
startColumn
}
this
.
_initLinesCache
()
// Search startRow
let
result
=
this
.
_findInLine
(
term
,
startRow
,
startCol
,
searchOptions
,
isReverseSearch
)
// Search from startRow - 1 to top
if
(
!
result
)
{
// If the line is wrapped line, increase number of columns that is needed to be scanned
// Se we can scan on wrapped line from unwrapped line
let
cumulativeCols
=
this
.
_terminal
.
cols
if
(
this
.
_terminal
.
buffer
.
getLine
(
startRow
)
!
.
isWrapped
)
{
cumulativeCols
+=
startCol
}
for
(
let
y
=
startRow
-
1
;
y
>=
0
;
y
--
)
{
result
=
this
.
_findInLine
(
term
,
y
,
cumulativeCols
,
searchOptions
,
isReverseSearch
)
if
(
result
)
{
break
}
// If the current line is wrapped line, increase scanning range,
// preparing for scanning on unwrapped line
const
line
=
this
.
_terminal
.
buffer
.
getLine
(
y
)
if
(
line
&&
line
.
isWrapped
)
{
cumulativeCols
+=
this
.
_terminal
.
cols
}
else
{
cumulativeCols
=
this
.
_terminal
.
cols
}
}
}
// Search from the bottom to startRow (search the whole startRow again in
// case startCol > 0)
if
(
!
result
)
{
const
searchFrom
=
this
.
_terminal
.
buffer
.
baseY
+
this
.
_terminal
.
rows
-
1
let
cumulativeCols
=
this
.
_terminal
.
cols
for
(
let
y
=
searchFrom
;
y
>=
startRow
;
y
--
)
{
result
=
this
.
_findInLine
(
term
,
y
,
cumulativeCols
,
searchOptions
,
isReverseSearch
)
if
(
result
)
{
break
}
const
line
=
this
.
_terminal
.
buffer
.
getLine
(
y
)
if
(
line
&&
line
.
isWrapped
)
{
cumulativeCols
+=
this
.
_terminal
.
cols
}
else
{
cumulativeCols
=
this
.
_terminal
.
cols
}
}
}
// Set selection and scroll if a result was found
return
this
.
_selectResult
(
result
)
}
private
_initLinesCache
():
void
{
const
terminal
=
this
.
_terminal
!
if
(
!
this
.
_linesCache
)
{
this
.
_linesCache
=
new
Array
(
terminal
.
buffer
.
length
)
this
.
_cursorMoveListener
=
terminal
.
onCursorMove
(()
=>
this
.
_destroyLinesCache
())
this
.
_resizeListener
=
terminal
.
onResize
(()
=>
this
.
_destroyLinesCache
())
}
window
.
clearTimeout
(
this
.
_linesCacheTimeoutId
)
this
.
_linesCacheTimeoutId
=
window
.
setTimeout
(()
=>
this
.
_destroyLinesCache
(),
LINES_CACHE_TIME_TO_LIVE
)
}
private
_destroyLinesCache
():
void
{
this
.
_linesCache
=
undefined
if
(
this
.
_cursorMoveListener
)
{
this
.
_cursorMoveListener
.
dispose
()
this
.
_cursorMoveListener
=
undefined
}
if
(
this
.
_resizeListener
)
{
this
.
_resizeListener
.
dispose
()
this
.
_resizeListener
=
undefined
}
if
(
this
.
_linesCacheTimeoutId
)
{
window
.
clearTimeout
(
this
.
_linesCacheTimeoutId
)
this
.
_linesCacheTimeoutId
=
0
}
}
private
_isWholeWord
(
searchIndex
:
number
,
line
:
string
,
term
:
string
):
boolean
{
return
(((
searchIndex
===
0
)
||
(
NON_WORD_CHARACTERS
.
indexOf
(
line
[
searchIndex
-
1
])
!==
-
1
))
&&
(((
searchIndex
+
term
.
length
)
===
line
.
length
)
||
(
NON_WORD_CHARACTERS
.
indexOf
(
line
[
searchIndex
+
term
.
length
])
!==
-
1
)))
}
protected
_findInLine
(
term
:
string
,
row
:
number
,
col
:
number
,
searchOptions
:
ISearchOptions
=
{},
isReverseSearch
:
boolean
=
false
):
ISearchResult
|
undefined
{
const
terminal
=
this
.
_terminal
!
// Ignore wrapped lines, only consider on unwrapped line (first row of command string).
const
firstLine
=
terminal
.
buffer
.
getLine
(
row
)
if
(
firstLine
&&
firstLine
.
isWrapped
)
{
return
null
}
let
stringLine
=
this
.
_linesCache
?
this
.
_linesCache
[
row
]
:
void
0
if
(
stringLine
===
void
0
)
{
stringLine
=
this
.
_translateBufferLineToStringWithWrap
(
row
,
true
)
if
(
this
.
_linesCache
)
{
this
.
_linesCache
[
row
]
=
stringLine
}
}
const
searchTerm
=
searchOptions
.
caseSensitive
?
term
:
term
.
toLowerCase
()
const
searchStringLine
=
searchOptions
.
caseSensitive
?
stringLine
:
stringLine
.
toLowerCase
()
let
resultIndex
=
-
1
if
(
searchOptions
.
regex
)
{
const
searchRegex
=
RegExp
(
searchTerm
,
'
g
'
)
let
foundTerm
:
RegExpExecArray
|
null
if
(
isReverseSearch
)
{
// This loop will get the resultIndex of the _last_ regex match in the range 0..col
while
(
foundTerm
=
searchRegex
.
exec
(
searchStringLine
.
slice
(
0
,
col
)))
{
resultIndex
=
searchRegex
.
lastIndex
-
foundTerm
[
0
].
length
term
=
foundTerm
[
0
]
searchRegex
.
lastIndex
-=
(
term
.
length
-
1
)
}
}
else
{
foundTerm
=
searchRegex
.
exec
(
searchStringLine
.
slice
(
col
))
if
(
foundTerm
&&
foundTerm
[
0
].
length
>
0
)
{
resultIndex
=
col
+
(
searchRegex
.
lastIndex
-
foundTerm
[
0
].
length
)
term
=
foundTerm
[
0
]
}
}
}
else
{
if
(
isReverseSearch
)
{
if
(
col
-
searchTerm
.
length
>=
0
)
{
resultIndex
=
searchStringLine
.
lastIndexOf
(
searchTerm
,
col
-
searchTerm
.
length
)
}
}
else
{
resultIndex
=
searchStringLine
.
indexOf
(
searchTerm
,
col
)
}
}
if
(
resultIndex
>=
0
)
{
// Adjust the row number and search index if needed since a "line" of text can span multiple rows
if
(
resultIndex
>=
terminal
.
cols
)
{
row
+=
Math
.
floor
(
resultIndex
/
terminal
.
cols
)
resultIndex
=
resultIndex
%
terminal
.
cols
}
if
(
searchOptions
.
wholeWord
&&
!
this
.
_isWholeWord
(
resultIndex
,
searchStringLine
,
term
))
{
return
null
}
const
line
=
terminal
.
buffer
.
getLine
(
row
)
if
(
line
)
{
for
(
let
i
=
0
;
i
<
resultIndex
;
i
++
)
{
const
cell
=
line
.
getCell
(
i
)
if
(
!
cell
)
{
break
}
// Adjust the searchIndex to normalize emoji into single chars
const
char
=
cell
.
char
if
(
char
.
length
>
1
)
{
resultIndex
-=
char
.
length
-
1
}
// Adjust the searchIndex for empty characters following wide unicode
// chars (eg. CJK)
const
charWidth
=
cell
.
width
if
(
charWidth
===
0
)
{
resultIndex
++
}
}
}
return
{
term
,
col
:
resultIndex
,
row
}
}
return
null
}
private
_translateBufferLineToStringWithWrap
(
lineIndex
:
number
,
trimRight
:
boolean
):
string
{
const
terminal
=
this
.
_terminal
!
let
lineString
=
''
let
lineWrapsToNext
:
boolean
do
{
const
nextLine
=
terminal
.
buffer
.
getLine
(
lineIndex
+
1
)
lineWrapsToNext
=
nextLine
?
nextLine
.
isWrapped
:
false
const
line
=
terminal
.
buffer
.
getLine
(
lineIndex
)
if
(
!
line
)
{
break
}
lineString
+=
line
.
translateToString
(
!
lineWrapsToNext
&&
trimRight
).
substring
(
0
,
terminal
.
cols
)
lineIndex
++
}
while
(
lineWrapsToNext
)
return
lineString
}
private
_selectResult
(
result
:
ISearchResult
|
undefined
):
boolean
{
const
terminal
=
this
.
_terminal
!
if
(
!
result
)
{
terminal
.
clearSelection
()
return
false
}
terminal
.
select
(
result
.
col
,
result
.
row
,
result
.
term
.
length
)
terminal
.
scrollLines
(
result
.
row
-
terminal
.
buffer
.
viewportY
)
return
true
}
}
terminus-terminal/yarn.lock
浏览文件 @
589b7ea4
...
...
@@ -246,6 +246,11 @@ windows-native-registry@^1.0.14:
dependencies:
nan "^2.13.2"
xterm-addon-fit@^0.1.0-beta3:
version "0.1.0-beta3"
resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.1.0-beta3.tgz#82bc2474cb00a2872d9a43ea52ed801bdfeebeaf"
integrity sha512-5UWwCH3smDWlqskK8r0GcCgLPvwbJiPpKiM01E67g5HIrQqCxITKawc01cuKCDLVj03sFJB9jDCOoh0n0mN+Zw==
xterm-addon-ligatures@^0.1.0-beta-2:
version "0.1.0-beta-2"
resolved "https://registry.yarnpkg.com/xterm-addon-ligatures/-/xterm-addon-ligatures-0.1.0-beta-2.tgz#def635fd0ca671fe61179629f8492b76c66dec6e"
...
...
@@ -254,9 +259,14 @@ xterm-addon-ligatures@^0.1.0-beta-2:
font-finder "^1.0.2"
font-ligatures "^1.3.1"
"xterm@https://registry.npmjs.org/@terminus-term/xterm/-/xterm-3.14.1.tgz":
version "3.14.1"
resolved "https://registry.npmjs.org/@terminus-term/xterm/-/xterm-3.14.1.tgz#f3f7c0b4726fc60c22af17bac95c1b8058eca317"
xterm-addon-search@^0.1.0-beta6:
version "0.1.0-beta6"
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.1.0-beta6.tgz#e2a2b441f8f7b0245c63731d0b2af32c7d4e6747"
integrity sha512-XKxdfO48HkCJW2m1wXW0PK/BOk00WEaN+W2LgDQqCBwwUjyBzWc9HaV8gzLXhSCDAYesWvtQa3RfqHfSp9qsbQ==
"xterm@https://registry.npmjs.org/@terminus-term/xterm/-/xterm-3.14.2.tgz":
version "3.14.2"
resolved "https://registry.npmjs.org/@terminus-term/xterm/-/xterm-3.14.2.tgz#3ad13ca05ef024e8fb993d5c8320ca56a43eaf8e"
yallist@^2.1.2:
version "2.1.2"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录