[Question]
  [
It is common to need to make a page selection interface. It typically looks like this:
```
prev 1 ... 3 4 [5] 6 7 ... 173 next
```
Which means there are totally 173 pages, and you are on the 5th page currently.
This challenge requires you take the total number of pages and the current page number as input, and output a string (or an array) to "display" the page selector.
## Input
2 positive integers
* current page number
* count of pages
It is guaranteed that 1 <= current <= total.
## Output
Output a string or an array which represent the ui for page selectors.
* If output as string, a single space (U+0020) should be used between each pages.
* If output as an array, the array should produce same result as the string after convert each item to string and join them with a single space.
	+ The three dots (`...`) is not optional for array output.
## Details
* If current == 1, no "prev" will be outputted, otherwise, "prev" comes first.
* If current == total, no "next" will be outputted, otherwise, "next" comes last.
* The first page (1) and the last page (total) should always be outputted.
* The current page, (current - 1) page, (current - 2) page, (current + 1) page, (current + 2) page should be outputted as long as the are in the range of [1..total].
* No other pages numbers should be outputted.
* Pages outputted should be sorted in ascending order.
* Output should not contain duplicate page numbers.
* Current page should be highlighted by wrap it in a pair of `[]`.
* If there is a gap between any neighbors, three dots (`...`) should be inserted.
## Test Cases
```
Current Total    Output
1       1        [1]
1       2        [1] 2 next
1       10       [1] 2 3 ... 10 next
3       3        prev 1 2 [3]
3       6        prev 1 2 [3] 4 5 6 next
4       6        prev 1 2 3 [4] 5 6 next
4       7        prev 1 2 3 [4] 5 6 7 next
3       10       prev 1 2 [3] 4 5 ... 10 next
5       10       prev 1 ... 3 4 [5] 6 7 ... 10 next
10      10       prev 1 ... 8 9 [10]
52      173      prev 1 ... 50 51 [52] 53 54 ... 173 next
```
## Rules
* This is code-golf, the shortest code wins!
  
[Answer]
# [Retina](https://github.com/m-ender/retina), ~~125~~ ~~113~~ ~~109~~ 107 bytes
```
.+
$*
r`1\G
 1$'
¶
O`1+
\b(1+) \1\b
[$1]
 .* (1+ 1+ \[)|(] 1+ 1+) .* 
$2 ... $1
^1
prev 1
1$
1 next
1+
$.&
```
[Try it online!](https://tio.run/##HYw9CsJQEIT7OcUUq@YHHpkE9QiWFpZ5kRhIYSMSglh4Lg/gxZ6bwH7DzFfsNM73xy1tskvPFEpYgalXPIGyHX5f4NyrRBwylTmj4oDW1IGhoCv6xTb/ZB3XkS8eVjOEQBOuwnMaXxRkEB/je4a/s7BNSYtl7ahCw8Y5OD72S6haa00dmz8 "Retina – Try It Online") Link includes test cases. Saved 12 bytes thanks to @MartinEnder. Explanation:
```
.+
$*
```
Convert to unary.
```
r`1\G
 1$'
```
Generate all the page numbers in reverse order.
```
¶
```
Delete the newline separating the input. (There's also a space there from the page number generation anyway.)
```
O`1+
```
Sort the pages back into ascending order. This also sorts the current page, which is now duplicated.
```
\b(1+) \1\b
[$1]
```
Unduplicate and wrap `[]`s around the current page.
```
 .* (1+ 1+ \[)|(] 1+ 1+) .* 
$2 ... $1
```
Add an ellipsis if the current page is at least 5, or if there are at least 4 pages after the current page. (Note trailing space, to avoid including the last page in the ellipsis.)
```
^1
prev 1
```
Add the prev if the current page is not 1.
```
1$
1 next
```
Add the next if the current page is not the last page.
```
1+
$.&
```
Convert back to decimal.
[Answer]
# JavaScript (ES6), ~~130~~ ~~122~~ 121 bytes
Invoke with currying syntax, e.g. `f(3)(10)`.
```
x=>X=>[x>1&&'prev 1',x>4&&'...',x>3&&x-2,x>2&&x-1,`[${x}]`,(X-=x)>1&&x+1,X>2&&x+2,X>3&&'...',X&&X+x+' next'].filter(_=>_)
```
```
f=
x=>X=>[x>1&&'prev 1',x>4&&'...',x>3&&x-2,x>2&&x-1,`[${x}]`,(X-=x)>1&&x+1,X>2&&x+2,X>3&&'...',X&&X+x+' next'].filter(_=>_)
console.log(f(1)(1))
console.log(f(1)(2))
console.log(f(1)(10))
console.log(f(3)(3))
console.log(f(3)(6))
console.log(f(4)(6))
console.log(f(4)(7))
console.log(f(3)(10))
console.log(f(5)(10))
console.log(f(10)(10))
console.log(f(52)(173))
```
[Try it online!](https://tio.run/##ZY7haoMwFIVf5VKGGozBm5i6UfQ5hBBqaXVYrClWSmDs2V2sbsUV8uPcc797Ts6H@@F27JvrEHXmVI1tppRCippuFOqNptPE5wk4dJUdFhPjP1cAYwwwfq4FFW577as7oAOU0Iu9/WdDAhK2z8NkTQhQiV4Tcm5ekKlYuBAltYPSl49g/IK/wwc4f/6R5BRTsQZkDBJdInfNAmQyh6ZiSdW7SzbaLC@yXNkcPc@fb31q88RNjp6k8DwbcSf4JJCW6u3LfuuSBkWUWTId2hBp8diH3Anxe1x4XhHa0H8U@prVTTtUfbDP8j0Za9ND0ICpoSVwNN3NtBVrzWdwCRoVa/fILFATdjZNV0JJduMP)
*-1 byte (Arnauld): Set `X` to `X-x`.*
[Answer]
# [6502 machine code](https://en.wikibooks.org/wiki/6502_Assembly) (C64), 160 bytes
```
00 C0 20 9B B7 86 FB CA F0 01 CA 86 FD 20 9B B7 86 FC A6 FB E8 E4 FC B0 01 E8
86 FE A2 01 E4 FB F0 1A A9 91 A0 C0 20 1E AB A2 02 E4 FD B0 0D A9 2E 20 D2 FF
CA 10 FA 20 3F AB A6 FD 86 9E E4 FB D0 05 A9 5B 20 D2 FF A9 00 20 CD BD A6 9E
E4 FB D0 05 A9 5D 20 D2 FF 20 3F AB A6 9E E4 FC F0 25 E4 FE F0 05 E8 86 9E D0
D5 E8 E4 FC F0 0D A2 02 A9 2E 20 D2 FF CA 10 FA 20 3F AB A6 FC A9 00 20 CD BD
20 3F AB A6 FC E4 FB F0 07 A9 99 A0 C0 20 1E AB 60 50 52 45 56 20 31 20 00 4E
45 58 54 00
```
**[Online demo](https://vice.janicek.co/c64/#%7B"controlPort2":"joystick","primaryControlPort":2,"keys":%7B"SPACE":"","RETURN":"","F1":"","F3":"","F5":"","F7":""%7D,"files":%7B"page.prg":"data:;base64,AMAgm7eG+8rwAcqG/SCbt4b8pvvo5PywAeiG/qIB5PvwGqmRoMAgHquiAuT9sA2pLiDS/8oQ+iA/q6b9hp7k+9AFqVsg0v+pACDNvaae5PvQBaldINL/ID+rpp7k/PAl5P7wBeiGntDV6OT88A2iAqkuINL/yhD6ID+rpvypACDNvSA/q6b85PvwB6mZoMAgHqtgUFJFViAxIABORVhUAA=="%7D,"vice":%7B"-autostart":"page.prg"%7D%7D)** -- **Usage:** `sys49152,[current],[total]`, e.g. `sys49152,5,173`.
The numbers must be in the range [1..255] with current <= total. As this wasn't specified otherwise, this is the "natural" unsigned integer range on an 8bit processor.
---
Explanation as commented disassembly listing:
```
         00 C0       .WORD $C000        ; load address
.C:c000  20 9B B7    JSR $B79B          ; read 8bit integer
.C:c003  86 FB       STX $FB            ; store current page
.C:c005  CA          DEX                ; calculate lower start for ...
.C:c006  F0 01       BEQ .stl
.C:c008  CA          DEX
.C:c009   .stl:
.C:c009  86 FD       STX $FD            ; ... range and store
.C:c00b  20 9B B7    JSR $B79B          ; read 8bit integer
.C:c00e  86 FC       STX $FC            ; store total pages
.C:c010  A6 FB       LDX $FB            ; load current page
.C:c012  E8          INX                ; calculate upper end for ...
.C:c013  E4 FC       CPX $FC
.C:c015  B0 01       BCS .stu
.C:c017  E8          INX
.C:c018   .stu:
.C:c018  86 FE       STX $FE            ; ... range and store
.C:c01a  A2 01       LDX #$01           ; check whether first page is current
.C:c01c  E4 FB       CPX $FB
.C:c01e  F0 1A       BEQ .sequence      ; then directly to sequence
.C:c020  A9 91       LDA #<.prev        ; output string for ...
.C:c022  A0 C0       LDY #>.prev
.C:c024  20 1E AB    JSR $AB1E          ; ... "prev 1 "
.C:c027  A2 02       LDX #$02           ; check whether page 2 is in range ...
.C:c029  E4 FD       CPX $FD
.C:c02b  B0 0D       BCS .sequence      ; ... then directly to sequence
.C:c02d  A9 2E       LDA #$2E           ; load character '.'
.C:c02f   .ellip1:
.C:c02f  20 D2 FF    JSR $FFD2          ; output ...
.C:c032  CA          DEX
.C:c033  10 FA       BPL .ellip1        ; ... 3 times
.C:c035  20 3F AB    JSR $AB3F          ; output space
.C:c038  A6 FD       LDX $FD            ; load lower start for range
.C:c03a   .sequence:
.C:c03a  86 9E       STX $9E            ; store to temporary
.C:c03c   .seqloop:
.C:c03c  E4 FB       CPX $FB            ; compare with current
.C:c03e  D0 05       BNE .notcurrent1   ; yes -> output '['
.C:c040  A9 5B       LDA #$5B
.C:c042  20 D2 FF    JSR $FFD2
.C:c045   .notcurrent1:
.C:c045  A9 00       LDA #$00
.C:c047  20 CD BD    JSR $BDCD          ; output number
.C:c04a  A6 9E       LDX $9E            ; compare with current
.C:c04c  E4 FB       CPX $FB
.C:c04e  D0 05       BNE .notcurrent2   ; yes -> output ']'
.C:c050  A9 5D       LDA #$5D
.C:c052  20 D2 FF    JSR $FFD2
.C:c055   .notcurrent2:
.C:c055  20 3F AB    JSR $AB3F          ; output space
.C:c058  A6 9E       LDX $9E
.C:c05a  E4 FC       CPX $FC            ; compare position with last page
.C:c05c  F0 25       BEQ .printnext     ; if eq jump to part printing "next"
.C:c05e  E4 FE       CPX $FE            ; compare position to upper end of range
.C:c060  F0 05       BEQ .printellip2   ; if eq jump to part printing "..."
.C:c062  E8          INX
.C:c063  86 9E       STX $9E            ; next number
.C:c065  D0 D5       BNE .seqloop       ; and repeat loop for sequence
.C:c067   .printellip2:
.C:c067  E8          INX
.C:c068  E4 FC       CPX $FC            ; compare next number with last page
.C:c06a  F0 0D       BEQ .printlast     ; if eq jump to part printing page num
.C:c06c  A2 02       LDX #$02
.C:c06e  A9 2E       LDA #$2E           ; load character '.'
.C:c070   .ellip2:
.C:c070  20 D2 FF    JSR $FFD2          ; output ...
.C:c073  CA          DEX
.C:c074  10 FA       BPL .ellip2        ; ... 3 times
.C:c076  20 3F AB    JSR $AB3F          ; output space
.C:c079   .printlast:
.C:c079  A6 FC       LDX $FC            ; output last page number
.C:c07b  A9 00       LDA #$00
.C:c07d  20 CD BD    JSR $BDCD
.C:c080  20 3F AB    JSR $AB3F          ; output space
.C:c083   .printnext:
.C:c083  A6 FC       LDX $FC            ; compare current page with last page
.C:c085  E4 FB       CPX $FB
.C:c087  F0 07       BEQ .done          ; if eq nothing else to do
.C:c089  A9 99       LDA #<.next        ; output string for ...
.C:c08b  A0 C0       LDY #>.next
.C:c08d  20 1E AB    JSR $AB1E          ; "next"
.C:c090   .done:
.C:c090  60          RTS
.C:c091   .prev:
.C:c091  50 52 45 56 .BYTE "prev"
.C:c095  20 31 20 00 .BYTE " 1 ", $00
.C:c099   .next:
.C:c099  4E 45 58 54 .BYTE "next"
.C:c09d  00          .BYTE $00
```
[Answer]
# [R](https://www.r-project.org/), ~~214 bytes~~ 168 bytes
```
function(c,m,`~`=function(x,y)if(x)cat(y)){o=-2:2+c
o=o[o>0&o<=m]
o[o==c]=paste0('[',c,']')
c>1~'prev '
c>3~'1 '
c>4~' ... '
T~o
c+3<m~' ...'
c+2<m~c('',m)
c<m~' next'}
```
[Try it online!](https://tio.run/##VY5BCoMwEEX3nsJVJ8FUjLppcTxFd1ZQBgMuTMTaopTm6nZqodDd@@/zh5k2g5u5W5p7ZwWpQTW@wZ9Y1Cp7IxZJ7SxWKZ8Oj@k5jShw6CpXJgdX4FAHzIhU49je5i4RUIEiBTXIgErtYZy6RwjMmQe9Q@4hjOOY@eJdQFFWDF/DZZRyIAGgBt7vhe2WGV6bEVppdvwMXC1f/4j0X@TqJLc3 "R – Try It Online")
Thanks to @user2390246 for some great golfing tips
[Answer]
# [APL (Dyalog)](https://www.dyalog.com/), ~~83~~ 82 bytes
Anonymous infix function taking current as left argument and total as right argument.
```
{('prev '/⍨⍺>1),('x+'⎕R'...'⍕∊(⊂1⌽'][',⍕)@⍺⊢'x'@(~∊∘(1,⍵,⍺+3-⍳5))⍳⍵),' next'/⍨⍺<⍵}
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///P@1R24RqDfWCotQyBXX9R70rHvXusjPU1NFQr9BWf9Q3NUhdT09P/VHv1EcdXRqPupoMH/XsVY@NVtcBCmk6ABU/6lqkXqHuoFEHVPCoY4aGIVBmKxDv0jbWfdS72VRTE0gChTR11BXyUitKYJbYAMVq//83VEhTMOQCkUZg0tCAyxhIGYNJMzAJFDKFUIYGUK4RiDY3BgA "APL (Dyalog Unicode) – Try It Online")
`{`…`}` explicit lambda where `⍺` and `⍵` represent the left and right arguments:
 `⍺<⍵` is current smaller than total?
 `' next'/⍨` if so (lit. use that to replicate) the text
 `(`…`),` prepend the following:
  `⍳⍵` **ɩ**ntegers 1 through total
  `'x'@(`…`)` replace with an `x` **at** the positions where the items are…
   `~` not
   `∊` members of
   `1` one
   `,` followed by
   `⍵` the total
   `,` followed by
    `⍳5` the first five **ɩ**ntegers (`[1,2,3,4,5]`)
    `3-` subtracted from three (`[2,1,0,-1,-2]`)
    `⍺+` added to the current (`[⍺+2,⍺+1,⍺,⍺-1,⍺-2]`)
   `⊢` yield that (serves to separate `⍺` from `'x'`)
   `(`…`)` apply the following tacit function **at** the current position:
    `⍕` format (stringify)
    `'][',` prepend the text` 
    `1⌽` rotate one step leftward (moves the `]` to the end)
    `⊂` enclose (so that it is a scalar which will fit in the single indicated position)
   `∊` **ϵ**nlist (flatten – because we made it nested when we inserted brackets)
   `⍕` format (stringify – 1 space separating numbers from each other and from `x` runs)
  `'x+'⎕R'...'` PCRE **R**eplace `x` runs with three periods
 `(`…`),` prepend the following:
  `⍺>1` is current larger than 1?
  `'prev '/⍨` if so (lit. use that to replicate) the text
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), ~~131~~ ~~114~~ 109 bytes
```
Range@#2/.{#->"["<>(t=ToString)@#<>"]",1->"prev 1",#2->t@#2<>" next",#-3|#+3:>"...",x_/;Abs[x-#]>2:>Nothing}&
```
[Try it online!](https://tio.run/##DY1RC4IwFEb/itxBFG0TJxGYDvsDEdXbGDFjqQ/OsFsI1W9f9/U7fOcMDjs/OOxvLt5foYonF1pfM5XKDxMaDJR6idVlPOPUh3ZVs1KDBZ4Re0z@nWTAmRIa6UIkCX5GWkT@Zeu80CClBD5f092@eZpZMKtVoQ8jdiT7LeKRpGgobDaKZ9vc2vgH "Wolfram Language (Mathematica) – Try It Online")
## How it works
Lots of replacing. Starting with a list of all pages, replace, in order:
1. `#->"["<>(t=ToString)@#<>"]"`: the current page with a bracketed string,
2. `1->"prev 1"`: page 1 with the string `prev 1`,
3. `#2->t@#2<>" next"`: the last page with the string `(number) next`, with
4. `#-3|#+3:>"..."`: page `current-3` and page `current+3` with the string `"..."`,
5. `x_/;Abs[x-#]>2:>Nothing`: all other (integer) pages below `current-2` or above `current+2` with nothing. (Yes, `Nothing` is a built-in.)
[Answer]
# [Funky](https://github.com/TehFlaminTaco/Funky), ~~218~~ 210 bytes
*Saved some bytes, some of which thanks to [tsh](https://codegolf.stackexchange.com/users/44718/tsh)*
```
p=>m=>{t={}a=t::push b=t::pop fori=p-2i<p+3i++a(i)t[2]="[%i]"%p whilet[0]<1b(0)whilet[n=-1+#t]>m b(n)ifp>4a(0,"...")ifp>3a(0,1)ifp>1a(0,"prev")ifp<m-3a("...")ifp<m-2a(m)ifp<m a("next")t::reduce((a,b)=>a+" "+b)}
```
[Try it online!](https://tio.run/##PY7LasMwEEV/RagEZlBsLKdkETz6EeOF1EpEtFYGV86DkG93HLV0dw7nLm6Y09dtCbQwmZHMPdP9YSkfDjz/HIUrdGIRTlMkrtrYsdpFpSxEzH07kOw3cZAbFpdj/Pa5b4ZOO2jwTxNVWr3lwYzCQcIY2LxbaLayrmtZdPdSXVCXwpM/l9SN1Rr/l6u2FsZfFGtI/polrgcn/zl/eAC7dUjGKimkcvhYeIopQwC9R9i3iMsT "Funky – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/), 135 bytes
```
lambda c,t:re.sub('  +',' ... ','prev '*(c>1)+' '.join(`[x,[x]][x==c]`*(x%t<2or-3<x-c<3)for x in range(1,t+1))+' next'*(c<t))
import re
```
[Try it online!](https://tio.run/##XcxNDoIwEIbhPaeYjWkLpaHgT2KKF0ESoBbFSEtqNfX0CCvB1eTJfHmHj7sZnY5tfh4fdd9capDUHa1iz1eDEUCEKALGGEx3sOoNKMTyxEmEALG76TSuCk8LX5aFz3NZViH2GydSY@NM@FiKjLTGgodOg631VWFOXcTJHNDKuzknHCFB1w/GOrBqHGynHbTTEDgJFkpX4smPGYVspf1Ky@luTZ78vdPJh0VsO8fGLw "Python 2 – Try It Online")
First we create a string like `prev 1 3 4 [5] 6 7 10 next`, which has “gaps” caused by erasing some numbers but not their delimiting spaces. Then we replace any run of 2+ spaces by `...` using a regex.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~136~~ 130 bytes
```
lambda p,n:[i for i,j in zip(['prev',1,'...',p-2,p-1,[p],p+1,p+2,'...',n,'next'],[1,3,4,2,1,.1,-n,1-n,3-n,2-n,-n])if p*cmp(j,0)>j]
```
[Try it online!](https://tio.run/##LctBDsIgFIThvadgB@iUCJgYTfQiyKJqiTT29aVBo16@sujiy7@YDH/LYyQ3p9NlfrbD9d4KBh1DFmmcREYvMolfZhUkT91bwkIaYyS4cZVF4Aje2MotC0FS9ykyIlh47ODqyVg0BFv5ylUNRZ2T4PVtYNVjq899nHnKVERSmfhVlMZSPfv9yh/@ "Python 2 – Try It Online")
> 
> If output as an array, the array should produce same result as the string after convert each item to string and join them with a single space.
> 
> 
> 
[Try it online!](https://tio.run/##LcvNCsIwEATgu0@R26Y6DSYVREFfpPZQf4IJdrvUKOrLxxw68DGHYeSb7iO77A@n/OiH87VXAt63QflxUgFRBVa/ILolmW5vggUZYwhSu8KilQ6ysoWbFwbx7ZOoQ2vRYANXTsaiZtiiKVxRc1cFr2R5GURHrKtj7LJMgRMpMnEMrIde9DNN8DqwvJKuMHdJbraLZvcH "Python 2 – Try It Online") in prettified form, where you can see the footer translates quite literally to "convert each to string, join on spaces".
This is an alternative to Lynn's approach.
[Answer]
# [Octave](https://www.gnu.org/software/octave/), ~~169 196 190 181 175 169~~ 166 bytes
```
@(n,m)(r=[(n>1)*'prev ' (g=n>4)*'1 ... ' (s=@sprintf)(f='%d ',max(n-3+g,1):n-1) s('[%d]',n) 32*(q=n<m) s(f,n+1:min(n+3-(l=n<m-3),m)) l*['... ' s(f,m)] q*'next'])(r>0)
```
[Try it online!](https://tio.run/##Pc7BjoJADAbgu0/Ri2kLA6GMulmzQ3wPwsEoQ0ycrgIxvj2Cxrl9/fsn7f9pPD7aybs8z6cDqQlMvatJK@EEb337AATqnFabeRaYa0swuMNw6y86eibvcH0GNOH4JM1s2hnhvWbCMBDW63ODRhlsmdDd6V9YYm80lX24KGlqM7oueWZ5Ps5wTWr8XFl6gRu4J6jtc8Rmfq0qePIkYASAV2@VUVK8ZcFY@Gr30SbKxt426jdKirgtjfxYnl4 "Octave – Try It Online")
I'll add an explanation later on.
Hmm, seems there were some issues with the output format. These have now been resolved - all outputs are correct. But alas it cost 27 bytes. Managed to claw all of those back though with a bit of fat trimming.
---
* Save 6 bytes by using `*` instead of `.*` - thanks @StewieGriffin
* Save 9 bytes using `sprintf` instead of `num2str` as I already had that handle in `s`.
* Save 6 bytes by pulling `[]` into the `sprint` call.
* Save 6 bytes by finding a way to reduce the number of comparisons.
* Save 3 bytes by removing need for `strtrim()` without causing trailing space.
[Answer]
# Java 8, ~~201~~ ~~200~~ 197 bytes
```
t->n->(n<2?"[1] ":"prev 1 ")+(n>4?"... "+(n-2)+" "+~-n+" ["+n+"] ":n>3?"2 3 [4] ":n>2?"2 [3] ":n>1?"[2] ":"")+(n<t?(n>t-2?"":n>t-3?t-1+" ":n>t-4?(t-2)+" "+~-t+" ":++n+" "+-~n+" ... ")+t+" next":"")
```
**Explanation:**
[Try it here.](https://tio.run/##nVDBboJAEL37FZM9saG7ccG2SUW4NemhJ4/EA0U0a3EhMJiaRn@dzq7UHppUbUJ23mPeezs7m2yXiaouzGb53udl1rbwmmnzOQJoMUOdw4YUskNdylVnctSVkc8DiF4MFuuiubtONMdGm3UcQw4z6FHERsSeiYKEpWoB7InVTbEDBYz7noknCZNSAiMsAu4zQkdhqKbMp2INJg4TFkAI6eREA0vT8EQU5QYu1wVGmFAqCtLYLoowQaFsrmOTxMOfe9D99@1FxMXRVjcN923LFB/ocvspLYq@unsraVfDynaVXsKW1uidnpwuION2pQCrqvG0QdAzNQUdzdSYiu8PXYD5vsViK6sOZU1WLI2Xy6yuy72nxnxAmvOp0x/cObpk5Gcw@P4QB7eIw38lB7ck3yQOv8WXHA@/HNeIJ1eI1eN5mvth9sPo0H8B)
```
t->n->             // Method with two integer parameters and String return-type
  (n<2?            //  If the current page is 1:
    "[1] "         //   Start with literal "[1] "
   :               //  Else:
    "prev 1 ")     //   Start with literal "prev 1"
  +(n>4?           //  +If the current page is larger than 4:
     "... "        //    Append literal "... "
     +(n-2)+" "    //    + the current page minus 2, and a space
     ~-n           //    + the current page minus 1, and a space
     +" ["+n+"] "  //    + "[current_page]" and a space
    :n>3?          //   Else-if the current page is 4:
     "2 3 [4] "    //    Append literal "2 3 [4] "
    :n>2?          //   Else-if the current page is 3:
     "2 [3] "      //    Append literal "2 [3] "
    :n>1?          //   Else-if the current page is 2:
     "[2] "        //    Append literal "[2] "
    :              //   Else (the current page is 1):
     "")           //    Append nothing
  +(n<t?           //  +If the current page and total amount of pages are not the same:
     (n>t-2?       //    If the current page is larger than the total minus 2:
       ""          //     Append nothing
      :n>t-3?      //    Else-if the current page is larger than the total minus 3:
       t-1+" "     //     Append the total minus 1, and a space
      :n>t-4?      //    Else-if the current page is larger than the total minus 4:
       (t-2)+" "   //     Append the total minus 2, and a space
       +~-t+" "    //     + the total minus 1, and a space
      :            //    Else:
       ++n+" "     //     Append the current page plus 1, and a space
       +-~n+       //     + the current page plus 2, and a space
       " ... ")    //     + literal "... "
     +t            //    + the total itself
     +" next")     //    + literal " next"
    :              //   Else (current page and total amount of pages are the same):
     "")           //    Append nothing
                   // End of method (implicit / single-line return-statement)
```
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), ~~218~~ ~~179~~ ~~177~~ ~~167~~ 166 bytes
```
c->t->{String p,e="... ",x="["+c+"] ";int i=c-2;for(p=c>1?"prev 1 "+(c>4?e:""):x;i<c+3;i++)p+=i>1&i<t?i==c?x:i+" ":"";return p+(i<t-1?e:"")+(c<t?t+" next":t>1?x:"");}
```
[Try it online!](https://tio.run/##nZA/b8IwEMX3fIqThyqpidXQf1KMk61Sh3ZhRAzGGGSaOJZzQUGIz05dQdOlC/F0uvd@vnu3k3uZNk7b3frrbGrXeIRd6LEOTcU2nVVoGsvueRS5blUZBaqSbQsf0lg4RlGLEkPz7WqcvVvUW@0n/3Tm6I3dFgU4udWfXb3SHgScVVpgWhwvKriJFoQxBmTSC7IgVFGyBMKNRTBCpVO@aXzshCqykjiv95ABobEqnkqdE5LkPTczRR@5oTRxVJgiuzMzLI0QquxzQwmQ4ONeY@ctOBoHNc0ucPgnWDF4rO6R5BiG9D8CP535b/5r4n1j1lCHK8SXzRdLkEm4CFzf/NCirlnTIXNBx8rGf7mZdK46xFkyFAkfR05Hk9nDrehjMhRjyZfR5O3rPo9HAzF@7HRgX4dDnaLT@Rs "Java (OpenJDK 8) – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 59 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
+2Rṫ-4>Ðḟ⁹1;;QµI’a3R”.ṁ⁸żẎ
Ị¬;n“¢©ỵY“¡&ç»ẋ"W€jçLÐfKṣ⁸j⁸WŒṘ¤
```
A full program\* printing the result to STDOUT. Takes arguments `current` and `total` in that order.
**[Try it online!](https://tio.run/##AXwAg/9qZWxsef//KzJS4bmrLTQ@w5DhuJ/igbkxOztRwrVJ4oCZYTNS4oCdLuG5geKBuMW84bqOCuG7isKsO27igJzCosKp4bu1WeKAnMKhJsOnwrvhuosiV@KCrGrDp0zDkGZL4bmj4oG4auKBuFfFkuG5mMKk////NTL/MTcz "Jelly – Try It Online")** or see the [test-suite](https://tio.run/##y0rNyan8/1/bKOjhztW6JnaHJzzcMf9R405Da@vAQ1s9HzXMTDQOetQwV@/hzsZHjTuO7nm4q4/r4e6uQ2us8x41zDm06NDKh7u3RoKYC9UOLz@0@@GubqXwR01rsg4v9zk8Ic374c7FQH1ZQBx@dNLDnTMOLfl/eLk@UMHRPQ5gAZBaIAaaoKBrpwC0KvL//@hoQx3DWB0gaQQmDQ2AlLGOMZg0A5NgIVMIZWgA5RrpGJobx8YCAA "Jelly – Try It Online").
### How?
```
+2Rṫ-4>Ðḟ⁹1;;QµI’a3R”.ṁ⁸żẎ - Link 1, numbers and ellipses: current, total
                           -                                   e.g. 52, 173
 2                         - literal two                            2
+                          - add to current                         54
  R                        - range                                  [1,2,3,...,53,54]
    -4                     - literal minus four                     -4
   ṫ                       - tail from index (i.e. right five)      [50,51,52,53,54]
         ⁹                 - chain's right argument, total          173
       Ðḟ                  - filter discard if:
      >                    -  greater than?                         [50,51,52,53,54]
          1                - literal one                            1
           ;               - concatenate                            [1,50,51,52,53,54]
            ;              - concatenate (implicit right = total)   [1,50,51,52,53,54,173]
             Q             - unique (remove excess 1 and/or total)  [1,50,51,52,53,54,173]
              µ            - new monadic chain, call that X
               I           - incremental differences                [49,1,1,1,1,119]
                ’          - decrement (vectorises)                 [48,0,0,0,0,118]
                  3        - literal three                          3
                 a         - logical and (vectorises)               [3,0,0,0,0,3]
                   R       - range (vectorises)                     [[1,2,3],[],[],[],[],[1,2,3]]
                    ”.     - literal '.' character                  '.'
                      ṁ    - mould like that                        [['.','.','.'],[],[],[],[],['.','.','.']]
                       ⁸   - chain's left argument, X               [1,50,51,52,53,54,173]
                        ż  - zip with that                          [[1,['.', '.', '.']],[50,[]],[51,[]],[52,[]],[53,[]],[54,['.','.','.']],[173]]
                         Ẏ - tighten                                [1,['.', '.', '.'],50,[],51,[],52,[],53,[],54,['.','.','.'],173]
Ị¬;n“¢©ỵY“¡&ç»ẋ"W€jçLÐfKṣ⁸j⁸WŒṘ¤ - Main link: current, total   e.g. 52, 173
Ị                                - insignificant? (abs(current)<=1)  0
 ¬                               - logical not                       1
   n                             - not equal (current != total)      1
  ;                              - concatenate                       [1,1]
    “¢©ỵY“¡&ç»                   - list of compressed strings        [['p','r','e','v'], ['n','e','x','t']]
               "                 - zip with:
              ẋ                  -   repeat (zeros -> empty lists)   [['p','r','e','v'], ['n','e','x','t']]
                W€               - wrap €ach (prep for the join)     [[['p','r','e','v']], [['n','e','x','t']]]
                   ç             - call last link (1) as a dyad      [1,['.', '.', '.'],50,[],51,[],52,[],53,[],54,['.','.','.'],173]
                  j              - join                              [['p','r','e','v'],1,['.','.','.'],50,[],51,[],52,[],53,[],54,['.','.','.'],173,['n','e','x','t']]
                     Ðf          - filter keep if:
                    L            -   length (removes empty lists)    [['p','r','e','v'],1,['.','.','.'],50,51,52,53,54,['.','.','.'],173,['n','e','x','t']]
                       K         - join with spaces                  ['p','r','e','v',' ',1,' ','.','.','.',' ',50,' ',51,' ',52,' ',53,' ',54,' ','.','.','.',' ',173,' ','n','e','x','t']
                         ⁸       - chain's left argument, current    52
                        ṣ        - split at that                     [['p','r','e','v',' ',1,' ','.','.','.',' ',50,' ',51,' ',],[,' ',53,' ',54,' ','.','.','.',' ',173,' ','n','e','x','t']]
                               ¤ - nilad followed by link(s) as a nilad:
                           ⁸     -   chain's left argument, current  52
                            W    -   wrap                            [52]
                             ŒṘ  -   Python string representation    ['[','5','2',']']
                          j      - join                              ['p','r','e','v',' ',1,' ','.','.','.',' ',50,' ',51,' ','[','5','2',']',' ',53,' ',54,' ','.','.','.',' ',173,' ','n','e','x','t']
                                 - implicit print                    prev 1 ... 50 51 [52] 53 54 ... 173 next
```
\* As a dyadic link taking `current` on the left and `total` on the right this returns a list with a mix of characters and integers; this list includes the spaces. The byte `K` cannot simply be removed to adhere to the spec however, since the result would then have the bracketed `current` as separate characters (like `[...'[','5','2',']'...]`) so the "convert each item to string and join them with a single space" would fail to produce the desired result)
[Answer]
# [Python 2](https://docs.python.org/2/), ~~178~~ 170 bytes
```
x,y=input()
e="... ",""
o=("Prev 1 ","[1] ")[y<2]+e[y<5]
for z in range(2,x):o+=("",(`z`,`[z]`)[z==y]+" ")[y-3<z<y+3]
print o+("",e[x-y<4]+(`x`+" Next",`[x]`)[y==x])[x>1]
```
[Try it online!](https://tio.run/##HcvBCgIhFIXhvU8hd6VoQ87UJrRHiPZywRZWs9FBLNSXN6fV4cD/bTW/Y5h7L7KaNWyfzDjxBqZpoiABSDQM7sl/qdq/VUiB26pnFH7MGckzJtroGmh6hJdnsyz8EsVQIJlrTjrb0HHbjKko4K8Pi266igXJltaQaRR77W05VH1CwVxxo7z5kmHwsvNqTEFuy1Vh7@oolx8 "Python 2 – Try It Online")
Second attempt after reading the rules more carefully.
-8 by losing some unneeded brackets.
[Answer]
# [C# (.NET Core)](https://www.microsoft.com/net/core/platform), ~~195~~ 192 bytes
Saved 3 bytes thanks to Kevin Cruijssen.
```
c=>t=>{var n=c>1?"prev ":"";n+=c>4?"1 ... ":c<2?"[1] ":"1 ";if(t>1){for(int i=c-3;i++<c+2;)if(i>1&i<t)n+=i==c?$"[{i}] ":i+" ";n+=c<t-4?"... "+t:c==t?$"[{t}]":t+"";n+=c<t?" next":"";}return n;}
```
[Try it online!](https://tio.run/##jY8/a8MwEMXn@FMcohQLNaZy@gciyx4KnVooZOgQMhhVDgeJXKRLaDH@7K7i0C4dHLjp3e/ee2fC3LTeDmZXhwBvvt36eg9dMgtUExo4tvgBrzW6NJBHt11voPbbwCOSrL4D2X32fHCmQEc38E8435QlNKAHo0vSZXesPThtSlmxT2@PwJaMKSeiclcxCVmWRckUecXWcnPaSmAKm5RKybum9Wl0BtRmvlAoRGFErnhcYymvsSAenVBrU12xdYf9yQAFg3NCQfOYMSYIWhqtacSo37AlCfYLVQyc/aKxWO8tHbwDp/pB/b381LrQ7mz27pHsCzqbNqnkcbiaQPJpRN5OMAseZxJ5mEYmk@4vYCJwgVEeocexdTLrk374AQ "C# (.NET Core) – Try It Online")
[Answer]
**C++ - 247 bytes**
```
#include <iostream>
#define c std::cout<<
#define N (a-i<3?i-a<2?1:b-i:a-i-2)
void s(int a,int b){if(a>1)c"prev ";for(int i=1;i<=b&&N!=0;i+=N)c(i==1?"":" ")<<(a==i?"[":"")<<i<<(a==i?"]":"")<<(N>1?" ...":"");if(a<b-2)c" "<<b;if(a<b)c" next";c"\n";}
```
[Try it online!](https://tio.run/##RY7RaoMwFIav51NkKZSEqRilG5gTfQNfYNtFjBEOrFHUlkHps7ukrd1FDt//5STnWDOOiT/rDp35OXWWAA7zMll9rKJdZ3t0lhgyL11ZmuG0ADxtQ5hOEIoaEw15Lco2wdKbJOfRecCOzAzdQnQcassv2DNdCW7oONkzobIfplsDKiERVLvfN68qk/imGm4YKiVqSktKKAdgWims6afPIeLTfD8MayrfTtI0vQkZhkHrVzH@A4D2IUJ09neh0tAvR@V1DRscNTrGySV6mZmIBZd3yDcQ2Z2KuNjgfYPt7vAkkf3LPBYf4c11Xf8A)
[Answer]
# [Python 2](https://docs.python.org/2/), ~~128~~ 124 bytes
*-4 bytes thanks to [Jonathan Allan](https://codegolf.stackexchange.com/users/53748/jonathan-allan)!*
```
lambda c,l:["prev"]*(c>1)+[range(1,c),[1,"...",c-2,c-1]][c>4]+[[c]]+[range(c+1,l+1),[c+1,c+2,"...",l]][l-c>4]+["next"]*(c<l)
```
[Try it online!](https://tio.run/##NU3brsIgEHznKxpepIKNi9WTeI7@CBKDWLUGkXDw9vV1qXUvszuZ2Wx4pdPVy@6w2nTOXHZ7U1jhloqG2NypHjO7hpKraPyxYSBsKRQIWlUVFXYisUFrZde15kpZrb9Oy0E4DujOm@VyuHHodpOPn/rmmfoXf67sHqfWNQUsixBbn0bFqDpfW88uJrD/FMWBtT7cEivFMDF@o3lsB9oBAYIlM8CUkBkm1iJD5vMesXsiCfygXmd9jvAG "Python 2 – Try It Online")
Output as a list, but tio link includes pretty-print.
[Answer]
# CJam, 74
```
q~\:A\:B]3e*[1T4A3+1A].>["prev"1'.3*_B"next"]:a.*3/5,A2-f+B,2>&*:+_A#Aa`tp
```
Outputs as array. [Try it online](http://cjam.aditsu.net/#code=q%7E%5C%3AA%5C%3AB%5D3e*%5B1T4A3%2B1A%5D.%3E%5B%22prev%221%27.3*_B%22next%22%5D%3Aa.*3%2F5%2CA2-f%2BB%2C2%3E%26*%3A%2B_A%23Aa%60tp&input=4%2010)
Replace the final `p` with `S*` to output as string.
**Explanation:**
```
q~          read and evaluate the input (pushing 2 numbers on the stack)
\:A\:B      store the numbers in A and B, keeping them in the same order
]3e*        wrap in array, then repeat each number 3 times - [A A A B B B]
[1T4        make an array containing 1, 0 (T=0 by default), 4,
A3+1A]      then A+3, 1, and A
.>          compare the 2 arrays element by element - [A>1 A>0 A>4 B>A+3 B>1 B>A]
             (each result is 1 or 0)
["prev"1    make an array containing "prev", 1,
'.3*_       "..." twice ("..." = '.' repeated 3 times),
B"next"]    then B and "next"
:a          wrap each of its elements in an array - [["prev"][1]["..."]…]
.*          repeat each of these arrays according to the previous array
             e.g. ["prev"] is repeated A>1 times - ["prev"] if A>1, else []
             [1] is repeated A>0 times (always 1), etc.
             obtaining an array of 6 arrays, some of which may be empty
3/          split into 2 arrays of 3 arrays each (between the "..." parts)
5,A2-f+     make an array [0 1 2 3 4] then add A-2 to each element
B,2>&       intersect with the array [2 3 … B-1] (these are the middle numbers)
*           join the 2 previous arrays by adding these numbers between them
:+          concatenate all these arrays and numbers together
             obtaining an array containing only numbers and strings
_A#         duplicate the array then find the position of A in it
Aa`         generate the "[A]" string (with the actual number for A)
             by wrapping A in an array and getting its string representation
t           put it in the array at A's position
p           print the array's string representation
```
[Answer]
## Haskell, ~~145~~ 129 bytes
```
s x=show x
a#t=["prev 1"|a>1]++["..."|a>4]++map s[max 4a-2..a-1]++s[a]:map s[a+1..min(a+3)t-1]++["..."|t-a>3]++[s t++" next"|a<t]
```
[Try it online!](https://tio.run/##TYzLDoIwEEX3fsUEN20KDaU@EiN@ga5cNsRMlAQiVNIWxcR/x1JcuDl3zszkVmjvZdOMo4Uht9XjBcMCly5XUWfKJ4jogwdRMKYizvkkKy8tdmBViwOsMMk4x2R6sQqL3XxCJjhva02QSeqSvwKX4EFOasExFoEuB@dr964YW6w15OAbThcgXe/Ozhw1cOj162FuNkzX3pg3kCWloIiIBY09s0CR@pCxDNwEhtV6DpH@NIvFVtJi/AI "Haskell – Try It Online")
Edit: @Ørjan Johansen saved 16 bytes. Thanks!
[Answer]
# PHP (<7.2), ~~157~~ 150 bytes
taking the details literally turned out to be the shortest approach:
```
[,$k,$n]=$argv;for($k>1&&print"prev ";$i++<$n;)$g=in_array($i,range($k-2,$k+2)+[5=>1,$n])?!print$i-$k?"$i ":"[$i] ":$g||print"... ";$k<$n&&print next;
```
Run with `php -nr '<code>' <curpage> <numpages>` or [try it online](http://sandbox.onlinephpfunctions.com/code/22e042b98ad6b0642c02ab4656c80dec20a3e74b?v=7.1.0).
[Answer]
## [Golf Script](https://tio.run/##JcvRCoIwFAbgVzlX/TT1OA0JtuWLOC@2YRFIiUkEY736Err7br7bc76@wnpftpy/VjmtvG6cwbJOb4I47WyImXcPXRkdtVWR6jGy7K0/mkMqI7tLxACLEUmAkGrtyVUqUNvjf30hZDCgx/TZIHLuJJ3lDw) - 104 characters
```
~\:a;:b;1a<'prev '*3a<'1 ... '*[5,{a 2-+}/]{.0>\b)<&},{.a={'['\']'}*' '}/;b a-:c 2>' ... 'b+*0c<' next'*
```
### Ungolfed
```
~\:a;:b;       # a = 1st arg, b = 2nd arg
1a<'prev '*    # if a > 1: print 'prev '
3a<'1 ... '*   # if a > 3: print '1 ... '
[5,{a 2-+}/]   # creates an array [a-2 a-1 a a+1 a+2]
{.0>\b)<&},    # keeps only elements >0 and <=b
{
  .a={'['\']'}*      # puts '[' ']' around the element equal to a
  ' '}/;             # prints each element with a leading space
b a-:c 2>' ... 'b+*  # if b-a > 2: print ' ... ' + b
0c<' next'*          # if b-a > 0: print ' next'
```
[Answer]
# Perl 5, ~~113+1 (-p)~~ 109 +3(-pal) bytes
```
$_=join$",1..<>;s/\b@F\b/[$&]/;s/^1/prev 1/;s/\d$/$& next/;s/(^|\] )\w+ \w+ \K[\w ]*(?= \w+ \w+( \[|$))/.../g
```
[Try it online](https://tio.run/##K0gtyjH9/18l3jYrPzNPRUnHUE/Pxs66WD8mycEtJkk/WkUtVh/IjTPULyhKLVMwBHFiUlT0VdQU8lIrSkBcjbiamFgFzZhybQUw9o6OKVeI1dKwt1WAimkoxETXqGhq6uvp6emn//9vyAWCRiDSgMsYDM2AGMgxBREQZAqUNzf@l19QkpmfV/xftyAxBwA)
[Answer]
# [Ruby](https://www.ruby-lang.org/), 127 bytes
I'm not particularly happy with this, especially the prev/next logic.
```
->c,t{"prev #{(1..t).chunk{|n|n<2||n==t||n>c-3&&n<c+3}.map{|t,a|t ?a:?.*3}*" "} next".sub(/(prev )?\b(#{c})\b( next)?/,'[\2]')}
```
[Try it online!](https://tio.run/##bZLfboIwFMbvfYoTSBQcVkupbovKxR5gN7urzYIV4zJXDZZlC@XZ2RFDIoNenKbn@52vp3@yfPtb7VfVZK0CUzjnLP0Gt/AoIcYn6pDrz8Jqq5ehtXq1MhjXasKGQ71UD6wkX8m5sCZIrIE4eY7JmJVjB5wSdPpjHHLJt97Uq039eLP13EKVPs617MfTYCQ2oRz5ZeXCS55lqTbwdjLJEcCF19ycczMQUA8aNNEFQeUA7tNhk4awtm6pdHanMiCEYKqFsaCJLtTNUiQFk2193tEhAg7zllXUhzIQkeyg7K65jmtPl7zLXymGvOASzRc9VTXfU/UIT3gjs@aI/HqDdMH@Y3wGnKJ9iO0z4NFthwW7bSFJmqjD@@X4oVIv9GF3AovfyKIpvtwF9gJXcpDqXfUH "Ruby – Try It Online")
## Ungolfed
```
->c,t{
  "prev #{
    (1..t)
    .chunk {|n| n < 2 || n == t || n > c - 3 && n < c + 3 }
    .map {|t,a| t ? a : ?. * 3 } * " "
  } next"
  .sub(/(prev )?\b(#{ c })\b( next)?/, '[\2]')
}
```
[Answer]
# PHP (Browser), 267 Bytes
```
<?php parse_str($_SERVER['QUERY_STRING']);$c=$a!=1?$a>3?$a>4?'prev 1 . . . ':'prev 1 ':'prev ':'[1] ';$d=$a<$b-2?$a+3:$b;for($i=$a<=2?$a==1?$i=2:$i=$a-1:$i=$a-2;$i<$d;$i++)$c.=$a==$i?"[$i] ":"$i ";if($a<$b-2)$c.=" . . . $b next";else $c.=$a==$b?"[$b]":"$b next";echo $c?>
```
[Try it online!](http://sandbox.onlinephpfunctions.com/code/f988cc25106ce35f2b78e7e880df5fe577ca0a19)
Definitely not as small as it could have been, and as was demonstrated above, using PHP in command line can be much smaller. The input is through GET requests, a is the selected number, b is the limit. This looks like `foo.bar.com/index.php?a=2&b=12`
# Ungolfed
```
<?
    parse_str($_SERVER['QUERY_STRING']);
    $c=$a!=1?$a>3?$a>4?'prev 1 . . . ':'prev 1 ':'prev ':'[1] ';
    $d=$a<$b-2?$a+3:$b;
    for($i=$a<=2?$a==1?$i=2:$i=$a-1:$i=$a-2;$i<$d;$i++)
        $c.=$a==$i?"[$i] ":"$i ";
    
    if($a<$b-2)$c.=" . . . $b next";else
    $c.=$a==$b?"[$b]":"$b next";
    echo $c
?>
```
I am pretty sure my ternary operators can be improved, feel free to try.
[Answer]
# IBM/Lotus Notes Formula, ~~217~~ 211 Bytes
-2 with thanks to @KevinCruijssen
-4 by using variables for the @Text values
```
o:=@If(a=1;"[1]";"Prev 1 ")+@If(a>4;"... ";"");@For(x:=2;x<b;x:=x+1;T:=@Text(x);o:=o+@If(x>a-3&x<a+3;@If(a=x;"["+T+"]";T)+" ";""));Z:=@Text(b);o:=o+@If(b>1;@If(b-a>3;"... ";"")+@If(a=b;"["+Z+"]";Z+" Next");"");o
```
Basically a port of my Python 2 answer just for the fun of trying to remember how to use Formula.
There's no TIO for Formula so here's a screenshot of some of the test cases:
[![enter image description here](https://i.stack.imgur.com/ZbRDA.png)](https://i.stack.imgur.com/ZbRDA.png)
[Answer]
# Excel VBA, ~~202~~ 201 Bytes
Anonymous VBE immediate window function that takes input from range `A1:A2` and outputs to the VBE immediate window.
```
For i=[Max(A1-2,1)]To[Min(A1+2,A2)]:s=s &IIf([A1]=i,"[" &i &"]",i)&" ":Next:?[If(A1=1,"","prev "&If(A1>3,1&If(A1>4," ... "," "),""))]s[If(A1<A2,If(A1-A2<-3,"... ","")&If(A1-A2<-2,A2&" ","")&"next","")]
```
### Subroutine Version
*Included for readablity*
```
Public Sub PageSelect(Optional ByVal Current As Long = -1, _
                      Optional ByVal Total   As Long = -1)
    Call Sheet1.Activate
    Let [A1] = IIf(Current = -1, [A1], Current)
    Let [A2] = IIf(Total   = -1, [A1], Total)
    Dim s As String
    Let s = ""
    For i = [Max(A1-2,1)] To [Min(A1+2,A2)] Step 1
        Let s = s & IIf([A1] = i, "[" & i & "]", i) & " "
    Next
    Debug.Print [If(A1=1,"","prev "&If(A1>3,1&If(A1>4," ... "," "),""))]; _
                s; _
                [If(A1<A2,If(A1-A2<-3,"... ","")&If(A1-A2<-2,A2&" ","")&"next","")]
End Sub
```
[Answer]
## C - 173 Bytes
```
#define p c&&printf(
c;main(t){scanf("%u%u",&c,&t);c&&t/c?1-p"prev 1"),3<p" ... %d",c-2),2<p" %d",c-1),1|p" [%d] ",c),t>1+p"%d ",c+1),t>2+p"%d ... ",c+2),t-p"%d next",t):0;}
```
Thanks to @ceilingcat for -45 bytes.
**Ungolfed (original version)**
```
#define p printf
c;
main(t)
{
    scanf("%u%u", &c, &t);
    if(1 <= c && c <= t) 
    {
        p(c != 1 ?"prev 1" :"");
        p(c - 2 > 1 ?" ... %d" :"", c - 2);
        p(c - 1 > 1 ?" %d" :"", c - 1);
        p(" [%d] ", c);
        p(c + 1 < t ?"%d " :"", c + 1);
        p(c + 2 < t ?"%d ... " :"", c + 2);
        p(c != t ?"%d next" :"", t);
    }
}
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 237 bytes
```
param($a,$n)('prev 1','[1]')[$n-lt2]+" ... $($n-2) $($n-1) [$n]"*($n-gt4)+" 2 3 [4]"*($n-eq4)+" 2 [3]"*($n-eq3)+" [2]"*($n-eq2)+" $($n+1) $($n+2) ..."*($n-lt$a-3)+" $($n+1) $($n+2)"*($n-eq$a-3)+" $($n+1)"*($n-eq$a-2)+" $a next"*($n-ne$a)
```
[Try it online!](https://tio.run/##bY3RCgIhEEV/ZVgG1NyV1P0b8cEHqQczM6n@3hS3JSIYGO65d@6k69Pn@9mHUGty2V0ouhkjoyRl/wBJZmKkJcxgXEJRlk8ghACkTSs2tmTQbDsdujiVlbWQAg1m3Zi/bczonehOjNq16rrXcTlqeatvr4YfCrpF/4l8zn/sLzyKHUT/KgNHj47VWuWxzRs "PowerShell – Try It Online")
One gigantic string concatenation with way too many dollar signs. ~~Working on golfing further.~~ Nope, I think this is as short as this approach can go.
[Answer]
# Javascript (ES6), ~~265~~ ~~263~~ ~~258~~ ~~240~~ ~~239~~ ~~220~~ ~~194~~ ~~193~~ ~~182~~ 178 bytes
*-2 from removing a debug tool*
*-5 from realizing that I'm using ES6 and can do away with parenthesis sometimes*
*-18 from removing something from an earlier version that is now obsolete*
*-1 from doing some sneaky stuff*
*-19 from removing unnecessary variables*
*-26 bytes from removing the all too complicated remove falsey values. I'm new to ES6*
*-1 from using shorter comparisons*
*-11 from using a recursive function*
\*-4 from replacing `?...:0` with `&&...`, and `... ${t}` with `...+t`
This took way too much of my life, and didn’t give enough upvotes.  ~~but I am so glad the final code is a power of 2 (2^8)~~ I do know there is another JavaScript answer that is about 120 bytes.  ~~but I still love this code~~
**EDIT: i don't know what i was thinking. 265 is not 2^8...**
While making this, I managed to break the ungolfed version. God, do I hate ungolfing code.
**EDIT 2: now it's looking like the better 121 byte solution**
```
y=(e,i,t="")=>i++<e?y(e,i,t+i+' '):t.slice(0,-1);m=(t,p)=>[p-1&&"prev",p<5?y(p-1,0):"1 ... "+y(p-1,p-3),`[${t}]`,t-p<4?y(t,p):y(p+2,p)+` ... `+t,t-p&&"next"].filter(e=>e).join` `
```
Explanation:
to come but basically y is `range(end, start)` and it does some cool stuff like:
1. show prev if `page` is 1
2. show left dots if `page > 4`
3. show right dots if `total - page < 4`
4. show next if `total - page == 0`
and stuff like that and just joins it by ' '. I know you don't have to but I like the fact that is semi-conventional. I don't know. Enjoy.
[Try it online!](https://tio.run/##ZY7RasIwFIbv9xSHMrQhaUiaRje17kFCoOLiiNS21CCTsWfvTk3ZcN4l3/nO/5/j7rI773vfhaxp391Ql8YYyaRliZE2sWz85fEHOTTuM0xQil@qgHMOUvyNFVM47Xp3AYmCUXbCi38YCtCw@Fss7g0FprD3ho7NkzIWKwwx2qK0fDhEigf9BV4BebxI50wu1b2gBWiJiTk2K9BFDF2qKdWuh2uZOuZZKJOElFtP6ca9XSOins5hTlaBn2u/d6lgmSTrU5kG1qFrukzOZre2hHUbjWtImCCrJJYnNJIuU4RV5vkrfNuKhazbFOiOISsUaI4PWt02KhrGOabG@/jB18H1qSu3jvBj65sKquHQ9pB6aA9QkyeAfduc29rxuv1ITynGeCMsIevhBw)
[Validate it online!](https://tio.run/##ZZHhasIwFEZf5VKGJiQtTdPopsY9SAhUXByR2pYaZDL27N2tKRPnv@bcc7/vQo@7y@68730X0qb9cEOtjTGCC8sTI2xi@fgq4gsKaNxXmKDI/6iELMtA5Pex5BKnXe8uIFAw0k548Q9DCQoW98Xy0ZBgSvtoqNg8KWOxxBCjLErLp0NE/qS/whsgjxepgoulfBRUDkpgYoHNElQZQ5dySrXDVRPHPQ86SajeesY27v0aEfNsDnO6Ctm59ntHcp4Kuj5pEniHrulSMZvdyhLebRSuIeE5XSWxO2GRdKmkvDIv3@HHVjyk3aZEdwxZocAK/GDVbaNiYZxjajwvO/g6uJ44vXU0O7a@qaAaDm0PxEN7gJrCvm3Obe2yuv0kJ4Ih3uSWgtbg8YfS9fAL)
Here's a ~~186~~ ~~185~~ ~~174~~ 170 byte solution that I don't like: [Try it online!](https://tio.run/##ZY7hasIwFEZf5RKGJiQtSdPoptY9SAhUXBwZ1ZYaZDL27N2tKRO3f8m5537f/dhddud9H7qYndo3PzSVtVYJ5QSxyhEnxl@RflDAyX/GCSr5SzXkeQ5K3sdaaJx2vb@AQsFqN@HFHwwlGFjcF8tHQ4Mt3aNhUvOkjMUaQ6xxKC3/HaLkP/0ZXgB5usgUQi31o2AkGIWJBTZrMGUKXeop1Q3XinoRRKwIYdU2cL7xr9eEeOBzmLNVzM9N2HsqRabY@ljRKDp0bZep2exWRkS3MbiGREi2Iqmb8ES6TDNR26ev@O1qEbNuU6I7hqxQ4AU@eH3bqHkc55iazssPoYm@p77aejYc2h5ogPYADYN9ezq3jc@b9p0eKS4HKx1j6@EH)
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 141 bytes
```
param($c,$t)($('prev'*($c-ne1)
1
'...'*($c-gt4)
($c-2)..($c+2)-gt1-lt$t
'...'*($t-$c-gt4)
$t
'next'*($t-ne$c))|?{$_}|gu)-replace"^$c$","[$c]"
```
[Try it online!](https://tio.run/##jZPfToMwFMbveYqT5ihUC1n5M9TE6HuQuRCs8wIZdp2abHt2bIEO3QLamzanv@87H4e0Xn8KuXkVZdngC9zDrqlzmb95WDBU1EPPraX4cK90wa8Epw533CAIusJKxdQxh5AGgd6vQ6pr3C8VqiOmfEuaYiW@VFetBBaU7h92uDzsV1vqS1GXeSHIExZIGMmwWJDm4DiPngN6MY9Dt5g9AHMzvnDp6X34@55ByKDrfIby2TkaadqEZ8Bnp8LI4tHQo52Qhrs@WbQ4p@dTNIOYQcJgftos/ktukmaxcZiUp/@Up6Nf@2NM4/lHh5ZM2vSyqLVxs8QY9mHGDK3PpOENg1tjyGfDD0lCK0yjUWGi@yW8zRK2w9HRkniIk0ZDHgp7uIBda4/FVkpRKQao1iov9S6@alEo8axfFi47SIrNtlS6cKkfnJX0ipYg6JGeIr54J0cTQu@snDiH5hs "PowerShell – Try It Online")
Less golfed:
```
param($current,$total)
$uiElements=$(
    'prev'*($current-ne1)
    1
    '...'*($current-gt4)
    ($current-2)..($current+2)-gt1-lt$total
    '...'*($total-$current-gt4)
    $total
    'next'*($total-ne$current)
)
($uiElements|where{$_}|Get-Unique)-replace"^$current$","[$current]"
```
]